Skip to content

Commit 8714f52

Browse files
committed
Implement gtk-layer-shell.
- Relies on layer-shell for scale changes and resizing to workarea, ignores Cinnamon proxy in Wayland mode. - If layer-shell is not supported by the compositor, resorts to x11 backend. (This is checked directly using wl_display, before gtk_init() runs) - nemo-icon-info: Add widget scale factor as part of the cache key. It's possible for nemo-desktop-windows to have different scale factors, and icon sizing if affected in these situations. Tested in: Cinnamon, labwc.
1 parent 0269902 commit 8714f52

12 files changed

Lines changed: 251 additions & 31 deletions

config.h.meson.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#mesondefine HAVE_SELINUX
2020
// Define to enable pango-1.44 fixes
2121
#mesondefine HAVE_PANGO_144
22+
// Define to use gtk-layer-shell
23+
#mesondefine HAVE_GTK_LAYER_SHELL
2224

2325

2426

debian/control

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@ Build-Depends:
2121
libgsf-1-dev,
2222
libgtk-3-dev (>= 3.10),
2323
libgtk-3-doc,
24+
libgtk-layer-shell-dev,
2425
libjson-glib-dev (>= 1.6),
2526
libpango1.0-dev,
2627
libx11-dev,
2728
libxapp-dev (>= 2.0.0),
2829
libxext-dev,
2930
libxrender-dev,
31+
libwayland-dev,
3032
meson,
3133
python3,
3234
python3-gi,

debian/rules

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ CONFIGURE_EXTRA_FLAGS = \
88
--buildtype=debugoptimized \
99
-D deprecated_warnings=false \
1010
-D gtk_doc=true \
11+
-D gtk_layer_shell=true \
1112
-D selinux=false
1213

1314
export DEB_LDFLAGS_MAINT_APPEND = -Wl,-z,defs -Wl,-O1 -Wl,--as-needed

