From 02b20a8c7d84d852eaddde5466f74977c402f106 Mon Sep 17 00:00:00 2001 From: Sam Lakerveld Date: Mon, 22 Jul 2024 22:04:22 +0200 Subject: [PATCH] Add gtk_layer_set_exclusive_edge --- include/gtk-layer-shell.h | 19 +++++++++++++---- protocol/wlr-layer-shell-unstable-v1.xml | 21 ++++++++++++++++-- src/api.c | 27 ++++++++++++++++++++++++ src/layer-surface.c | 14 ++++++++++++ src/layer-surface.h | 2 ++ 5 files changed, 77 insertions(+), 6 deletions(-) diff --git a/include/gtk-layer-shell.h b/include/gtk-layer-shell.h index 93557fb..e4a0c11 100644 --- a/include/gtk-layer-shell.h +++ b/include/gtk-layer-shell.h @@ -292,15 +292,26 @@ void gtk_layer_set_margin (GtkWindow *window, GtkLayerShellEdge edge, int margin */ int gtk_layer_get_margin (GtkWindow *window, GtkLayerShellEdge edge); +/** + * gtk_layer_set_exclusive_edge: + * @window: A layer surface. + * @exclusive_edge: The edge for which to set the exclusive zone. + * + * Set the edge for which the exclusive zone should apply. This is required if + * the edge cannot be automatically deduced from the anchor points. + */ +void gtk_layer_set_exclusive_edge (GtkWindow *window, int exclusive_edge); + /** * gtk_layer_set_exclusive_zone: * @window: A layer surface. * @exclusive_zone: The size of the exclusive zone. * - * Has no effect unless the surface is anchored to an edge. Requests that the compositor - * does not place other surfaces within the given exclusive zone of the anchored edge. - * For example, a panel can request to not be covered by maximized windows. See - * wlr-layer-shell-unstable-v1.xml for details. + * Has no effect unless the surface is anchored to an edge, or has an exclusive + * edge set with gtk_layer_set_exclusive_edge(). Requests that the compositor + * does not place other surfaces within the given exclusive zone of the + * anchored edge. For example, a panel can request to not be covered by + * maximized windows. See wlr-layer-shell-unstable-v1.xml for details. * * Default is 0 */ diff --git a/protocol/wlr-layer-shell-unstable-v1.xml b/protocol/wlr-layer-shell-unstable-v1.xml index d62fd51..e9f27e4 100644 --- a/protocol/wlr-layer-shell-unstable-v1.xml +++ b/protocol/wlr-layer-shell-unstable-v1.xml @@ -25,7 +25,7 @@ THIS SOFTWARE. - + Clients can use this interface to assign the surface_layer role to wl_surfaces. Such surfaces are assigned to a "layer" of the output and @@ -100,7 +100,7 @@ - + An interface that may be implemented by a wl_surface, for surfaces that are designed to be rendered as a layer of a stacked desktop-like @@ -367,6 +367,7 @@ + @@ -386,5 +387,21 @@ + + + + + + Requests an edge for the exclusive zone to apply. The exclusive + edge will be automatically deduced from anchor points when possible, + but when the surface is anchored to a corner, it will be necessary + to set it explicitly to disambiguate, as it is not possible to deduce + which one of the two corner edges should be used. + + The edge must be one the surface is anchored to, otherwise the + invalid_exclusive_edge protocol error will be raised. + + + diff --git a/src/api.c b/src/api.c index 7b51dce..3122ac9 100644 --- a/src/api.c +++ b/src/api.c @@ -190,6 +190,33 @@ gtk_layer_get_margin (GtkWindow *window, GtkLayerShellEdge edge) return layer_surface->margins[edge]; } +void +gtk_layer_set_exclusive_edge (GtkWindow *window, int exclusive_edge) +{ + LayerSurface *layer_surface = gtk_window_get_layer_surface (window); + if (!layer_surface) return; // Error message already shown in gtk_window_get_layer_surface + int wlr_anchor; + switch (exclusive_edge) + { + case GTK_LAYER_SHELL_EDGE_LEFT: + wlr_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT; + break; + case GTK_LAYER_SHELL_EDGE_RIGHT: + wlr_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; + break; + case GTK_LAYER_SHELL_EDGE_TOP: + wlr_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP; + break; + case GTK_LAYER_SHELL_EDGE_BOTTOM: + wlr_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; + break; + default: + g_critical ("Invalid exclusive edge %d", exclusive_edge); + return; + } + layer_surface_set_exclusive_edge (layer_surface, wlr_anchor); +} + void gtk_layer_set_exclusive_zone (GtkWindow *window, int exclusive_zone) { diff --git a/src/layer-surface.c b/src/layer-surface.c index 574f416..591f126 100644 --- a/src/layer-surface.c +++ b/src/layer-surface.c @@ -182,6 +182,7 @@ layer_surface_map (CustomShellSurface *super, struct wl_surface *wl_surface) g_return_if_fail (self->layer_surface); zwlr_layer_surface_v1_set_keyboard_interactivity (self->layer_surface, self->keyboard_mode); + zwlr_layer_surface_v1_set_exclusive_edge (self->layer_surface, self->exclusive_edge); zwlr_layer_surface_v1_set_exclusive_zone (self->layer_surface, self->exclusive_zone); layer_surface_send_set_anchor (self); layer_surface_send_set_margin (self); @@ -316,6 +317,7 @@ layer_surface_new (GtkWindow *gtk_window) self->monitor = NULL; self->layer = GTK_LAYER_SHELL_LAYER_TOP; self->name_space = NULL; + self->exclusive_edge = 0; self->exclusive_zone = 0; self->auto_exclusive_zone = FALSE; self->keyboard_mode = GTK_LAYER_SHELL_KEYBOARD_MODE_NONE; @@ -406,6 +408,18 @@ layer_surface_set_margin (LayerSurface *self, GtkLayerShellEdge edge, int margin } } +void +layer_surface_set_exclusive_edge (LayerSurface *self, int exclusive_edge) +{ + if (self->exclusive_edge != exclusive_edge) { + self->exclusive_edge = exclusive_edge; + if (self->layer_surface) { + zwlr_layer_surface_v1_set_exclusive_edge (self->layer_surface, self->exclusive_edge); + custom_shell_surface_needs_commit ((CustomShellSurface *)self); + } + } +} + void layer_surface_set_exclusive_zone (LayerSurface *self, int exclusive_zone) { diff --git a/src/layer-surface.h b/src/layer-surface.h index 7833231..2aeef75 100644 --- a/src/layer-surface.h +++ b/src/layer-surface.h @@ -29,6 +29,7 @@ struct _LayerSurface // Can be set at any time gboolean anchors[GTK_LAYER_SHELL_EDGE_ENTRY_NUMBER]; // The current anchor int margins[GTK_LAYER_SHELL_EDGE_ENTRY_NUMBER]; // The current margins + int exclusive_edge; // The current exclusive edge int exclusive_zone; // The current exclusive zone (set either explicitly or automatically) gboolean auto_exclusive_zone; // If to automatically change the exclusive zone to match the window size GtkLayerShellKeyboardMode keyboard_mode; // Type of keyboard interactivity enabled for this surface @@ -58,6 +59,7 @@ void layer_surface_set_name_space (LayerSurface *self, char const* name_space); void layer_surface_set_layer (LayerSurface *self, GtkLayerShellLayer layer); // Remaps surface on old layer shell versions void layer_surface_set_anchor (LayerSurface *self, GtkLayerShellEdge edge, gboolean anchor_to_edge); void layer_surface_set_margin (LayerSurface *self, GtkLayerShellEdge edge, int margin_size); +void layer_surface_set_exclusive_edge (LayerSurface *self, int exclusive_edge); void layer_surface_set_exclusive_zone (LayerSurface *self, int exclusive_zone); void layer_surface_auto_exclusive_zone_enable (LayerSurface *self); void layer_surface_set_keyboard_mode (LayerSurface *self, GtkLayerShellKeyboardMode mode);