Skip to content

Commit aa4573d

Browse files
authored
csd-background: Run as a wayland client if gtk-layer-shell is (#437)
available. Current csd-background runs with xwayland and requires special handling built in to muffin to 'make it work'. Benefits: - Allows running as a wayland client - Enables free re-use of background surfaces by Cinnamon consumers. - Eliminates need for special handling in wayland sessions by muffin.
1 parent 5d79d06 commit aa4573d

13 files changed

Lines changed: 256 additions & 82 deletions

debian/control

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Build-Depends:
1414
libfontconfig1-dev,
1515
libglib2.0-dev (>= 2.37.3),
1616
libgtk-3-dev (>= 3.9.10),
17+
libgtk-layer-shell-dev,
1718
libgudev-1.0-dev [linux-any],
1819
liblcms2-dev,
1920
libnotify-dev (>= 0.7.0),
@@ -24,6 +25,7 @@ Build-Depends:
2425
libsystemd-dev [linux-any],
2526
libupower-glib-dev (>= 0.99.11),
2627
libwacom-dev (>= 0.4) [!s390x !hurd-any !kfreebsd-any],
28+
libwayland-dev,
2729
libx11-dev,
2830
libxext-dev,
2931
libxi-dev,

debian/rules

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
1515
override_dh_auto_configure:
1616
dh_auto_configure -- \
1717
--libexecdir=/usr/libexec \
18+
-D gtk_layer_shell=true \
1819
$(CONFFLAGS)
1920

2021

meson.build

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,14 @@ if not get_option('use_logind').disabled()
8989
endif
9090
endif
9191

92+
gtk_layer_shell_enabled = get_option('gtk_layer_shell')
93+
gtk_layer_shell = dependency('', required: false)
94+
wayland_client = dependency('', required: false)
95+
if gtk_layer_shell_enabled
96+
gtk_layer_shell = dependency('gtk-layer-shell-0', version: '>= 0.8', required: true)
97+
wayland_client = dependency('wayland-client', required: true)
98+
endif
99+
92100
cc = meson.get_compiler('c')
93101
math = cc.find_library('m', required: false)
94102

@@ -105,6 +113,9 @@ csd_conf.set_quoted('LIBEXECDIR', join_paths(prefix, libexecdir))
105113
csd_conf.set_quoted('SYSCONFDIR', sysconfdir)
106114
csd_conf.set_quoted('LIBDIR', libdir)
107115
csd_conf.set10('HAVE_TIMERFD', has_timerfd_create)
116+
if gtk_layer_shell_enabled
117+
csd_conf.set('HAVE_GTK_LAYER_SHELL', 1)
118+
endif
108119

109120
if gudev.found()
110121
cargs += '-DHAVE_GUDEV'

meson_options.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,9 @@ option(
7070
value: '/usr/share/zoneinfo/zone.tab',
7171
description: 'Path to tzdata zone.tab or zone1970.tab'
7272
)
73+
option(
74+
'gtk_layer_shell',
75+
type: 'boolean',
76+
value: false,
77+
description: 'Use gtk-layer-shell for native Wayland background windows'
78+
)

plugins/background/csd-background-manager.c

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@
3737
#include <gio/gio.h>
3838
#include <gdk/gdk.h>
3939
#include <gdk/gdkx.h>
40+
#ifdef GDK_WINDOWING_WAYLAND
41+
#include <gdk/gdkwayland.h>
42+
#endif
4043

4144
#define GNOME_DESKTOP_USE_UNSTABLE_API
4245
#include <libcinnamon-desktop/gnome-bg.h>
@@ -59,11 +62,14 @@ struct CsdBackgroundManagerPrivate
5962
guint proxy_signal_id;
6063

6164
GPtrArray *mbs;
65+
66+
guint screen_changed_id;
6267
};
6368

6469
static void csd_background_manager_finalize (GObject *object);
6570

6671
static void setup_bg (CsdBackgroundManager *manager);
72+
static void setup_monitors (CsdBackgroundManager *manager);
6773
static void connect_screen_signals (CsdBackgroundManager *manager);
6874

6975
G_DEFINE_TYPE (CsdBackgroundManager, csd_background_manager, G_TYPE_OBJECT)
@@ -77,6 +83,13 @@ draw_background_wayland_session (CsdBackgroundManager *manager)
7783

7884
cinnamon_settings_profile_start (NULL);
7985

86+
if (!manager->priv->mbs || manager->priv->mbs->len == 0 ||
87+
manager->priv->screen_changed_id != 0)
88+
{
89+
cinnamon_settings_profile_end (NULL);
90+
return;
91+
}
92+
8093
for (i = 0; i < manager->priv->mbs->len; i++)
8194
{
8295
GtkImage *image;
@@ -127,29 +140,19 @@ draw_background_x11_session (CsdBackgroundManager *manager)
127140
}
128141