libnemo-private/nemo-icon-container.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3620,6 +3620,28 @@ nemo_icon_container_search_position_func (NemoIconContainer *container,
36203620
if (nemo_icon_container_get_is_desktop (container)) {
36213621
x = cont_x + cont_width - requisition.width;
36223622
y = cont_y + cont_height - requisition.height;
3623+
3624+
if (eel_check_is_wayland ()) {
3625+
GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (container));
3626+
GdkWindow *parent_window = gtk_widget_get_window (toplevel);
3627+
gint parent_x, parent_y;
3628+
3629+
gdk_window_get_origin (parent_window, &parent_x, &parent_y);
3630+
3631+
GdkRectangle anchor_rect = {
3632+
x - parent_x,
3633+
y - parent_y,
3634+
1, 1
3635+
};
3636+
3637+
gdk_window_move_to_rect (gtk_widget_get_window (search_dialog),
3638+
&anchor_rect,
3639+
GDK_GRAVITY_NORTH_WEST,
3640+
GDK_GRAVITY_NORTH_WEST,
3641+
0,
3642+
0, 0);
3643+
return;
3644+
}
36233645
} else {
36243646
if (cont_x + cont_width > monitor.x + monitor.width) {
36253647
x = monitor.x + monitor.width - requisition.width;
@@ -4082,6 +4104,17 @@ nemo_icon_container_ensure_interactive_directory (NemoIconContainer *container)
40824104
gtk_container_add (GTK_CONTAINER (vbox), container->details->search_entry);
40834105

40844106
gtk_widget_realize (container->details->search_entry);
4107+
4108+
if (eel_check_is_wayland () && nemo_icon_container_get_is_desktop (container)) {
4109+
GdkRectangle anchor_rect = { 0, 0, 1, 1 };
4110+
4111+
gdk_window_move_to_rect (gtk_widget_get_window (container->details->search_window),
4112+
&anchor_rect,
4113+
GDK_GRAVITY_NORTH_WEST,
4114+
GDK_GRAVITY_NORTH_WEST,
4115+
0,
4116+
0, 0);
4117+
}
40854118
}
40864119

40874120
/* Pops up the interactive search entry. If keybinding is TRUE then the user

libnemo-private/nemo-icon-info.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ nemo_icon_info_new_for_icon_info (GtkIconInfo *icon_info,
168168
typedef struct {
169169
GIcon *icon;
170170
int size;
171+
int scale;
171172
} IconKey;
172173

173174
static GHashTable *loadable_icon_cache = NULL;
@@ -253,25 +254,27 @@ nemo_icon_info_clear_caches (void)
253254
static guint
254255
icon_key_hash (IconKey *key)
255256
{
256-
return g_icon_hash (key->icon) ^ key->size;
257+
return g_icon_hash (key->icon) ^ key->size ^ key->scale;
257258
}
258259

259260
static gboolean
260261
icon_key_equal (const IconKey *a,
261262
const IconKey *b)
262263
{
263264
return a->size == b->size &&
265+
a->scale == b->scale &&
264266
g_icon_equal (a->icon, b->icon);
265267
}
266268

267269
static IconKey *
268-
icon_key_new (GIcon *icon, int size)
270+
icon_key_new (GIcon *icon, int size, int scale)
269271
{
270272
IconKey *key;
271273

272274
key = g_new0 (IconKey, 1);
273275
key->icon = g_object_ref (icon);
274276
key->size = size;
277+
key->scale = scale;
275278

276279
return key;
277280
}
@@ -311,6 +314,7 @@ nemo_icon_info_lookup (GIcon *icon,
311314

312315
lookup_key.icon = icon;
313316
lookup_key.size = size;
317+
lookup_key.scale = scale;
314318

315319
icon_info = g_hash_table_lookup (loadable_icon_cache, &lookup_key);
316320
if (icon_info) {
@@ -344,7 +348,7 @@ nemo_icon_info_lookup (GIcon *icon,
344348

345349
icon_info = nemo_icon_info_new_for_pixbuf (pixbuf, scale);
346350

347-
key = icon_key_new (icon, size);
351+
key = icon_key_new (icon, size, scale);
348352
g_hash_table_insert (loadable_icon_cache, key, icon_info);
349353

350354
g_clear_object (&pixbuf);
@@ -363,6 +367,7 @@ nemo_icon_info_lookup (GIcon *icon,
363367

364368
lookup_key.icon = icon;
365369
lookup_key.size = size;
370+
lookup_key.scale = scale;
366371

367372
icon_info = g_hash_table_lookup (themed_icon_cache, &lookup_key);
368373
if (icon_info) {
@@ -388,7 +393,7 @@ nemo_icon_info_lookup (GIcon *icon,
388393
icon_info = nemo_icon_info_new_for_icon_info (gtkicon_info, scale);
389394
g_object_unref (gtkicon_info);
390395

391-
key = icon_key_new (icon, size);
396+
key = icon_key_new (icon, size, scale);
392397
g_hash_table_insert (themed_icon_cache, key, icon_info);
393398

394399
return nemo_icon_info_ref (icon_info);

meson.build

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,13 @@ if libselinux_enabled
133133
endif
134134
conf.set('HAVE_SELINUX', libselinux_enabled)
135135

136+
gtk_layer_shell_enabled = get_option('gtk_layer_shell')
137+
if gtk_layer_shell_enabled
138+
gtk_layer_shell = dependency('gtk-layer-shell-0', version: '>=0.8', required: true)
139+
wayland_client = dependency('wayland-client', required: true)
140+
conf.set('HAVE_GTK_LAYER_SHELL', gtk_layer_shell.found())
141+
endif
142+
136143
# make sure pango development files are installed
137144
pango = dependency('pango', version: '>=1.40.0')
138145
# check for newer pango for necessary workarounds
@@ -201,6 +208,7 @@ message('\n'.join(['',
201208
' exempi support: @0@'.format(exempi_enabled),
202209
' Tracker support: @0@'.format(tracker_enabled),
203210
' Wayland support: @0@'.format(cc.has_header('gdk/gdkwayland.h', dependencies: gtk)),
211+
' gtk-layer-shell: @0@'.format(gtk_layer_shell_enabled),
204212
'',
205213
' nemo-extension documentation: @0@'.format(gtkdoc_enabled),
206214
' nemo-extension introspection: @0@'.format(true),

meson_options.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,5 @@ option('empty_view', type : 'boolean', value : false,
1212
description: 'Enable empty view')
1313
option('tracker',type : 'combo', choices : ['true', 'false', 'auto'], value : 'false',
1414
description: 'Tracker support')
15+
option('gtk_layer_shell', type : 'boolean', value : false,
16+
description: 'Use gtk-layer-shell to draw desktop on wayland')

src/meson.build

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,11 @@ if libexif_enabled
113113
nemo_deps += libexif
114114
endif
115115

116+
if gtk_layer_shell_enabled
117+
nemo_deps += gtk_layer_shell
118+
nemo_deps += wayland_client
119+
endif
120+
116121
nemo = executable('nemo',
117122
nemoCommon_sources + nemoWindow_sources,
118123
include_directories: [ rootInclude ],

src/nemo-blank-desktop-window.c

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030
#include <gio/gio.h>
3131
#include <glib/gi18n.h>
3232

33+
#ifdef HAVE_GTK_LAYER_SHELL
34+
#include <gtk-layer-shell/gtk-layer-shell.h>
35+
#endif
36+
3337
#include <libnemo-private/nemo-desktop-utils.h>
3438
#include <libnemo-private/nemo-action.h>
3539
#include <libnemo-private/nemo-file.h>
@@ -402,7 +406,15 @@ nemo_blank_desktop_window_init (NemoBlankDesktopWindow *window)
402406

403407
window->details->popup_menu = NULL;
404408
window->details->actions_changed_id = 0;
405-
gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DESKTOP);
409+
410+
#ifdef HAVE_GTK_LAYER_SHELL
411+
if (gtk_layer_is_supported ()) {
412+
gtk_layer_init_for_window (GTK_WINDOW (window));
413+
} else
414+
#endif
415+
{
416+
gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DESKTOP);
417+
}
406418

407419
/* Make it easier for themes authors to style the desktop window separately */
408420
gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (window)), "nemo-desktop-window");
@@ -436,7 +448,13 @@ map (GtkWidget *widget)
436448
{
437449
/* Chain up to realize our children */
438450
GTK_WIDGET_CLASS (nemo_blank_desktop_window_parent_class)->map (widget);
439-
gdk_window_lower (gtk_widget_get_window (widget));
451+
452+
#ifdef HAVE_GTK_LAYER_SHELL
453+
if (!gtk_layer_is_layer_window (GTK_WINDOW (widget)))
454+
#endif
455+
{
456+
gdk_window_lower (gtk_widget_get_window (widget));
457+
}
440458

441459
GdkWindow *window;
442460
GdkRGBA transparent = { 0, 0, 0, 0 };
@@ -499,6 +517,31 @@ nemo_blank_desktop_window_update_geometry (NemoBlankDesktopWindow *window)
499517
{
500518
GdkRectangle rect;
501519

520+
#ifdef HAVE_GTK_LAYER_SHELL
521+
if (gtk_layer_is_layer_window (GTK_WINDOW (window))) {
522+
GdkDisplay *display = gdk_display_get_default ();
523+
GdkMonitor *monitor = gdk_display_get_monitor (display, window->details->monitor);
524+
525+
DEBUG ("NemoBlankDesktopWindow: using layer-shell for monitor %d",
526+
window->details->monitor);
527+
528+
gtk_layer_set_layer (GTK_WINDOW (window), GTK_LAYER_SHELL_LAYER_BOTTOM);
529+
gtk_layer_set_namespace (GTK_WINDOW (window), "nemo-desktop");
530+
gtk_layer_set_keyboard_mode (GTK_WINDOW (window), GTK_LAYER_SHELL_KEYBOARD_MODE_NONE);
531+
gtk_layer_set_exclusive_zone (GTK_WINDOW (window), 0);
532+
gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_TOP, TRUE);
533+
gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_BOTTOM, TRUE);
534+
gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_LEFT, TRUE);
535+
gtk_layer_set_anchor (GTK_WINDOW (window), GTK_LAYER_SHELL_EDGE_RIGHT, TRUE);
536+
537+
if (monitor) {
538+
gtk_layer_set_monitor (GTK_WINDOW (window), monitor);
539+
}
540+
541+
return;
542+
}
543+
#endif
544+
502545
nemo_desktop_manager_get_window_rect_for_monitor (nemo_desktop_manager_get (),
503546
window->details->monitor,
504547
&rect);

