From aea66ddff6fd91edf10499b8fd156e0663f2f271 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Thu, 17 Aug 2017 00:49:36 -0300 Subject: [PATCH] wayland: Send edge constraints Following up the previous patch, this patch makes the Wayland backend send the edge constraints through a custom protocol extension internal to GTK. As it mature, we can think of upstreaming the protocol to Wayland itself. https://bugzilla.gnome.org/show_bug.cgi?id=751857 --- src/wayland/meta-wayland-gtk-shell.c | 113 ++++++++++++++++++++++++--- src/wayland/meta-wayland-versions.h | 2 +- src/wayland/protocol/gtk-shell.xml | 20 ++++- 3 files changed, 122 insertions(+), 13 deletions(-) diff --git a/src/wayland/meta-wayland-gtk-shell.c b/src/wayland/meta-wayland-gtk-shell.c index d6e249f02..0ef9b83ff 100644 --- a/src/wayland/meta-wayland-gtk-shell.c +++ b/src/wayland/meta-wayland-gtk-shell.c @@ -148,31 +148,124 @@ gtk_surface_surface_destroyed (MetaWaylandGtkSurface *gtk_surface) } static void -fill_states (struct wl_array *states, - MetaWindow *window) +fill_edge_states (struct wl_array *states, + MetaWindow *window) { uint32_t *s; - if (window->tile_mode == META_TILE_LEFT || - window->tile_mode == META_TILE_RIGHT) + /* Top */ + if (window->edge_constraints[0] != META_EDGE_CONSTRAINT_MONITOR) + { + s = wl_array_add (states, sizeof *s); + *s = GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_TOP; + } + + /* Right */ + if (window->edge_constraints[1] != META_EDGE_CONSTRAINT_MONITOR) + { + s = wl_array_add (states, sizeof *s); + *s = GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_RIGHT; + } + + /* Bottom */ + if (window->edge_constraints[2] != META_EDGE_CONSTRAINT_MONITOR) + { + s = wl_array_add (states, sizeof *s); + *s = GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_BOTTOM; + } + + /* Left */ + if (window->edge_constraints[3] != META_EDGE_CONSTRAINT_MONITOR) + { + s = wl_array_add (states, sizeof *s); + *s = GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_LEFT; + } +} + +static void +send_configure_edges (MetaWaylandGtkSurface *gtk_surface, + MetaWindow *window) +{ + struct wl_array edge_states; + + wl_array_init (&edge_states); + fill_edge_states (&edge_states, window); + + gtk_surface1_send_configure_edges (gtk_surface->resource, &edge_states); + + wl_array_release (&edge_states); +} + +static void +fill_states (struct wl_array *states, + MetaWindow *window, + struct wl_resource *resource) +{ + uint32_t *s; + guint version; + + version = wl_resource_get_version (resource); + + if (version < GTK_SURFACE1_CONFIGURE_EDGES_SINCE_VERSION && + (window->tile_mode == META_TILE_LEFT || + window->tile_mode == META_TILE_RIGHT)) { s = wl_array_add (states, sizeof *s); *s = GTK_SURFACE1_STATE_TILED; } + + if (version >= GTK_SURFACE1_STATE_TILED_TOP_SINCE_VERSION && + window->edge_constraints[0] != META_EDGE_CONSTRAINT_NONE) + { + s = wl_array_add (states, sizeof *s); + *s = GTK_SURFACE1_STATE_TILED_TOP; + } + + if (version >= GTK_SURFACE1_STATE_TILED_RIGHT_SINCE_VERSION && + window->edge_constraints[1] != META_EDGE_CONSTRAINT_NONE) + { + s = wl_array_add (states, sizeof *s); + *s = GTK_SURFACE1_STATE_TILED_RIGHT; + } + + if (version >= GTK_SURFACE1_STATE_TILED_BOTTOM_SINCE_VERSION && + window->edge_constraints[2] != META_EDGE_CONSTRAINT_NONE) + { + s = wl_array_add (states, sizeof *s); + *s = GTK_SURFACE1_STATE_TILED_BOTTOM; + } + + if (version >= GTK_SURFACE1_STATE_TILED_LEFT_SINCE_VERSION && + window->edge_constraints[3] != META_EDGE_CONSTRAINT_NONE) + { + s = wl_array_add (states, sizeof *s); + *s = GTK_SURFACE1_STATE_TILED_LEFT; + } +} + +static void +send_configure (MetaWaylandGtkSurface *gtk_surface, + MetaWindow *window) +{ + struct wl_array states; + + wl_array_init (&states); + fill_states (&states, window, gtk_surface->resource); + + gtk_surface1_send_configure (gtk_surface->resource, &states); + + wl_array_release (&states); } static void on_configure (MetaWaylandSurface *surface, MetaWaylandGtkSurface *gtk_surface) { - struct wl_array states; + send_configure (gtk_surface, surface->window); - wl_array_init (&states); - fill_states (&states, surface->window); - gtk_surface1_send_configure (gtk_surface->resource, &states); - - wl_array_release (&states); + if (wl_resource_get_version (gtk_surface->resource) >= GTK_SURFACE1_CONFIGURE_EDGES_SINCE_VERSION) + send_configure_edges (gtk_surface, surface->window); } static void diff --git a/src/wayland/meta-wayland-versions.h b/src/wayland/meta-wayland-versions.h index 65496b4d6..42bab7db1 100644 --- a/src/wayland/meta-wayland-versions.h +++ b/src/wayland/meta-wayland-versions.h @@ -42,7 +42,7 @@ #define META_WL_SEAT_VERSION 5 #define META_WL_OUTPUT_VERSION 2 #define META_XSERVER_VERSION 1 -#define META_GTK_SHELL1_VERSION 1 +#define META_GTK_SHELL1_VERSION 2 #define META_WL_SUBCOMPOSITOR_VERSION 1 #define META_ZWP_POINTER_GESTURES_V1_VERSION 1 #define META_ZXDG_EXPORTER_V1_VERSION 1 diff --git a/src/wayland/protocol/gtk-shell.xml b/src/wayland/protocol/gtk-shell.xml index 5cfdd42c2..8191fa9cf 100644 --- a/src/wayland/protocol/gtk-shell.xml +++ b/src/wayland/protocol/gtk-shell.xml @@ -1,6 +1,6 @@ - + gtk_shell is a protocol extension providing additional features for clients implementing it. @@ -30,7 +30,7 @@ - + @@ -51,11 +51,27 @@ + + + + + + + + + + + + + + + +