129142
static gboolean
130-
session_is_wayland (void)
143+
using_wayland_backend (void)
131144
{
132-
static gboolean session_is_wayland = FALSE;
133-
static gsize once_init = 0;
134-
135-
if (g_once_init_enter (&once_init)) {
136-
const gchar *env = g_getenv ("XDG_SESSION_TYPE");
137-
if (env && g_strcmp0 (env, "wayland") == 0) {
138-
session_is_wayland = TRUE;
139-
}
140-
141-
g_debug ("Session is Wayland? %d", session_is_wayland);
142-
143-
g_once_init_leave (&once_init, 1);
144-
}
145-
146-
return session_is_wayland;
145+
#ifdef GDK_WINDOWING_WAYLAND
146+
return GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ());
147+
#else
148+
return FALSE;
149+
#endif
147150
}
148151

149152
static void
150153
draw_background (CsdBackgroundManager *manager)
151154
{
152-
if (session_is_wayland ()) {
155+
if (using_wayland_backend ()) {
153156
draw_background_wayland_session (manager);
154157
} else {
155158
draw_background_x11_session (manager);
@@ -177,12 +180,31 @@ settings_change_event_cb (GSettings *settings,
177180
return FALSE;
178181
}
179182

183+
static gboolean
184+
on_screen_changed_idle (gpointer user_data)
185+
{
186+
CsdBackgroundManager *manager = CSD_BACKGROUND_MANAGER (user_data);
187+
188+
manager->priv->screen_changed_id = 0;
189+
190+
if (using_wayland_backend ()) {
191+
setup_monitors (manager);
192+
}
193+
194+
draw_background (manager);
195+
196+
return G_SOURCE_REMOVE;
197+
}
198+
180199
static void
181200
on_screen_size_changed (GdkScreen *screen,
182201
CsdBackgroundManager *manager)
183202
{
203+
if (manager->priv->screen_changed_id != 0)
204+
return;
184205

185-
draw_background (manager);
206+
manager->priv->screen_changed_id =
207+
g_timeout_add (250, on_screen_changed_idle, manager);
186208
}
187209

188210
static void
@@ -193,6 +215,9 @@ setup_monitors (CsdBackgroundManager *manager)
193215

194216
display = gdk_display_get_default ();
195217

218+
if (!display)
219+
return;
220+
196221
g_clear_pointer (&manager->priv->mbs, g_ptr_array_unref);
197222
manager->priv->mbs = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
198223

@@ -251,7 +276,7 @@ setup_bg_and_draw_background (CsdBackgroundManager *manager)
251276
{
252277
setup_bg (manager);
253278

254-
if (session_is_wayland ()) {
279+
if (using_wayland_backend ()) {
255280
setup_monitors (manager);
256281
}
257282

@@ -396,6 +421,8 @@ csd_background_manager_stop (CsdBackgroundManager *manager)
396421

397422
g_debug ("Stopping background manager");
398423

424+
g_clear_handle_id (&manager->priv->screen_changed_id, g_source_remove);
425+
399426
disconnect_screen_signals (manager);
400427

401428
if (manager->priv->proxy) {

plugins/background/main.c

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
#include "config.h"
2+
3+
#include <glib.h>
4+
#include <gdk/gdk.h>
5+
16
#define NEW csd_background_manager_new
27
#define START csd_background_manager_start
38
#define STOP csd_background_manager_stop
@@ -12,8 +17,34 @@
1217
// Setting this to TRUE makes the plugin force GDK_SCALE=1
1318
#define FORCE_GDK_SCALE TRUE
1419

15-
// This plugin must run under x11/xwayland
20+
// When gtk-layer-shell is available, check at runtime if the compositor
21+
// supports wlr-layer-shell. If not, fall back to X11/XWayland.
22+
#ifdef HAVE_GTK_LAYER_SHELL
23+
#include "wayland-utils.h"
24+
25+
static void
26+
pre_gtk_init (void)
27+
{
28+
if (csd_check_layer_shell_support ()) {
29+
g_message ("csd-background: using Wayland backend, gtk-layer-shell supported");
30+
} else {
31+
g_message ("csd-background: not a Wayland session or wlr-layer-shell protocol not supported, using X11 backend");
32+
gdk_set_allowed_backends ("x11");
33+
}
34+
}
35+
36+
#define PRE_GTK_INIT pre_gtk_init
37+
#define FORCE_X11_BACKEND FALSE
38+
#else
39+
static void
40+
pre_gtk_init (void)
41+
{
42+
g_message ("csd-background: gtk-layer-shell not built, using X11 backend");
43+
}
44+
45+
#define PRE_GTK_INIT pre_gtk_init
1646
#define FORCE_X11_BACKEND TRUE
47+
#endif
1748

1849
#include "csd-background-manager.h"
1950

plugins/background/meson.build

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ background_deps = [
1313
libnotify,
1414
]
1515

16+
if gtk_layer_shell_enabled
17+
background_deps += gtk_layer_shell
18+
endif
19+
1620
executable(
1721
'csd-background',
1822
background_sources,

0 commit comments

Comments
 (0)