diff options
author | Matthias Clasen <mclasen@redhat.com> | 2018-03-20 16:28:00 +0000 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2018-03-20 16:28:00 +0000 |
commit | 5c8bb51a58937bfa2d62bb26ba9f1b94993df4a6 (patch) | |
tree | 0d988dadcc24fc1ea1f2cc78a00a2655cb5d9e00 | |
parent | 68fce76faf94e1b0d7a514b880dbb90f5075fc52 (diff) | |
parent | 0454a1cacec8850fefa0e7b55fe6f87d44eefb06 (diff) | |
download | gtk+-5c8bb51a58937bfa2d62bb26ba9f1b94993df4a6.tar.gz |
Merge branch 'wip/xdg-shell-gtk-3-22' into 'gtk-3-22'
xdg shell (stable; gtk 3 22)
See merge request GNOME/gtk!36
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | gdk/wayland/Makefile.am | 4 | ||||
-rw-r--r-- | gdk/wayland/gdkdisplay-wayland.c | 69 | ||||
-rw-r--r-- | gdk/wayland/gdkdisplay-wayland.h | 14 | ||||
-rw-r--r-- | gdk/wayland/gdkwindow-wayland.c | 1004 |
5 files changed, 885 insertions, 208 deletions
diff --git a/configure.ac b/configure.ac index a510c53d8d..0804206f6d 100644 --- a/configure.ac +++ b/configure.ac @@ -60,7 +60,7 @@ m4_define([cairo_required_version], [1.14.0]) m4_define([gdk_pixbuf_required_version], [2.30.0]) m4_define([introspection_required_version], [1.39.0]) m4_define([wayland_required_version], [1.9.91]) -m4_define([wayland_protocols_required_version], [1.9]) +m4_define([wayland_protocols_required_version], [1.12]) m4_define([mirclient_required_version], [0.22.0]) m4_define([mircookie_required_version], [0.17.0]) m4_define([epoxy_required_version], [1.0]) diff --git a/gdk/wayland/Makefile.am b/gdk/wayland/Makefile.am index 0b2d4ce27d..e3fb57f53d 100644 --- a/gdk/wayland/Makefile.am +++ b/gdk/wayland/Makefile.am @@ -23,6 +23,8 @@ noinst_LTLIBRARIES = \ BUILT_SOURCES = \ pointer-gestures-unstable-v1-client-protocol.h \ pointer-gestures-unstable-v1-protocol.c \ + xdg-shell-client-protocol.h \ + xdg-shell-protocol.c \ xdg-shell-unstable-v6-client-protocol.h \ xdg-shell-unstable-v6-protocol.c \ xdg-foreign-unstable-v1-client-protocol.h \ @@ -80,7 +82,7 @@ libgdkwaylandinclude_HEADERS = \ .SECONDEXPANSION: define protostability -$(shell echo $1 | sed 's/.*-\(\(un\)\{0,1\}stable\)-.*/\1/') +$(if $(findstring unstable,$1),unstable,stable) endef define protoname diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index 3e9ca8465d..b4ef4485da 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -119,9 +119,28 @@ _gdk_wayland_display_async_roundtrip (GdkWaylandDisplay *display_wayland) } static void -xdg_shell_ping (void *data, - struct zxdg_shell_v6 *xdg_shell, - uint32_t serial) +xdg_wm_base_ping (void *data, + struct xdg_wm_base *xdg_wm_base, + uint32_t serial) +{ + GdkWaylandDisplay *display_wayland = data; + + _gdk_wayland_display_update_serial (display_wayland, serial); + + GDK_NOTE (EVENTS, + g_message ("ping, shell %p, serial %u\n", xdg_wm_base, serial)); + + xdg_wm_base_pong (xdg_wm_base, serial); +} + +static const struct xdg_wm_base_listener xdg_wm_base_listener = { + xdg_wm_base_ping, +}; + +static void +zxdg_shell_v6_ping (void *data, + struct zxdg_shell_v6 *xdg_shell, + uint32_t serial) { GdkWaylandDisplay *display_wayland = data; @@ -133,8 +152,8 @@ xdg_shell_ping (void *data, zxdg_shell_v6_pong (xdg_shell, serial); } -static const struct zxdg_shell_v6_listener xdg_shell_listener = { - xdg_shell_ping, +static const struct zxdg_shell_v6_listener zxdg_shell_v6_listener = { + zxdg_shell_v6_ping, }; static gboolean @@ -388,14 +407,13 @@ gdk_registry_handle_global (void *data, wl_registry_bind (display_wayland->wl_registry, id, &wl_shm_interface, 1); wl_shm_add_listener (display_wayland->shm, &wl_shm_listener, display_wayland); } + else if (strcmp (interface, "xdg_wm_base") == 0) + { + display_wayland->xdg_wm_base_id = id; + } else if (strcmp (interface, "zxdg_shell_v6") == 0) { - display_wayland->xdg_shell = - wl_registry_bind (display_wayland->wl_registry, id, - &zxdg_shell_v6_interface, 1); - zxdg_shell_v6_add_listener (display_wayland->xdg_shell, - &xdg_shell_listener, - display_wayland); + display_wayland->zxdg_shell_v6_id = id; } else if (strcmp (interface, "gtk_shell1") == 0) { @@ -603,11 +621,32 @@ _gdk_wayland_display_open (const gchar *display_name) } } - /* Make sure we have xdg_shell at least */ - if (display_wayland->xdg_shell == NULL) + if (display_wayland->xdg_wm_base_id) + { + display_wayland->shell_variant = GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL; + display_wayland->xdg_wm_base = + wl_registry_bind (display_wayland->wl_registry, + display_wayland->xdg_wm_base_id, + &xdg_wm_base_interface, 1); + xdg_wm_base_add_listener (display_wayland->xdg_wm_base, + &xdg_wm_base_listener, + display_wayland); + } + else if (display_wayland->zxdg_shell_v6_id) + { + display_wayland->shell_variant = GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6; + display_wayland->zxdg_shell_v6 = + wl_registry_bind (display_wayland->wl_registry, + display_wayland->zxdg_shell_v6_id, + &zxdg_shell_v6_interface, 1); + zxdg_shell_v6_add_listener (display_wayland->zxdg_shell_v6, + &zxdg_shell_v6_listener, + display_wayland); + } + else { - g_warning ("Wayland compositor does not support xdg_shell interface," - " not using Wayland display"); + g_warning ("The Wayland compositor does not provide any supported shell interface, " + "not using Wayland display"); g_object_unref (display); return NULL; diff --git a/gdk/wayland/gdkdisplay-wayland.h b/gdk/wayland/gdkdisplay-wayland.h index 61ac7a4d5f..d8b4a8d7d1 100644 --- a/gdk/wayland/gdkdisplay-wayland.h +++ b/gdk/wayland/gdkdisplay-wayland.h @@ -29,6 +29,7 @@ #include <wayland-egl.h> #include <gdk/wayland/tablet-unstable-v2-client-protocol.h> #include <gdk/wayland/gtk-shell-client-protocol.h> +#include <gdk/wayland/xdg-shell-client-protocol.h> #include <gdk/wayland/xdg-shell-unstable-v6-client-protocol.h> #include <gdk/wayland/xdg-foreign-unstable-v1-client-protocol.h> #include <gdk/wayland/keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h> @@ -53,6 +54,12 @@ G_BEGIN_DECLS typedef struct _GdkWaylandSelection GdkWaylandSelection; +typedef enum _GdkWaylandShellVariant +{ + GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL, + GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6, +} GdkWaylandShellVariant; + struct _GdkWaylandDisplay { GdkDisplay parent_instance; @@ -64,12 +71,17 @@ struct _GdkWaylandDisplay /* Most recent serial */ guint32 serial; + uint32_t xdg_wm_base_id; + uint32_t zxdg_shell_v6_id; + GdkWaylandShellVariant shell_variant; + /* Wayland fields below */ struct wl_display *wl_display; struct wl_registry *wl_registry; struct wl_compositor *compositor; struct wl_shm *shm; - struct zxdg_shell_v6 *xdg_shell; + struct xdg_wm_base *xdg_wm_base; + struct zxdg_shell_v6 *zxdg_shell_v6; struct gtk_shell1 *gtk_shell; struct wl_input_device *input_device; struct wl_data_device_manager *data_device_manager; diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index 9ee4fe2be4..3746d13206 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -118,9 +118,16 @@ struct _GdkWindowImplWayland GSList *outputs; struct wl_surface *wl_surface; - struct zxdg_surface_v6 *xdg_surface; - struct zxdg_toplevel_v6 *xdg_toplevel; - struct zxdg_popup_v6 *xdg_popup; + + struct xdg_surface *xdg_surface; + struct xdg_toplevel *xdg_toplevel; + struct xdg_popup *xdg_popup; + + /* Legacy xdg-shell unstable v6 fallback support */ + struct zxdg_surface_v6 *zxdg_surface_v6; + struct zxdg_toplevel_v6 *zxdg_toplevel_v6; + struct zxdg_popup_v6 *zxdg_popup_v6; + struct gtk_surface1 *gtk_surface; struct wl_subsurface *wl_subsurface; struct wl_egl_window *egl_window; @@ -1019,6 +1026,33 @@ gdk_wayland_window_configure (GdkWindow *window, _gdk_wayland_display_deliver_event (display, event); } +static gboolean +is_realized_shell_surface (GdkWindow *window) +{ + GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + return (impl->display_server.xdg_surface || + impl->display_server.zxdg_surface_v6); +} + +static gboolean +is_realized_toplevel (GdkWindow *window) +{ + GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + return (impl->display_server.xdg_toplevel || + impl->display_server.zxdg_toplevel_v6); +} + +static gboolean +is_realized_popup (GdkWindow *window) +{ + GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + return (impl->display_server.xdg_popup || + impl->display_server.zxdg_popup_v6); +} + static void gdk_wayland_window_maybe_configure (GdkWindow *window, int width, @@ -1040,7 +1074,7 @@ gdk_wayland_window_maybe_configure (GdkWindow *window, * force the new size onto the compositor. See bug #772505. */ - is_xdg_popup = (impl->display_server.xdg_popup != NULL); + is_xdg_popup = is_realized_popup (window); is_visible = gdk_window_is_visible (window); if (is_xdg_popup && is_visible && !impl->initial_configure_received) @@ -1056,14 +1090,15 @@ static void gdk_wayland_window_sync_parent (GdkWindow *window, GdkWindow *parent) { + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)); GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); GdkWindowImplWayland *impl_parent = NULL; - struct zxdg_toplevel_v6 *parent_toplevel; g_assert (parent == NULL || gdk_window_get_display (window) == gdk_window_get_display (parent)); - if (!impl->display_server.xdg_toplevel) + if (!is_realized_toplevel (window)) return; if (impl->transient_for) @@ -1071,19 +1106,40 @@ gdk_wayland_window_sync_parent (GdkWindow *window, else if (parent) impl_parent = GDK_WINDOW_IMPL_WAYLAND (parent->impl); - if (impl_parent) + /* XXX: Is this correct? */ + if (impl_parent && !impl_parent->display_server.wl_surface) + return; + + switch (display_wayland->shell_variant) { - /* XXX: Is this correct? */ - if (!impl_parent->display_server.wl_surface) - return; + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + { + struct xdg_toplevel *parent_toplevel; - parent_toplevel = impl_parent->display_server.xdg_toplevel; - } - else - parent_toplevel = NULL; + if (impl_parent) + parent_toplevel = impl_parent->display_server.xdg_toplevel; + else + parent_toplevel = NULL; + + xdg_toplevel_set_parent (impl->display_server.xdg_toplevel, + parent_toplevel); + break; + } + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + { + struct zxdg_toplevel_v6 *parent_toplevel; - zxdg_toplevel_v6_set_parent (impl->display_server.xdg_toplevel, - parent_toplevel); + if (impl_parent) + parent_toplevel = impl_parent->display_server.zxdg_toplevel_v6; + else + parent_toplevel = NULL; + + zxdg_toplevel_v6_set_parent (impl->display_server.zxdg_toplevel_v6, + parent_toplevel); + break; + } + } } static void @@ -1097,7 +1153,7 @@ gdk_wayland_window_sync_parent_of_imported (GdkWindow *window) if (!impl->imported_transient_for) return; - if (!impl->display_server.xdg_toplevel) + if (!is_realized_toplevel (window)) return; zxdg_imported_v1_set_parent_of (impl->imported_transient_for, @@ -1139,14 +1195,26 @@ static void gdk_wayland_window_sync_title (GdkWindow *window) { GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)); - if (!impl->display_server.xdg_toplevel) + if (!is_realized_toplevel (window)) return; if (!impl->title) return; - zxdg_toplevel_v6_set_title (impl->display_server.xdg_toplevel, impl->title); + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_toplevel_set_title (impl->display_server.xdg_toplevel, + impl->title); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_toplevel_v6_set_title (impl->display_server.zxdg_toplevel_v6, + impl->title); + break; + } } static void @@ -1167,20 +1235,35 @@ static void gdk_wayland_window_sync_margin (GdkWindow *window) { GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)); GdkRectangle geometry; - if (!impl->display_server.xdg_surface) + if (!is_realized_shell_surface (window)) return; gdk_wayland_window_get_window_geometry (window, &geometry); gdk_window_set_geometry_hints (window, &impl->geometry_hints, impl->geometry_mask); - zxdg_surface_v6_set_window_geometry (impl->display_server.xdg_surface, + + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_surface_set_window_geometry (impl->display_server.xdg_surface, geometry.x, geometry.y, geometry.width, geometry.height); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_surface_v6_set_window_geometry (impl->display_server.zxdg_surface_v6, + geometry.x, + geometry.y, + geometry.width, + geometry.height); + break; + } } static struct wl_region * @@ -1382,12 +1465,12 @@ gdk_wayland_window_create_surface (GdkWindow *window) } static void -xdg_surface_configure (void *data, - struct zxdg_surface_v6 *xdg_surface, - uint32_t serial) +gdk_wayland_window_handle_configure (GdkWindow *window, + uint32_t serial) { - GdkWindow *window = GDK_WINDOW (data); GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)); GdkWindowState new_state; int width = impl->pending.width; int height = impl->pending.height; @@ -1402,7 +1485,13 @@ xdg_surface_configure (void *data, if (impl->display_server.xdg_popup) { - zxdg_surface_v6_ack_configure (xdg_surface, serial); + xdg_surface_ack_configure (impl->display_server.xdg_surface, serial); + return; + } + else if (impl->display_server.zxdg_popup_v6) + { + zxdg_surface_v6_ack_configure (impl->display_server.zxdg_surface_v6, + serial); return; } @@ -1410,7 +1499,9 @@ xdg_surface_configure (void *data, impl->pending.state = 0; fixed_size = - new_state & (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN | GDK_WINDOW_STATE_TILED); + new_state & (GDK_WINDOW_STATE_MAXIMIZED | + GDK_WINDOW_STATE_FULLSCREEN | + GDK_WINDOW_STATE_TILED); saved_size = (width == 0 && height == 0); /* According to xdg_shell, an xdg_surface.configure with size 0x0 @@ -1460,40 +1551,179 @@ xdg_surface_configure (void *data, (new_state & GDK_WINDOW_STATE_TILED) ? " tiled" : "")); _gdk_set_window_state (window, new_state); - zxdg_surface_v6_ack_configure (xdg_surface, serial); + + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_surface_ack_configure (impl->display_server.xdg_surface, serial); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_surface_v6_ack_configure (impl->display_server.zxdg_surface_v6, + serial); + break; + } + if (impl->hint != GDK_WINDOW_TYPE_HINT_DIALOG && new_state & GDK_WINDOW_STATE_FOCUSED) gdk_wayland_window_update_dialogs (window); } -static const struct zxdg_surface_v6_listener xdg_surface_listener = { +static void +gdk_wayland_window_handle_configure_toplevel (GdkWindow *window, + int32_t width, + int32_t height, + GdkWindowState state) +{ + GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + impl->pending.state |= state; + impl->pending.width = width; + impl->pending.height = height; +} + +static void +gdk_wayland_window_handle_close (GdkWindow *window) +{ + GdkDisplay *display; + GdkEvent *event; + + GDK_NOTE (EVENTS, + g_message ("close %p", window)); + + event = gdk_event_new (GDK_DELETE); + event->any.window = g_object_ref (window); + event->any.send_event = TRUE; + + display = gdk_window_get_display (window); + _gdk_wayland_display_deliver_event (display, event); +} + +static void +xdg_surface_configure (void *data, + struct xdg_surface *xdg_surface, + uint32_t serial) +{ + GdkWindow *window = GDK_WINDOW (data); + + gdk_wayland_window_handle_configure (window, serial); +} + +static const struct xdg_surface_listener xdg_surface_listener = { xdg_surface_configure, }; static void -xdg_toplevel_configure (void *data, - struct zxdg_toplevel_v6 *xdg_toplevel, - int32_t width, - int32_t height, - struct wl_array *states) +xdg_toplevel_configure (void *data, + struct xdg_toplevel *xdg_toplevel, + int32_t width, + int32_t height, + struct wl_array *states) { GdkWindow *window = GDK_WINDOW (data); + uint32_t *p; + GdkWindowState pending_state = 0; + + wl_array_for_each (p, states) + { + uint32_t state = *p; + + switch (state) + { + case XDG_TOPLEVEL_STATE_FULLSCREEN: + pending_state |= GDK_WINDOW_STATE_FULLSCREEN; + break; + case XDG_TOPLEVEL_STATE_MAXIMIZED: + pending_state |= GDK_WINDOW_STATE_MAXIMIZED; + break; + case XDG_TOPLEVEL_STATE_ACTIVATED: + pending_state |= GDK_WINDOW_STATE_FOCUSED; + break; + case XDG_TOPLEVEL_STATE_RESIZING: + break; + default: + /* Unknown state */ + break; + } + } + + gdk_wayland_window_handle_configure_toplevel (window, width, height, + pending_state); +} + +static void +xdg_toplevel_close (void *data, + struct xdg_toplevel *xdg_toplevel) +{ + GdkWindow *window = GDK_WINDOW (data); + + gdk_wayland_window_handle_close (window); +} + +static const struct xdg_toplevel_listener xdg_toplevel_listener = { + xdg_toplevel_configure, + xdg_toplevel_close, +}; + +static void +create_xdg_toplevel_resources (GdkWindow *window) +{ + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)); GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + impl->display_server.xdg_surface = + xdg_wm_base_get_xdg_surface (display_wayland->xdg_wm_base, + impl->display_server.wl_surface); + xdg_surface_add_listener (impl->display_server.xdg_surface, + &xdg_surface_listener, + window); + + impl->display_server.xdg_toplevel = + xdg_surface_get_toplevel (impl->display_server.xdg_surface); + xdg_toplevel_add_listener (impl->display_server.xdg_toplevel, + &xdg_toplevel_listener, + window); +} + +static void +zxdg_surface_v6_configure (void *data, + struct zxdg_surface_v6 *xdg_surface, + uint32_t serial) +{ + GdkWindow *window = GDK_WINDOW (data); + + gdk_wayland_window_handle_configure (window, serial); +} + +static const struct zxdg_surface_v6_listener zxdg_surface_v6_listener = { + zxdg_surface_v6_configure, +}; + +static void +zxdg_toplevel_v6_configure (void *data, + struct zxdg_toplevel_v6 *xdg_toplevel, + int32_t width, + int32_t height, + struct wl_array *states) +{ + GdkWindow *window = GDK_WINDOW (data); uint32_t *p; + GdkWindowState pending_state = 0; wl_array_for_each (p, states) { uint32_t state = *p; + switch (state) { case ZXDG_TOPLEVEL_V6_STATE_FULLSCREEN: - impl->pending.state |= GDK_WINDOW_STATE_FULLSCREEN; + pending_state |= GDK_WINDOW_STATE_FULLSCREEN; break; case ZXDG_TOPLEVEL_V6_STATE_MAXIMIZED: - impl->pending.state |= GDK_WINDOW_STATE_MAXIMIZED; + pending_state |= GDK_WINDOW_STATE_MAXIMIZED; break; case ZXDG_TOPLEVEL_V6_STATE_ACTIVATED: - impl->pending.state |= GDK_WINDOW_STATE_FOCUSED; + pending_state |= GDK_WINDOW_STATE_FOCUSED; break; case ZXDG_TOPLEVEL_V6_STATE_RESIZING: break; @@ -1503,35 +1733,46 @@ xdg_toplevel_configure (void *data, } } - impl->pending.width = width; - impl->pending.height = height; + gdk_wayland_window_handle_configure_toplevel (window, width, height, + pending_state); } static void -xdg_toplevel_close (void *data, - struct zxdg_toplevel_v6 *xdg_toplevel) +zxdg_toplevel_v6_close (void *data, + struct zxdg_toplevel_v6 *xdg_toplevel) { GdkWindow *window = GDK_WINDOW (data); - GdkDisplay *display; - GdkEvent *event; - GDK_NOTE (EVENTS, - g_message ("close %p", window)); - - event = gdk_event_new (GDK_DELETE); - event->any.window = g_object_ref (window); - event->any.send_event = TRUE; - - display = gdk_window_get_display (window); - _gdk_wayland_display_deliver_event (display, event); + gdk_wayland_window_handle_close (window); } -static const struct zxdg_toplevel_v6_listener xdg_toplevel_listener = { - xdg_toplevel_configure, - xdg_toplevel_close, +static const struct zxdg_toplevel_v6_listener zxdg_toplevel_v6_listener = { + zxdg_toplevel_v6_configure, + zxdg_toplevel_v6_close, }; static void +create_zxdg_toplevel_v6_resources (GdkWindow *window) +{ + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)); + GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + impl->display_server.zxdg_surface_v6 = + zxdg_shell_v6_get_xdg_surface (display_wayland->zxdg_shell_v6, + impl->display_server.wl_surface); + zxdg_surface_v6_add_listener (impl->display_server.zxdg_surface_v6, + &zxdg_surface_v6_listener, + window); + + impl->display_server.zxdg_toplevel_v6 = + zxdg_surface_v6_get_toplevel (impl->display_server.zxdg_surface_v6); + zxdg_toplevel_v6_add_listener (impl->display_server.zxdg_toplevel_v6, + &zxdg_toplevel_v6_listener, + window); +} + +static void gdk_wayland_window_create_xdg_toplevel (GdkWindow *window) { GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)); @@ -1539,41 +1780,64 @@ gdk_wayland_window_create_xdg_toplevel (GdkWindow *window) const gchar *app_id; GdkScreen *screen = gdk_window_get_screen (window); struct wl_output *fullscreen_output = NULL; + G_GNUC_BEGIN_IGNORE_DEPRECATIONS if (impl->initial_fullscreen_monitor >= 0 && impl->initial_fullscreen_monitor < gdk_screen_get_n_monitors (screen)) - fullscreen_output = _gdk_wayland_screen_get_wl_output (screen, impl->initial_fullscreen_monitor); + fullscreen_output = + _gdk_wayland_screen_get_wl_output (screen, + impl->initial_fullscreen_monitor); G_GNUC_END_IGNORE_DEPRECATIONS - impl->display_server.xdg_surface = - zxdg_shell_v6_get_xdg_surface (display_wayland->xdg_shell, - impl->display_server.wl_surface); - zxdg_surface_v6_add_listener (impl->display_server.xdg_surface, - &xdg_surface_listener, - window); gdk_window_freeze_updates (window); - impl->display_server.xdg_toplevel = - zxdg_surface_v6_get_toplevel (impl->display_server.xdg_surface); - zxdg_toplevel_v6_add_listener (impl->display_server.xdg_toplevel, - &xdg_toplevel_listener, - window); + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + create_xdg_toplevel_resources (window); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + create_zxdg_toplevel_v6_resources (window); + break; + } gdk_wayland_window_sync_parent (window, NULL); gdk_wayland_window_sync_parent_of_imported (window); gdk_wayland_window_sync_title (window); - if (window->state & GDK_WINDOW_STATE_MAXIMIZED) - zxdg_toplevel_v6_set_maximized (impl->display_server.xdg_toplevel); - if (window->state & GDK_WINDOW_STATE_FULLSCREEN) - zxdg_toplevel_v6_set_fullscreen (impl->display_server.xdg_toplevel, + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + if (window->state & GDK_WINDOW_STATE_MAXIMIZED) + xdg_toplevel_set_maximized (impl->display_server.xdg_toplevel); + if (window->state & GDK_WINDOW_STATE_FULLSCREEN) + xdg_toplevel_set_fullscreen (impl->display_server.xdg_toplevel, fullscreen_output); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + if (window->state & GDK_WINDOW_STATE_MAXIMIZED) + zxdg_toplevel_v6_set_maximized (impl->display_server.zxdg_toplevel_v6); + if (window->state & GDK_WINDOW_STATE_FULLSCREEN) + zxdg_toplevel_v6_set_fullscreen (impl->display_server.zxdg_toplevel_v6, + fullscreen_output); + break; + } app_id = g_get_prgname (); if (app_id == NULL) app_id = gdk_get_program_class (); - zxdg_toplevel_v6_set_app_id (impl->display_server.xdg_toplevel, app_id); + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_toplevel_set_app_id (impl->display_server.xdg_toplevel, + app_id); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_toplevel_v6_set_app_id (impl->display_server.zxdg_toplevel_v6, + app_id); + break; + } maybe_set_gtk_surface_dbus_properties (window); maybe_set_gtk_surface_modal (window); @@ -1585,14 +1849,12 @@ G_GNUC_END_IGNORE_DEPRECATIONS } static void -xdg_popup_configure (void *data, - struct zxdg_popup_v6 *xdg_popup, - int32_t x, - int32_t y, - int32_t width, - int32_t height) +gdk_wayland_window_handle_configure_popup (GdkWindow *window, + int32_t x, + int32_t y, + int32_t width, + int32_t height) { - GdkWindow *window = GDK_WINDOW (data); GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); GdkRectangle flipped_rect; GdkRectangle final_rect; @@ -1619,8 +1881,21 @@ xdg_popup_configure (void *data, } static void -xdg_popup_done (void *data, - struct zxdg_popup_v6 *xdg_popup) +xdg_popup_configure (void *data, + struct xdg_popup *xdg_popup, + int32_t x, + int32_t y, + int32_t width, + int32_t height) +{ + GdkWindow *window = GDK_WINDOW (data); + + gdk_wayland_window_handle_configure_popup (window, x, y, width, height); +} + +static void +xdg_popup_done (void *data, + struct xdg_popup *xdg_popup) { GdkWindow *window = GDK_WINDOW (data); @@ -1630,18 +1905,106 @@ xdg_popup_done (void *data, gdk_window_hide (window); } -static const struct zxdg_popup_v6_listener xdg_popup_listener = { +static const struct xdg_popup_listener xdg_popup_listener = { xdg_popup_configure, xdg_popup_done, }; -static enum zxdg_positioner_v6_anchor +static void +zxdg_popup_v6_configure (void *data, + struct zxdg_popup_v6 *xdg_popup, + int32_t x, + int32_t y, + int32_t width, + int32_t height) +{ + GdkWindow *window = GDK_WINDOW (data); + + gdk_wayland_window_handle_configure_popup (window, x, y, width, height); +} + +static void +zxdg_popup_v6_done (void *data, + struct zxdg_popup_v6 *xdg_popup) +{ + GdkWindow *window = GDK_WINDOW (data); + + GDK_NOTE (EVENTS, + g_message ("done %p", window)); + + gdk_window_hide (window); +} + +static const struct zxdg_popup_v6_listener zxdg_popup_v6_listener = { + zxdg_popup_v6_configure, + zxdg_popup_v6_done, +}; + +static enum xdg_positioner_anchor rect_anchor_to_anchor (GdkGravity rect_anchor) { switch (rect_anchor) { case GDK_GRAVITY_NORTH_WEST: case GDK_GRAVITY_STATIC: + return XDG_POSITIONER_ANCHOR_TOP_LEFT; + case GDK_GRAVITY_NORTH: + return XDG_POSITIONER_ANCHOR_TOP; + case GDK_GRAVITY_NORTH_EAST: + return XDG_POSITIONER_ANCHOR_TOP_RIGHT; + case GDK_GRAVITY_WEST: + return XDG_POSITIONER_ANCHOR_LEFT; + case GDK_GRAVITY_CENTER: + return XDG_POSITIONER_ANCHOR_NONE; + case GDK_GRAVITY_EAST: + return XDG_POSITIONER_ANCHOR_RIGHT; + case GDK_GRAVITY_SOUTH_WEST: + return XDG_POSITIONER_ANCHOR_BOTTOM_LEFT; + case GDK_GRAVITY_SOUTH: + return XDG_POSITIONER_ANCHOR_BOTTOM; + case GDK_GRAVITY_SOUTH_EAST: + return XDG_POSITIONER_ANCHOR_BOTTOM_RIGHT; + default: + g_assert_not_reached (); + } +} + +static enum xdg_positioner_gravity +window_anchor_to_gravity (GdkGravity rect_anchor) +{ + switch (rect_anchor) + { + case GDK_GRAVITY_NORTH_WEST: + case GDK_GRAVITY_STATIC: + return XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT; + case GDK_GRAVITY_NORTH: + return XDG_POSITIONER_GRAVITY_BOTTOM; + case GDK_GRAVITY_NORTH_EAST: + return XDG_POSITIONER_GRAVITY_BOTTOM_LEFT; + case GDK_GRAVITY_WEST: + return XDG_POSITIONER_GRAVITY_RIGHT; + case GDK_GRAVITY_CENTER: + return XDG_POSITIONER_GRAVITY_NONE; + case GDK_GRAVITY_EAST: + return XDG_POSITIONER_GRAVITY_LEFT; + case GDK_GRAVITY_SOUTH_WEST: + return XDG_POSITIONER_GRAVITY_TOP_RIGHT; + case GDK_GRAVITY_SOUTH: + return XDG_POSITIONER_GRAVITY_TOP; + case GDK_GRAVITY_SOUTH_EAST: + return XDG_POSITIONER_GRAVITY_TOP_LEFT; + default: + g_assert_not_reached (); + } +} + +static enum zxdg_positioner_v6_anchor +rect_anchor_to_anchor_legacy (GdkGravity rect_anchor) +{ + switch (rect_anchor) + { + case GDK_GRAVITY_NORTH_WEST: + case GDK_GRAVITY_STATIC: return (ZXDG_POSITIONER_V6_ANCHOR_TOP | ZXDG_POSITIONER_V6_ANCHOR_LEFT); case GDK_GRAVITY_NORTH: @@ -1669,7 +2032,7 @@ rect_anchor_to_anchor (GdkGravity rect_anchor) } static enum zxdg_positioner_v6_gravity -window_anchor_to_gravity (GdkGravity rect_anchor) +window_anchor_to_gravity_legacy (GdkGravity rect_anchor) { switch (rect_anchor) { @@ -2026,24 +2389,18 @@ calculate_moved_to_rect_result (GdkWindow *window, *flipped_y = flipped_rect->y != best_rect.y; } -static struct zxdg_positioner_v6 * +static gpointer create_dynamic_positioner (GdkWindow *window) { GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)); - struct zxdg_positioner_v6 *positioner; GdkRectangle geometry; - enum zxdg_positioner_v6_anchor anchor; - enum zxdg_positioner_v6_gravity gravity; uint32_t constraint_adjustment = ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_NONE; gint real_anchor_rect_x, real_anchor_rect_y; gint anchor_rect_width, anchor_rect_height; - positioner = zxdg_shell_v6_create_positioner (display->xdg_shell); - gdk_wayland_window_get_window_geometry (window, &geometry); - zxdg_positioner_v6_set_size (positioner, geometry.width, geometry.height); real_anchor_rect_x = impl->pending_move_to_rect.rect.x; real_anchor_rect_y = impl->pending_move_to_rect.rect.y; @@ -2053,56 +2410,107 @@ create_dynamic_positioner (GdkWindow *window) anchor_rect_width = impl->pending_move_to_rect.rect.width; anchor_rect_height = impl->pending_move_to_rect.rect.height; - zxdg_positioner_v6_set_anchor_rect (positioner, - real_anchor_rect_x, - real_anchor_rect_y, - anchor_rect_width, - anchor_rect_height); - - zxdg_positioner_v6_set_offset (positioner, - impl->pending_move_to_rect.rect_anchor_dx, - impl->pending_move_to_rect.rect_anchor_dy); - - anchor = rect_anchor_to_anchor (impl->pending_move_to_rect.rect_anchor); - zxdg_positioner_v6_set_anchor (positioner, anchor); - - gravity = window_anchor_to_gravity (impl->pending_move_to_rect.window_anchor); - zxdg_positioner_v6_set_gravity (positioner, gravity); - - if (impl->pending_move_to_rect.anchor_hints & GDK_ANCHOR_FLIP_X) - constraint_adjustment |= ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_X; - if (impl->pending_move_to_rect.anchor_hints & GDK_ANCHOR_FLIP_Y) - constraint_adjustment |= ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_Y; - if (impl->pending_move_to_rect.anchor_hints & GDK_ANCHOR_SLIDE_X) - constraint_adjustment |= ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_SLIDE_X; - if (impl->pending_move_to_rect.anchor_hints & GDK_ANCHOR_SLIDE_Y) - constraint_adjustment |= ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_SLIDE_Y; - if (impl->pending_move_to_rect.anchor_hints & GDK_ANCHOR_RESIZE_X) - constraint_adjustment |= ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_RESIZE_X; - if (impl->pending_move_to_rect.anchor_hints & GDK_ANCHOR_RESIZE_Y) - constraint_adjustment |= ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_RESIZE_Y; - - zxdg_positioner_v6_set_constraint_adjustment (positioner, - constraint_adjustment); - - return positioner; -} - -static struct zxdg_positioner_v6 * + + switch (display->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + { + struct xdg_positioner *positioner; + enum xdg_positioner_anchor anchor; + enum xdg_positioner_gravity gravity; + + positioner = xdg_wm_base_create_positioner (display->xdg_wm_base); + + xdg_positioner_set_size (positioner, geometry.width, geometry.height); + xdg_positioner_set_anchor_rect (positioner, + real_anchor_rect_x, + real_anchor_rect_y, + anchor_rect_width, + anchor_rect_height); + xdg_positioner_set_offset (positioner, + impl->pending_move_to_rect.rect_anchor_dx, + impl->pending_move_to_rect.rect_anchor_dy); + + anchor = rect_anchor_to_anchor (impl->pending_move_to_rect.rect_anchor); + xdg_positioner_set_anchor (positioner, anchor); + + gravity = window_anchor_to_gravity (impl->pending_move_to_rect.window_anchor); + xdg_positioner_set_gravity (positioner, gravity); + + if (impl->pending_move_to_rect.anchor_hints & GDK_ANCHOR_FLIP_X) + constraint_adjustment |= XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_X; + if (impl->pending_move_to_rect.anchor_hints & GDK_ANCHOR_FLIP_Y) + constraint_adjustment |= XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_Y; + if (impl->pending_move_to_rect.anchor_hints & GDK_ANCHOR_SLIDE_X) + constraint_adjustment |= XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X; + if (impl->pending_move_to_rect.anchor_hints & GDK_ANCHOR_SLIDE_Y) + constraint_adjustment |= XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_Y; + if (impl->pending_move_to_rect.anchor_hints & GDK_ANCHOR_RESIZE_X) + constraint_adjustment |= XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_X; + if (impl->pending_move_to_rect.anchor_hints & GDK_ANCHOR_RESIZE_Y) + constraint_adjustment |= XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_Y; + xdg_positioner_set_constraint_adjustment (positioner, + constraint_adjustment); + + return positioner; + } + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + { + struct zxdg_positioner_v6 *positioner; + enum zxdg_positioner_v6_anchor anchor; + enum zxdg_positioner_v6_gravity gravity; + + positioner = zxdg_shell_v6_create_positioner (display->zxdg_shell_v6); + + zxdg_positioner_v6_set_size (positioner, geometry.width, geometry.height); + zxdg_positioner_v6_set_anchor_rect (positioner, + real_anchor_rect_x, + real_anchor_rect_y, + anchor_rect_width, + anchor_rect_height); + zxdg_positioner_v6_set_offset (positioner, + impl->pending_move_to_rect.rect_anchor_dx, + impl->pending_move_to_rect.rect_anchor_dy); + + anchor = rect_anchor_to_anchor_legacy (impl->pending_move_to_rect.rect_anchor); + zxdg_positioner_v6_set_anchor (positioner, anchor); + + gravity = window_anchor_to_gravity_legacy (impl->pending_move_to_rect.window_anchor); + zxdg_positioner_v6_set_gravity (positioner, gravity); + + if (impl->pending_move_to_rect.anchor_hints & GDK_ANCHOR_FLIP_X) + constraint_adjustment |= ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_X; + if (impl->pending_move_to_rect.anchor_hints & GDK_ANCHOR_FLIP_Y) + constraint_adjustment |= ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_Y; + if (impl->pending_move_to_rect.anchor_hints & GDK_ANCHOR_SLIDE_X) + constraint_adjustment |= ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_SLIDE_X; + if (impl->pending_move_to_rect.anchor_hints & GDK_ANCHOR_SLIDE_Y) + constraint_adjustment |= ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_SLIDE_Y; + if (impl->pending_move_to_rect.anchor_hints & GDK_ANCHOR_RESIZE_X) + constraint_adjustment |= ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_RESIZE_X; + if (impl->pending_move_to_rect.anchor_hints & GDK_ANCHOR_RESIZE_Y) + constraint_adjustment |= ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_RESIZE_Y; + zxdg_positioner_v6_set_constraint_adjustment (positioner, + constraint_adjustment); + + return positioner; + } + } + + g_assert_not_reached (); +} + +static gpointer create_simple_positioner (GdkWindow *window, GdkWindow *parent) { GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)); - struct zxdg_positioner_v6 *positioner; GdkRectangle geometry; GdkRectangle parent_geometry; int parent_x, parent_y; - positioner = zxdg_shell_v6_create_positioner (display->xdg_shell); - gdk_wayland_window_get_window_geometry (window, &geometry); - zxdg_positioner_v6_set_size (positioner, geometry.width, geometry.height); parent_x = parent->x; parent_y = parent->y; @@ -2111,18 +2519,47 @@ create_simple_positioner (GdkWindow *window, parent_x += parent_geometry.x; parent_y += parent_geometry.y; - zxdg_positioner_v6_set_anchor_rect (positioner, - (window->x + geometry.x) - parent_x, - (window->y + geometry.y) - parent_y, - 1, 1); - zxdg_positioner_v6_set_anchor (positioner, - (ZXDG_POSITIONER_V6_ANCHOR_TOP | - ZXDG_POSITIONER_V6_ANCHOR_LEFT)); - zxdg_positioner_v6_set_gravity (positioner, - (ZXDG_POSITIONER_V6_GRAVITY_BOTTOM | - ZXDG_POSITIONER_V6_GRAVITY_RIGHT)); + switch (display->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + { + struct xdg_positioner *positioner; + + positioner = xdg_wm_base_create_positioner (display->xdg_wm_base); + xdg_positioner_set_size (positioner, geometry.width, geometry.height); + xdg_positioner_set_anchor_rect (positioner, + (window->x + geometry.x) - parent_x, + (window->y + geometry.y) - parent_y, + 1, 1); + xdg_positioner_set_anchor (positioner, + XDG_POSITIONER_ANCHOR_TOP_LEFT); + xdg_positioner_set_gravity (positioner, + XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT); + + return positioner; + } + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + { + struct zxdg_positioner_v6 *positioner; + + positioner = zxdg_shell_v6_create_positioner (display->zxdg_shell_v6); + zxdg_positioner_v6_set_size (positioner, geometry.width, geometry.height); + zxdg_positioner_v6_set_anchor_rect (positioner, + (window->x + geometry.x) - parent_x, + (window->y + geometry.y) - parent_y, + 1, 1); + zxdg_positioner_v6_set_anchor (positioner, + (ZXDG_POSITIONER_V6_ANCHOR_TOP | + ZXDG_POSITIONER_V6_ANCHOR_LEFT)); + zxdg_positioner_v6_set_gravity (positioner, + (ZXDG_POSITIONER_V6_GRAVITY_BOTTOM | + ZXDG_POSITIONER_V6_GRAVITY_RIGHT)); + + return positioner; + } + } - return positioner; + g_assert_not_reached (); } static void @@ -2133,22 +2570,22 @@ gdk_wayland_window_create_xdg_popup (GdkWindow *window, GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)); GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); GdkWindowImplWayland *parent_impl = GDK_WINDOW_IMPL_WAYLAND (parent->impl); - struct zxdg_positioner_v6 *positioner; + gpointer positioner; GdkSeat *gdk_seat; guint32 serial; if (!impl->display_server.wl_surface) return; - if (!parent_impl->display_server.xdg_surface) + if (!is_realized_shell_surface (parent)) return; - if (impl->display_server.xdg_toplevel) + if (is_realized_toplevel (window)) { g_warning ("Can't map popup, already mapped as toplevel"); return; } - if (impl->display_server.xdg_popup) + if (is_realized_popup (window)) { g_warning ("Can't map popup, already mapped"); return; @@ -2156,18 +2593,12 @@ gdk_wayland_window_create_xdg_popup (GdkWindow *window, if ((display->current_popups && g_list_last (display->current_popups)->data != parent) || (!display->current_popups && - !parent_impl->display_server.xdg_toplevel)) + !is_realized_toplevel (parent))) { g_warning ("Tried to map a popup with a non-top most parent"); return; } - impl->display_server.xdg_surface = - zxdg_shell_v6_get_xdg_surface (display->xdg_shell, - impl->display_server.wl_surface); - zxdg_surface_v6_add_listener (impl->display_server.xdg_surface, - &xdg_surface_listener, - window); gdk_window_freeze_updates (window); if (impl->position_method == POSITION_METHOD_MOVE_TO_RECT) @@ -2175,21 +2606,56 @@ gdk_wayland_window_create_xdg_popup (GdkWindow *window, else positioner = create_simple_positioner (window, parent); - impl->display_server.xdg_popup = - zxdg_surface_v6_get_popup (impl->display_server.xdg_surface, + switch (display->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + impl->display_server.xdg_surface = + xdg_wm_base_get_xdg_surface (display->xdg_wm_base, + impl->display_server.wl_surface); + xdg_surface_add_listener (impl->display_server.xdg_surface, + &xdg_surface_listener, + window); + impl->display_server.xdg_popup = + xdg_surface_get_popup (impl->display_server.xdg_surface, parent_impl->display_server.xdg_surface, positioner); - zxdg_popup_v6_add_listener (impl->display_server.xdg_popup, + xdg_popup_add_listener (impl->display_server.xdg_popup, &xdg_popup_listener, window); - - zxdg_positioner_v6_destroy (positioner); + xdg_positioner_destroy (positioner); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + impl->display_server.zxdg_surface_v6 = + zxdg_shell_v6_get_xdg_surface (display->zxdg_shell_v6, + impl->display_server.wl_surface); + zxdg_surface_v6_add_listener (impl->display_server.zxdg_surface_v6, + &zxdg_surface_v6_listener, + window); + impl->display_server.zxdg_popup_v6 = + zxdg_surface_v6_get_popup (impl->display_server.zxdg_surface_v6, + parent_impl->display_server.zxdg_surface_v6, + positioner); + zxdg_popup_v6_add_listener (impl->display_server.zxdg_popup_v6, + &zxdg_popup_v6_listener, + window); + zxdg_positioner_v6_destroy (positioner); + break; + } if (seat) { gdk_seat = gdk_display_get_default_seat (GDK_DISPLAY (display)); serial = _gdk_wayland_seat_get_last_implicit_grab_serial (gdk_seat, NULL); - zxdg_popup_v6_grab (impl->display_server.xdg_popup, seat, serial); + + switch (display->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_popup_grab (impl->display_server.xdg_popup, seat, serial); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_popup_v6_grab (impl->display_server.zxdg_popup_v6, seat, serial); + break; + } } wl_surface_commit (impl->display_server.wl_surface); @@ -2332,7 +2798,7 @@ get_popup_parent (GdkWindow *window) { GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); - if (impl->display_server.xdg_popup || impl->display_server.xdg_toplevel) + if (is_realized_popup (window) || is_realized_toplevel (window)) return window; window = impl->transient_for; @@ -2546,19 +3012,19 @@ gdk_wayland_window_hide_surface (GdkWindow *window) if (impl->display_server.xdg_toplevel) { - zxdg_toplevel_v6_destroy (impl->display_server.xdg_toplevel); + xdg_toplevel_destroy (impl->display_server.xdg_toplevel); impl->display_server.xdg_toplevel = NULL; } else if (impl->display_server.xdg_popup) { - zxdg_popup_v6_destroy (impl->display_server.xdg_popup); + xdg_popup_destroy (impl->display_server.xdg_popup); impl->display_server.xdg_popup = NULL; display_wayland->current_popups = g_list_remove (display_wayland->current_popups, window); } if (impl->display_server.xdg_surface) { - zxdg_surface_v6_destroy (impl->display_server.xdg_surface); + xdg_surface_destroy (impl->display_server.xdg_surface); impl->display_server.xdg_surface = NULL; if (!impl->initial_configure_received) gdk_window_thaw_updates (window); @@ -2566,6 +3032,28 @@ gdk_wayland_window_hide_surface (GdkWindow *window) impl->initial_configure_received = FALSE; } + if (impl->display_server.zxdg_toplevel_v6) + { + zxdg_toplevel_v6_destroy (impl->display_server.zxdg_toplevel_v6); + impl->display_server.zxdg_toplevel_v6 = NULL; + } + else if (impl->display_server.zxdg_popup_v6) + { + zxdg_popup_v6_destroy (impl->display_server.zxdg_popup_v6); + impl->display_server.zxdg_popup_v6 = NULL; + display_wayland->current_popups = + g_list_remove (display_wayland->current_popups, window); + } + if (impl->display_server.zxdg_surface_v6) + { + zxdg_surface_v6_destroy (impl->display_server.zxdg_surface_v6); + impl->display_server.zxdg_surface_v6 = NULL; + if (!impl->initial_configure_received) + gdk_window_thaw_updates (window); + else + impl->initial_configure_received = FALSE; + } + if (impl->display_server.wl_subsurface) unmap_subsurface (window); @@ -3075,7 +3563,7 @@ gdk_wayland_window_init_gtk_surface (GdkWindow *window) if (impl->display_server.gtk_surface != NULL) return; - if (impl->display_server.xdg_surface == NULL) + if (!is_realized_toplevel (window)) return; if (display->gtk_shell == NULL) return; @@ -3138,6 +3626,7 @@ gdk_wayland_window_set_geometry_hints (GdkWindow *window, const GdkGeometry *geometry, GdkWindowHints geom_mask) { + GdkWaylandDisplay *display_wayland; GdkWindowImplWayland *impl; int width, height; @@ -3146,11 +3635,12 @@ gdk_wayland_window_set_geometry_hints (GdkWindow *window, return; impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)); impl->geometry_hints = *geometry; impl->geometry_mask = geom_mask; - if (!impl->display_server.xdg_toplevel) + if (!is_realized_toplevel (window)) return; if (geom_mask & GDK_HINT_MIN_SIZE) @@ -3164,8 +3654,6 @@ gdk_wayland_window_set_geometry_hints (GdkWindow *window, height = 0; } - zxdg_toplevel_v6_set_min_size (impl->display_server.xdg_toplevel, width, height); - if (geom_mask & GDK_HINT_MAX_SIZE) { width = MAX (0, geometry->max_width - (impl->margin_left + impl->margin_right)); @@ -3177,7 +3665,21 @@ gdk_wayland_window_set_geometry_hints (GdkWindow *window, height = 0; } - zxdg_toplevel_v6_set_max_size (impl->display_server.xdg_toplevel, width, height); + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_toplevel_set_min_size (impl->display_server.xdg_toplevel, + width, height); + xdg_toplevel_set_max_size (impl->display_server.xdg_toplevel, + width, height); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_toplevel_v6_set_min_size (impl->display_server.zxdg_toplevel_v6, + width, height); + zxdg_toplevel_v6_set_max_size (impl->display_server.zxdg_toplevel_v6, + width, height); + break; + } } static void @@ -3325,15 +3827,25 @@ static void gdk_wayland_window_iconify (GdkWindow *window) { GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + GdkWaylandDisplay *display_wayland; if (GDK_WINDOW_DESTROYED (window) || !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return; - if (!impl->display_server.xdg_toplevel) + if (!is_realized_toplevel (window)) return; - zxdg_toplevel_v6_set_minimized (impl->display_server.xdg_toplevel); + display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)); + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_toplevel_set_minimized (impl->display_server.xdg_toplevel); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_toplevel_v6_set_minimized (impl->display_server.zxdg_toplevel_v6); + break; + } } static void @@ -3369,10 +3881,25 @@ gdk_wayland_window_maximize (GdkWindow *window) return; _gdk_wayland_window_save_size (window); - if (impl->display_server.xdg_toplevel) - zxdg_toplevel_v6_set_maximized (impl->display_server.xdg_toplevel); + if (is_realized_toplevel (window)) + { + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)); + + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_toplevel_set_maximized (impl->display_server.xdg_toplevel); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_toplevel_v6_set_maximized (impl->display_server.zxdg_toplevel_v6); + break; + } + } else - gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_MAXIMIZED); + { + gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_MAXIMIZED); + } } static void @@ -3383,10 +3910,25 @@ gdk_wayland_window_unmaximize (GdkWindow *window) if (GDK_WINDOW_DESTROYED (window)) return; - if (impl->display_server.xdg_toplevel) - zxdg_toplevel_v6_unset_maximized (impl->display_server.xdg_toplevel); + if (is_realized_toplevel (window)) + { + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)); + + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_toplevel_unset_maximized (impl->display_server.xdg_toplevel); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_toplevel_v6_unset_maximized (impl->display_server.zxdg_toplevel_v6); + break; + } + } else - gdk_synthesize_window_state (window, GDK_WINDOW_STATE_MAXIMIZED, 0); + { + gdk_synthesize_window_state (window, GDK_WINDOW_STATE_MAXIMIZED, 0); + } } static void @@ -3401,10 +3943,22 @@ gdk_wayland_window_fullscreen_on_monitor (GdkWindow *window, gint monitor) return; _gdk_wayland_window_save_size (window); - if (impl->display_server.xdg_toplevel) + if (is_realized_toplevel (window)) { - zxdg_toplevel_v6_set_fullscreen (impl->display_server.xdg_toplevel, + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)); + + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_toplevel_set_fullscreen (impl->display_server.xdg_toplevel, fullscreen_output); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_toplevel_v6_set_fullscreen (impl->display_server.zxdg_toplevel_v6, + fullscreen_output); + break; + } } else { @@ -3424,10 +3978,27 @@ gdk_wayland_window_fullscreen (GdkWindow *window) impl->initial_fullscreen_monitor = -1; _gdk_wayland_window_save_size (window); - if (impl->display_server.xdg_toplevel) - zxdg_toplevel_v6_set_fullscreen (impl->display_server.xdg_toplevel, NULL); + if (is_realized_toplevel (window)) + { + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)); + + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_toplevel_set_fullscreen (impl->display_server.xdg_toplevel, + NULL); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_toplevel_v6_set_fullscreen (impl->display_server.zxdg_toplevel_v6, + NULL); + break; + } + } else - gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FULLSCREEN); + { + gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FULLSCREEN); + } } static void @@ -3440,10 +4011,25 @@ gdk_wayland_window_unfullscreen (GdkWindow *window) impl->initial_fullscreen_monitor = -1; - if (impl->display_server.xdg_toplevel) - zxdg_toplevel_v6_unset_fullscreen (impl->display_server.xdg_toplevel); + if (is_realized_toplevel (window)) + { + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)); + + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_toplevel_unset_fullscreen (impl->display_server.xdg_toplevel); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_toplevel_v6_unset_fullscreen (impl->display_server.zxdg_toplevel_v6); + break; + } + } else - gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FULLSCREEN, 0); + { + gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FULLSCREEN, 0); + } } static void @@ -3497,6 +4083,7 @@ gdk_wayland_window_begin_resize_drag (GdkWindow *window, guint32 timestamp) { GdkWindowImplWayland *impl; + GdkWaylandDisplay *display_wayland; GdkEventSequence *sequence; uint32_t resize_edges, serial; @@ -3544,16 +4131,27 @@ gdk_wayland_window_begin_resize_drag (GdkWindow *window, } impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)); - if (!impl->display_server.xdg_toplevel) + if (!is_realized_toplevel (window)) return; serial = _gdk_wayland_seat_get_last_implicit_grab_serial (gdk_device_get_seat (device), &sequence); - zxdg_toplevel_v6_resize (impl->display_server.xdg_toplevel, + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_toplevel_resize (impl->display_server.xdg_toplevel, gdk_wayland_device_get_wl_seat (device), serial, resize_edges); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_toplevel_v6_resize (impl->display_server.zxdg_toplevel_v6, + gdk_wayland_device_get_wl_seat (device), + serial, resize_edges); + break; + } if (sequence) gdk_wayland_device_unset_touch_grab (device, sequence); @@ -3573,6 +4171,7 @@ gdk_wayland_window_begin_move_drag (GdkWindow *window, guint32 timestamp) { GdkWindowImplWayland *impl; + GdkWaylandDisplay *display_wayland; GdkEventSequence *sequence; uint32_t serial; @@ -3581,15 +4180,27 @@ gdk_wayland_window_begin_move_drag (GdkWindow *window, return; impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)); - if (!impl->display_server.xdg_toplevel) + if (!is_realized_toplevel (window)) return; serial = _gdk_wayland_seat_get_last_implicit_grab_serial (gdk_device_get_seat (device), &sequence); - zxdg_toplevel_v6_move (impl->display_server.xdg_toplevel, + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_toplevel_move (impl->display_server.xdg_toplevel, gdk_wayland_device_get_wl_seat (device), serial); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_toplevel_v6_move (impl->display_server.zxdg_toplevel_v6, + gdk_wayland_device_get_wl_seat (device), + serial); + break; + } + if (sequence) gdk_wayland_device_unset_touch_grab (device, sequence); @@ -3742,6 +4353,8 @@ gdk_wayland_window_show_window_menu (GdkWindow *window, GdkEvent *event) { GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)); struct wl_seat *seat; GdkWaylandDevice *device; double x, y; @@ -3758,7 +4371,7 @@ gdk_wayland_window_show_window_menu (GdkWindow *window, return FALSE; } - if (!impl->display_server.xdg_surface) + if (!is_realized_toplevel (window)) return FALSE; device = GDK_WAYLAND_DEVICE (gdk_event_get_device (event)); @@ -3766,8 +4379,19 @@ gdk_wayland_window_show_window_menu (GdkWindow *window, gdk_event_get_coords (event, &x, &y); serial = _gdk_wayland_device_get_implicit_grab_serial (device, event); - zxdg_toplevel_v6_show_window_menu (impl->display_server.xdg_toplevel, + + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_toplevel_show_window_menu (impl->display_server.xdg_toplevel, seat, serial, x, y); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_toplevel_v6_show_window_menu (impl->display_server.zxdg_toplevel_v6, + seat, serial, x, y); + break; + } + return TRUE; } |