src/nemo-desktop-main.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,47 @@
5555

5656
#ifdef HAVE_GTK_LAYER_SHELL
5757
#include <gtk-layer-shell/gtk-layer-shell.h>
58+
#include <wayland-client.h>
59+
60+
static gboolean layer_shell_available = FALSE;
61+
62+
static void
63+
registry_handle_global (void *data, struct wl_registry *registry,
64+
uint32_t name, const char *interface, uint32_t version)
65+
{
66+
if (g_strcmp0 (interface, "zwlr_layer_shell_v1") == 0)
67+
layer_shell_available = TRUE;
68+
}
69+
70+
static void
71+
registry_handle_global_remove (void *data, struct wl_registry *registry, uint32_t name)
72+
{
73+
}
74+
75+
static const struct wl_registry_listener registry_listener = {
76+
registry_handle_global,
77+
registry_handle_global_remove,
78+
};
79+
80+
static gboolean
81+
check_layer_shell_support (void)
82+
{
83+
struct wl_display *display;
84+
struct wl_registry *registry;
85+
86+
display = wl_display_connect (NULL);
87+
if (!display)
88+
return FALSE;
89+
90+
registry = wl_display_get_registry (display);
91+
wl_registry_add_listener (registry, &registry_listener, NULL);
92+
wl_display_roundtrip (display);
93+
94+
wl_registry_destroy (registry);
95+
wl_display_disconnect (display);
96+
97+
return layer_shell_available;
98+
}
5899
#endif
59100

60101
int
@@ -91,7 +132,20 @@ main (int argc, char *argv[])
91132

92133
g_set_prgname ("nemo-desktop");
93134

135+
#ifdef HAVE_GTK_LAYER_SHELL
136+
if (check_layer_shell_support ())
137+
{
138+
g_message ("nemo-desktop: using Wayland backend, gtk-layer-shell supported");
139+
}
140+
else
141+
{
142+
g_message ("nemo-desktop: Not a Wayland session, or wlr-layer-shell protocol not supported, using X11 backend");
143+
gdk_set_allowed_backends ("x11");
144+
}
145+
#else
146+
g_message ("nemo-desktop: using X11");
94147
gdk_set_allowed_backends ("x11");
148+
#endif
95149

96150
#ifdef HAVE_EXEMPI
97151
xmp_init();

0 commit comments

Comments
 (0)