diff options
-rw-r--r-- | gdk/wayland/gdkdisplay-wayland.c | 69 | ||||
-rw-r--r-- | gdk/wayland/gdkdisplay-wayland.h | 14 | ||||
-rw-r--r-- | gdk/wayland/gdksurface-wayland.c | 1361 | ||||
-rw-r--r-- | gdk/wayland/meson.build | 12 | ||||
-rw-r--r-- | meson.build | 2 |
5 files changed, 1094 insertions, 364 deletions
diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index 8ba75e6ae9..3fb9fda050 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -126,9 +126,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; @@ -140,8 +159,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 @@ -401,14 +420,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) { @@ -617,11 +635,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 625b5e2f4a..6b62ef8e9a 100644 --- a/gdk/wayland/gdkdisplay-wayland.h +++ b/gdk/wayland/gdkdisplay-wayland.h @@ -30,6 +30,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> @@ -63,6 +64,12 @@ typedef struct { const gchar *hintstyle; } GsdXftSettings; +typedef enum _GdkWaylandShellVariant +{ + GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL, + GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6 +} GdkWaylandShellVariant; + struct _GdkWaylandDisplay { GdkDisplay parent_instance; @@ -79,12 +86,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/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index f774ad13dd..0ffdabee87 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -106,9 +106,16 @@ struct _GdkSurfaceImplWayland 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; @@ -204,9 +211,9 @@ struct _GdkSurfaceImplWaylandClass }; static void gdk_wayland_surface_maybe_configure (GdkSurface *surface, - int width, - int height, - int scale); + int width, + int height, + int scale); static void maybe_set_gtk_surface_dbus_properties (GdkSurface *surface); static void maybe_set_gtk_surface_modal (GdkSurface *surface); @@ -220,14 +227,14 @@ static void gdk_wayland_surface_sync_opaque_region (GdkSurface *surface); static void unset_transient_for_exported (GdkSurface *surface); static void calculate_moved_to_rect_result (GdkSurface *surface, - int x, - int y, - int width, - int height, - GdkRectangle *flipped_rect, - GdkRectangle *final_rect, - gboolean *flipped_x, - gboolean *flipped_y); + int x, + int y, + int width, + int height, + GdkRectangle *flipped_rect, + GdkRectangle *final_rect, + gboolean *flipped_x, + gboolean *flipped_y); static gboolean gdk_wayland_surface_is_exported (GdkSurface *surface); @@ -288,9 +295,9 @@ _gdk_wayland_surface_clear_saved_size (GdkSurface *surface) */ static void gdk_wayland_surface_update_size (GdkSurface *surface, - int32_t width, - int32_t height, - int scale) + int32_t width, + int32_t height, + int scale) { GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); @@ -546,11 +553,11 @@ gdk_wayland_surface_update_scale (GdkSurface *surface) static void gdk_wayland_surface_create_surface (GdkSurface *surface); void -_gdk_wayland_display_create_surface_impl (GdkDisplay *display, - GdkSurface *surface, - GdkSurface *real_parent, - GdkEventMask event_mask, - GdkSurfaceAttr *attributes) +_gdk_wayland_display_create_surface_impl (GdkDisplay *display, + GdkSurface *surface, + GdkSurface *real_parent, + GdkEventMask event_mask, + GdkSurfaceAttr *attributes) { GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display); GdkSurfaceImplWayland *impl; @@ -688,9 +695,9 @@ gdk_surface_impl_wayland_finalize (GObject *object) static void gdk_wayland_surface_configure (GdkSurface *surface, - int width, - int height, - int scale) + int width, + int height, + int scale) { GdkDisplay *display; GdkEvent *event; @@ -708,11 +715,38 @@ gdk_wayland_surface_configure (GdkSurface *surface, _gdk_wayland_display_deliver_event (display, event); } +static gboolean +is_realized_shell_surface (GdkSurface *surface) +{ + GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); + + return (impl->display_server.xdg_surface || + impl->display_server.zxdg_surface_v6); +} + +static gboolean +is_realized_toplevel (GdkSurface *surface) +{ + GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); + + return (impl->display_server.xdg_toplevel || + impl->display_server.zxdg_toplevel_v6); +} + +static gboolean +is_realized_popup (GdkSurface *surface) +{ + GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); + + return (impl->display_server.xdg_popup || + impl->display_server.zxdg_popup_v6); +} + static void gdk_wayland_surface_maybe_configure (GdkSurface *surface, - int width, - int height, - int scale) + int width, + int height, + int scale) { GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); gboolean is_xdg_popup; @@ -729,7 +763,7 @@ gdk_wayland_surface_maybe_configure (GdkSurface *surface, * 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 (surface); is_visible = gdk_surface_is_visible (surface); if (is_xdg_popup && is_visible && !impl->initial_configure_received) @@ -743,16 +777,17 @@ gdk_wayland_surface_maybe_configure (GdkSurface *surface, static void gdk_wayland_surface_sync_parent (GdkSurface *surface, - GdkSurface *parent) + GdkSurface *parent) { GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); GdkSurfaceImplWayland *impl_parent = NULL; - struct zxdg_toplevel_v6 *parent_toplevel; g_assert (parent == NULL || gdk_surface_get_display (surface) == gdk_surface_get_display (parent)); - if (!impl->display_server.xdg_toplevel) + if (!is_realized_toplevel (surface)) return; if (impl->transient_for) @@ -760,19 +795,42 @@ gdk_wayland_surface_sync_parent (GdkSurface *surface, else if (parent) impl_parent = GDK_SURFACE_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; - zxdg_toplevel_v6_set_parent (impl->display_server.xdg_toplevel, - parent_toplevel); + 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; + + 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; + } + default: + g_assert_not_reached (); + } } static void @@ -786,7 +844,7 @@ gdk_wayland_surface_sync_parent_of_imported (GdkSurface *surface) if (!impl->imported_transient_for) return; - if (!impl->display_server.xdg_toplevel) + if (!is_realized_toplevel (surface)) return; zxdg_imported_v1_set_parent_of (impl->imported_transient_for, @@ -828,18 +886,32 @@ static void gdk_wayland_surface_sync_title (GdkSurface *surface) { GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); - if (!impl->display_server.xdg_toplevel) + if (!is_realized_toplevel (surface)) 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; + default: + g_assert_not_reached (); + } } static void -gdk_wayland_surface_get_window_geometry (GdkSurface *surface, +gdk_wayland_surface_get_window_geometry (GdkSurface *surface, GdkRectangle *geometry) { GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); @@ -856,20 +928,37 @@ static void gdk_wayland_surface_sync_margin (GdkSurface *surface) { GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); GdkRectangle geometry; - if (!impl->display_server.xdg_surface) + if (!is_realized_shell_surface (surface)) return; gdk_wayland_surface_get_window_geometry (surface, &geometry); gdk_surface_set_geometry_hints (surface, &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; + default: + g_assert_not_reached (); + } } static struct wl_region * @@ -1071,12 +1160,12 @@ gdk_wayland_surface_create_surface (GdkSurface *surface) } static void -xdg_surface_configure (void *data, - struct zxdg_surface_v6 *xdg_surface, - uint32_t serial) +gdk_wayland_surface_handle_configure (GdkSurface *surface, + uint32_t serial) { - GdkSurface *surface = GDK_SURFACE (data); GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); GdkSurfaceState new_state; int width = impl->pending.width; int height = impl->pending.height; @@ -1091,7 +1180,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; } @@ -1099,7 +1194,9 @@ xdg_surface_configure (void *data, impl->pending.state = 0; fixed_size = - new_state & (GDK_SURFACE_STATE_MAXIMIZED | GDK_SURFACE_STATE_FULLSCREEN | GDK_SURFACE_STATE_TILED); + new_state & (GDK_SURFACE_STATE_MAXIMIZED | + GDK_SURFACE_STATE_FULLSCREEN | + GDK_SURFACE_STATE_TILED); saved_size = (width == 0 && height == 0); /* According to xdg_shell, an xdg_surface.configure with size 0x0 @@ -1149,40 +1246,181 @@ xdg_surface_configure (void *data, (new_state & GDK_SURFACE_STATE_TILED) ? " tiled" : "")); gdk_surface_set_state (surface, 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; + default: + g_assert_not_reached (); + } + if (impl->hint != GDK_SURFACE_TYPE_HINT_DIALOG && new_state & GDK_SURFACE_STATE_FOCUSED) gdk_wayland_surface_update_dialogs (surface); } -static const struct zxdg_surface_v6_listener xdg_surface_listener = { +static void +gdk_wayland_surface_handle_configure_toplevel (GdkSurface *surface, + int32_t width, + int32_t height, + GdkSurfaceState state) +{ + GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); + + impl->pending.state |= state; + impl->pending.width = width; + impl->pending.height = height; +} + +static void +gdk_wayland_surface_handle_close (GdkSurface *surface) +{ + GdkDisplay *display; + GdkEvent *event; + + display = gdk_surface_get_display (surface); + + GDK_DISPLAY_NOTE (display, EVENTS, g_message ("close %p", surface)); + + event = gdk_event_new (GDK_DELETE); + event->any.surface = g_object_ref (surface); + event->any.send_event = TRUE; + + _gdk_wayland_display_deliver_event (display, event); +} + +static void +xdg_surface_configure (void *data, + struct xdg_surface *xdg_surface, + uint32_t serial) +{ + GdkSurface *surface = GDK_SURFACE (data); + + gdk_wayland_surface_handle_configure (surface, 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) { GdkSurface *surface = GDK_SURFACE (data); + uint32_t *p; + GdkSurfaceState pending_state = 0; + + wl_array_for_each (p, states) + { + uint32_t state = *p; + + switch (state) + { + case XDG_TOPLEVEL_STATE_FULLSCREEN: + pending_state |= GDK_SURFACE_STATE_FULLSCREEN; + break; + case XDG_TOPLEVEL_STATE_MAXIMIZED: + pending_state |= GDK_SURFACE_STATE_MAXIMIZED; + break; + case XDG_TOPLEVEL_STATE_ACTIVATED: + pending_state |= GDK_SURFACE_STATE_FOCUSED; + break; + case XDG_TOPLEVEL_STATE_RESIZING: + break; + default: + /* Unknown state */ + break; + } + } + + gdk_wayland_surface_handle_configure_toplevel (surface, width, height, + pending_state); +} + +static void +xdg_toplevel_close (void *data, + struct xdg_toplevel *xdg_toplevel) +{ + GdkSurface *surface = GDK_SURFACE (data); + + gdk_wayland_surface_handle_close (surface); +} + +static const struct xdg_toplevel_listener xdg_toplevel_listener = { + xdg_toplevel_configure, + xdg_toplevel_close, +}; + +static void +create_xdg_toplevel_resources (GdkSurface *surface) +{ + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->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, + surface); + + 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, + surface); +} + +static void +zxdg_surface_v6_configure (void *data, + struct zxdg_surface_v6 *xdg_surface, + uint32_t serial) +{ + GdkSurface *surface = GDK_SURFACE (data); + + gdk_wayland_surface_handle_configure (surface, 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) +{ + GdkSurface *surface = GDK_SURFACE (data); uint32_t *p; + GdkSurfaceState 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_SURFACE_STATE_FULLSCREEN; + pending_state |= GDK_SURFACE_STATE_FULLSCREEN; break; case ZXDG_TOPLEVEL_V6_STATE_MAXIMIZED: - impl->pending.state |= GDK_SURFACE_STATE_MAXIMIZED; + pending_state |= GDK_SURFACE_STATE_MAXIMIZED; break; case ZXDG_TOPLEVEL_V6_STATE_ACTIVATED: - impl->pending.state |= GDK_SURFACE_STATE_FOCUSED; + pending_state |= GDK_SURFACE_STATE_FOCUSED; break; case ZXDG_TOPLEVEL_V6_STATE_RESIZING: break; @@ -1192,33 +1430,44 @@ xdg_toplevel_configure (void *data, } } - impl->pending.width = width; - impl->pending.height = height; + gdk_wayland_surface_handle_configure_toplevel (surface, 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) { GdkSurface *surface = GDK_SURFACE (data); - GdkDisplay *display; - GdkEvent *event; - display = gdk_surface_get_display (surface); + gdk_wayland_surface_handle_close (surface); +} - GDK_DISPLAY_NOTE (display, EVENTS, g_message ("close %p", surface)); +static const struct zxdg_toplevel_v6_listener zxdg_toplevel_v6_listener = { + zxdg_toplevel_v6_configure, + zxdg_toplevel_v6_close, +}; - event = gdk_event_new (GDK_DELETE); - event->any.surface = g_object_ref (surface); - event->any.send_event = TRUE; +static void +create_zxdg_toplevel_v6_resources (GdkSurface *surface) +{ + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); + GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); - _gdk_wayland_display_deliver_event (display, event); -} + 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, + surface); -static const struct zxdg_toplevel_v6_listener xdg_toplevel_listener = { - xdg_toplevel_configure, - xdg_toplevel_close, -}; + 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, + surface); +} static void gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface) @@ -1227,29 +1476,43 @@ gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface) GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); const gchar *app_id; - 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, - surface); gdk_surface_freeze_updates (surface); - 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, - surface); + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + create_xdg_toplevel_resources (surface); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + create_zxdg_toplevel_v6_resources (surface); + break; + default: + g_assert_not_reached (); + } gdk_wayland_surface_sync_parent (surface, NULL); gdk_wayland_surface_sync_parent_of_imported (surface); gdk_wayland_surface_sync_title (surface); - if (surface->state & GDK_SURFACE_STATE_MAXIMIZED) - zxdg_toplevel_v6_set_maximized (impl->display_server.xdg_toplevel); - if (surface->state & GDK_SURFACE_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 (surface->state & GDK_SURFACE_STATE_MAXIMIZED) + xdg_toplevel_set_maximized (impl->display_server.xdg_toplevel); + if (surface->state & GDK_SURFACE_STATE_FULLSCREEN) + xdg_toplevel_set_fullscreen (impl->display_server.xdg_toplevel, impl->initial_fullscreen_output); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + if (surface->state & GDK_SURFACE_STATE_MAXIMIZED) + zxdg_toplevel_v6_set_maximized (impl->display_server.zxdg_toplevel_v6); + if (surface->state & GDK_SURFACE_STATE_FULLSCREEN) + zxdg_toplevel_v6_set_fullscreen (impl->display_server.zxdg_toplevel_v6, + impl->initial_fullscreen_output); + break; + default: + g_assert_not_reached (); + } impl->initial_fullscreen_output = NULL; @@ -1258,7 +1521,19 @@ gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface) if (app_id == NULL) app_id = "GTK+ Application"; - 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; + default: + g_assert_not_reached (); + } maybe_set_gtk_surface_dbus_properties (surface); maybe_set_gtk_surface_modal (surface); @@ -1270,14 +1545,12 @@ gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface) } 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_surface_handle_configure_popup (GdkSurface *surface, + int32_t x, + int32_t y, + int32_t width, + int32_t height) { - GdkSurface *surface = GDK_SURFACE (data); GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); GdkRectangle flipped_rect; GdkRectangle final_rect; @@ -1304,8 +1577,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) +{ + GdkSurface *surface = GDK_SURFACE (data); + + gdk_wayland_surface_handle_configure_popup (surface, x, y, width, height); +} + +static void +xdg_popup_done (void *data, + struct xdg_popup *xdg_popup) { GdkSurface *surface = GDK_SURFACE (data); @@ -1314,18 +1600,106 @@ xdg_popup_done (void *data, gdk_surface_hide (surface); } -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) +{ + GdkSurface *surface = GDK_SURFACE (data); + + gdk_wayland_surface_handle_configure_popup (surface, x, y, width, height); +} + +static void +zxdg_popup_v6_done (void *data, + struct zxdg_popup_v6 *xdg_popup) +{ + GdkSurface *surface = GDK_SURFACE (data); + + GDK_NOTE (EVENTS, + g_message ("done %p", surface)); + + gdk_surface_hide (surface); +} + +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 +surface_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: @@ -1356,7 +1730,7 @@ rect_anchor_to_anchor (GdkGravity rect_anchor) } static enum zxdg_positioner_v6_gravity -surface_anchor_to_gravity (GdkGravity rect_anchor) +surface_anchor_to_gravity_legacy (GdkGravity rect_anchor) { switch (rect_anchor) { @@ -1408,8 +1782,8 @@ gdk_wayland_surface_announce_csd (GdkSurface *surface) static GdkSurface * get_real_parent_and_translate (GdkSurface *surface, - gint *x, - gint *y) + gint *x, + gint *y) { GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); GdkSurface *parent = impl->transient_for; @@ -1440,8 +1814,8 @@ get_real_parent_and_translate (GdkSurface *surface, static void translate_to_real_parent_surface_geometry (GdkSurface *surface, - gint *x, - gint *y) + gint *x, + gint *y) { GdkSurface *parent; @@ -1453,8 +1827,8 @@ translate_to_real_parent_surface_geometry (GdkSurface *surface, static GdkSurface * translate_from_real_parent_surface_geometry (GdkSurface *surface, - gint *x, - gint *y) + gint *x, + gint *y) { GdkSurface *parent; gint dx = 0; @@ -1469,7 +1843,7 @@ translate_from_real_parent_surface_geometry (GdkSurface *surface, } static void -calculate_popup_rect (GdkSurface *surface, +calculate_popup_rect (GdkSurface *surface, GdkGravity rect_anchor, GdkGravity surface_anchor, GdkRectangle *out_rect) @@ -1637,7 +2011,7 @@ flip_anchor_vertically (GdkGravity anchor) } static void -calculate_moved_to_rect_result (GdkSurface *surface, +calculate_moved_to_rect_result (GdkSurface *surface, int x, int y, int width, @@ -1720,24 +2094,18 @@ calculate_moved_to_rect_result (GdkSurface *surface, *flipped_y = flipped_rect->y != best_rect.y; } -static struct zxdg_positioner_v6 * +static gpointer create_dynamic_positioner (GdkSurface *surface) { GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); - 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_surface_get_window_geometry (surface, &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; @@ -1747,56 +2115,109 @@ create_dynamic_positioner (GdkSurface *surface) 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 = surface_anchor_to_gravity (impl->pending_move_to_rect.surface_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 = surface_anchor_to_gravity (impl->pending_move_to_rect.surface_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 = surface_anchor_to_gravity_legacy (impl->pending_move_to_rect.surface_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; + } + default: + g_assert_not_reached (); + } + + g_assert_not_reached (); +} + +static gpointer create_simple_positioner (GdkSurface *surface, GdkSurface *parent) { GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); - 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_surface_get_window_geometry (surface, &geometry); - zxdg_positioner_v6_set_size (positioner, geometry.width, geometry.height); parent_x = parent->x; parent_y = parent->y; @@ -1805,44 +2226,75 @@ create_simple_positioner (GdkSurface *surface, parent_x += parent_geometry.x; parent_y += parent_geometry.y; - zxdg_positioner_v6_set_anchor_rect (positioner, - (surface->x + geometry.x) - parent_x, - (surface->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, + (surface->x + geometry.x) - parent_x, + (surface->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, + (surface->x + geometry.x) - parent_x, + (surface->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; + } + default: + g_assert_not_reached (); + } - return positioner; + g_assert_not_reached (); } static void -gdk_wayland_surface_create_xdg_popup (GdkSurface *surface, - GdkSurface *parent, - struct wl_seat *seat) +gdk_wayland_surface_create_xdg_popup (GdkSurface *surface, + GdkSurface *parent, + struct wl_seat *seat) { GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); GdkSurfaceImplWayland *parent_impl = GDK_SURFACE_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 (surface)) { g_warning ("Can't map popup, already mapped as toplevel"); return; } - if (impl->display_server.xdg_popup) + if (is_realized_popup (surface)) { g_warning ("Can't map popup, already mapped"); return; @@ -1850,18 +2302,12 @@ gdk_wayland_surface_create_xdg_popup (GdkSurface *surface, 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, - surface); gdk_surface_freeze_updates (surface); if (impl->position_method == POSITION_METHOD_MOVE_TO_RECT) @@ -1869,21 +2315,60 @@ gdk_wayland_surface_create_xdg_popup (GdkSurface *surface, else positioner = create_simple_positioner (surface, 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, + surface); + 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, surface); - - 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, + surface); + 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, + surface); + zxdg_positioner_v6_destroy (positioner); + break; + default: + g_assert_not_reached (); + } 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; + default: + g_assert_not_reached (); + } } wl_surface_commit (impl->display_server.wl_surface); @@ -1893,7 +2378,8 @@ gdk_wayland_surface_create_xdg_popup (GdkSurface *surface, } static struct wl_seat * -find_grab_input_seat (GdkSurface *surface, GdkSurface *transient_for) +find_grab_input_seat (GdkSurface *surface, + GdkSurface *transient_for) { GdkSurface *attached_grab_surface; GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); @@ -2026,7 +2512,7 @@ get_popup_parent (GdkSurface *surface) { GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); - if (impl->display_server.xdg_popup || impl->display_server.xdg_toplevel) + if (is_realized_popup (surface) || is_realized_toplevel (surface)) return surface; surface = impl->transient_for; @@ -2146,7 +2632,7 @@ gdk_wayland_surface_map (GdkSurface *surface) static void gdk_wayland_surface_show (GdkSurface *surface, - gboolean already_mapped) + gboolean already_mapped) { GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); @@ -2236,19 +2722,19 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface) 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, surface); } 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_surface_thaw_updates (surface); @@ -2256,6 +2742,28 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface) 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, surface); + } + 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_surface_thaw_updates (surface); + else + impl->initial_configure_received = FALSE; + } + if (impl->display_server.wl_subsurface) unmap_subsurface (surface); @@ -2316,8 +2824,8 @@ gdk_surface_wayland_withdraw (GdkSurface *surface) } static void -gdk_surface_wayland_set_events (GdkSurface *surface, - GdkEventMask event_mask) +gdk_surface_wayland_set_events (GdkSurface *surface, + GdkEventMask event_mask) { GDK_SURFACE (surface)->event_mask = event_mask; } @@ -2343,8 +2851,8 @@ gdk_surface_wayland_lower (GdkSurface *surface) static void gdk_surface_wayland_restack_toplevel (GdkSurface *surface, - GdkSurface *sibling, - gboolean above) + GdkSurface *sibling, + gboolean above) { } @@ -2376,11 +2884,11 @@ gdk_surface_request_transient_parent_commit (GdkSurface *surface) static void gdk_surface_wayland_move_resize (GdkSurface *surface, - gboolean with_move, - gint x, - gint y, - gint width, - gint height) + gboolean with_move, + gint x, + gint y, + gint width, + gint height) { GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); @@ -2412,7 +2920,7 @@ gdk_surface_wayland_move_resize (GdkSurface *surface, /* Avoid zero width/height as this is a protocol error */ static void -sanitize_anchor_rect (GdkSurface *surface, +sanitize_anchor_rect (GdkSurface *surface, GdkRectangle *rect) { gint original_width = rect->width; @@ -2425,13 +2933,13 @@ sanitize_anchor_rect (GdkSurface *surface, } static void -gdk_surface_wayland_move_to_rect (GdkSurface *surface, - const GdkRectangle *rect, - GdkGravity rect_anchor, - GdkGravity surface_anchor, - GdkAnchorHints anchor_hints, - gint rect_anchor_dx, - gint rect_anchor_dy) +gdk_surface_wayland_move_to_rect (GdkSurface *surface, + const GdkRectangle *rect, + GdkGravity rect_anchor, + GdkGravity surface_anchor, + GdkAnchorHints anchor_hints, + gint rect_anchor_dx, + gint rect_anchor_dy) { GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); @@ -2449,10 +2957,10 @@ gdk_surface_wayland_move_to_rect (GdkSurface *surface, static void gdk_surface_wayland_get_geometry (GdkSurface *surface, - gint *x, - gint *y, - gint *width, - gint *height) + gint *x, + gint *y, + gint *width, + gint *height) { if (!GDK_SURFACE_DESTROYED (surface)) { @@ -2469,10 +2977,10 @@ gdk_surface_wayland_get_geometry (GdkSurface *surface, static void gdk_surface_wayland_get_root_coords (GdkSurface *surface, - gint x, - gint y, - gint *root_x, - gint *root_y) + gint x, + gint y, + gint *root_x, + gint *root_y) { /* * Wayland does not have a global coordinate space shared between surfaces. In @@ -2505,10 +3013,10 @@ gdk_surface_wayland_get_root_coords (GdkSurface *surface, static gboolean gdk_surface_wayland_get_device_state (GdkSurface *surface, - GdkDevice *device, - gdouble *x, - gdouble *y, - GdkModifierType *mask) + GdkDevice *device, + gdouble *x, + gdouble *y, + GdkModifierType *mask) { gboolean return_val; @@ -2531,10 +3039,10 @@ gdk_surface_wayland_get_device_state (GdkSurface *surface, } static void -gdk_surface_wayland_input_shape_combine_region (GdkSurface *surface, - const cairo_region_t *shape_region, - gint offset_x, - gint offset_y) +gdk_surface_wayland_input_shape_combine_region (GdkSurface *surface, + const cairo_region_t *shape_region, + gint offset_x, + gint offset_y) { GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); @@ -2554,8 +3062,8 @@ gdk_surface_wayland_input_shape_combine_region (GdkSurface *surface, static void gdk_wayland_surface_destroy (GdkSurface *surface, - gboolean recursing, - gboolean foreign_destroy) + gboolean recursing, + gboolean foreign_destroy) { g_return_if_fail (GDK_IS_SURFACE (surface)); @@ -2575,7 +3083,7 @@ gdk_wayland_surface_destroy (GdkSurface *surface, static void gdk_wayland_surface_focus (GdkSurface *surface, - guint32 timestamp) + guint32 timestamp) { GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); @@ -2594,7 +3102,7 @@ gdk_wayland_surface_focus (GdkSurface *surface, static void gdk_wayland_surface_set_type_hint (GdkSurface *surface, - GdkSurfaceTypeHint hint) + GdkSurfaceTypeHint hint) { GdkSurfaceImplWayland *impl; @@ -2712,7 +3220,7 @@ gdk_wayland_surface_init_gtk_surface (GdkSurface *surface) if (impl->display_server.gtk_surface != NULL) return; - if (impl->display_server.xdg_surface == NULL) + if (!is_realized_toplevel (surface)) return; if (display->gtk_shell == NULL) return; @@ -2746,7 +3254,7 @@ maybe_set_gtk_surface_modal (GdkSurface *surface) static void gdk_wayland_surface_set_modal_hint (GdkSurface *surface, - gboolean modal) + gboolean modal) { surface->modal_hint = modal; maybe_set_gtk_surface_modal (surface); @@ -2754,72 +3262,93 @@ gdk_wayland_surface_set_modal_hint (GdkSurface *surface, static void gdk_wayland_surface_set_skip_taskbar_hint (GdkSurface *surface, - gboolean skips_taskbar) + gboolean skips_taskbar) { } static void gdk_wayland_surface_set_skip_pager_hint (GdkSurface *surface, - gboolean skips_pager) + gboolean skips_pager) { } static void gdk_wayland_surface_set_urgency_hint (GdkSurface *surface, - gboolean urgent) + gboolean urgent) { } static void gdk_wayland_surface_set_geometry_hints (GdkSurface *surface, - const GdkGeometry *geometry, - GdkSurfaceHints geom_mask) + const GdkGeometry *geometry, + GdkSurfaceHints geom_mask) { + GdkWaylandDisplay *display_wayland; GdkSurfaceImplWayland *impl; - int width, height; + int min_width, min_height; + int max_width, max_height; if (GDK_SURFACE_DESTROYED (surface) || !SURFACE_IS_TOPLEVEL (surface)) return; impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); + display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); impl->geometry_hints = *geometry; impl->geometry_mask = geom_mask; - if (!impl->display_server.xdg_toplevel) + if (!is_realized_toplevel (surface)) return; if (geom_mask & GDK_HINT_MIN_SIZE) { - width = MAX (0, geometry->min_width - (impl->margin_left + impl->margin_right)); - height = MAX (0, geometry->min_height - (impl->margin_top + impl->margin_bottom)); + min_width = MAX (0, (geometry->min_width - + (impl->margin_left + impl->margin_right))); + min_height = MAX (0, (geometry->min_height - + (impl->margin_top + impl->margin_bottom))); } else { - width = 0; - height = 0; + min_width = 0; + min_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)); - height = MAX (0, geometry->max_height - (impl->margin_top + impl->margin_bottom)); + max_width = MAX (0, (geometry->max_width - + (impl->margin_left + impl->margin_right))); + max_height = MAX (0, (geometry->max_height - + (impl->margin_top + impl->margin_bottom))); } else { - width = 0; - height = 0; + max_width = 0; + max_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, + min_width, min_height); + xdg_toplevel_set_max_size (impl->display_server.xdg_toplevel, + max_width, max_height); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_toplevel_v6_set_min_size (impl->display_server.zxdg_toplevel_v6, + min_width, min_height); + zxdg_toplevel_v6_set_max_size (impl->display_server.zxdg_toplevel_v6, + max_width, max_height); + break; + default: + g_assert_not_reached (); + } } static void -gdk_wayland_surface_set_title (GdkSurface *surface, - const gchar *title) +gdk_wayland_surface_set_title (GdkSurface *surface, + const gchar *title) { GdkSurfaceImplWayland *impl; const char *end; @@ -2854,14 +3383,14 @@ gdk_wayland_surface_set_title (GdkSurface *surface, } static void -gdk_wayland_surface_set_role (GdkSurface *surface, - const gchar *role) +gdk_wayland_surface_set_role (GdkSurface *surface, + const gchar *role) { } static void -gdk_wayland_surface_set_startup_id (GdkSurface *surface, - const gchar *startup_id) +gdk_wayland_surface_set_startup_id (GdkSurface *surface, + const gchar *startup_id) { } @@ -2886,7 +3415,7 @@ check_transient_for_loop (GdkSurface *surface, static void gdk_wayland_surface_set_transient_for (GdkSurface *surface, - GdkSurface *parent) + GdkSurface *parent) { GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); GdkWaylandDisplay *display_wayland = @@ -2925,8 +3454,8 @@ gdk_wayland_surface_set_transient_for (GdkSurface *surface, } static void -gdk_wayland_surface_get_frame_extents (GdkSurface *surface, - GdkRectangle *rect) +gdk_wayland_surface_get_frame_extents (GdkSurface *surface, + GdkRectangle *rect) { *rect = (GdkRectangle) { .x = surface->x, @@ -2938,25 +3467,25 @@ gdk_wayland_surface_get_frame_extents (GdkSurface *surface, static void gdk_wayland_surface_set_accept_focus (GdkSurface *surface, - gboolean accept_focus) + gboolean accept_focus) { } static void gdk_wayland_surface_set_focus_on_map (GdkSurface *surface, - gboolean focus_on_map) + gboolean focus_on_map) { } static void gdk_wayland_surface_set_icon_list (GdkSurface *surface, - GList *surfaces) + GList *surfaces) { } static void -gdk_wayland_surface_set_icon_name (GdkSurface *surface, - const gchar *name) +gdk_wayland_surface_set_icon_name (GdkSurface *surface, + const gchar *name) { if (GDK_SURFACE_DESTROYED (surface)) return; @@ -2966,15 +3495,27 @@ static void gdk_wayland_surface_iconify (GdkSurface *surface) { GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); + GdkWaylandDisplay *display_wayland; if (GDK_SURFACE_DESTROYED (surface) || !SURFACE_IS_TOPLEVEL (surface)) return; - if (!impl->display_server.xdg_toplevel) + if (!is_realized_toplevel (surface)) return; - zxdg_toplevel_v6_set_minimized (impl->display_server.xdg_toplevel); + display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); + 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; + default: + g_assert_not_reached (); + } } static void @@ -3010,10 +3551,28 @@ gdk_wayland_surface_maximize (GdkSurface *surface) return; _gdk_wayland_surface_save_size (surface); - if (impl->display_server.xdg_toplevel) - zxdg_toplevel_v6_set_maximized (impl->display_server.xdg_toplevel); + + if (is_realized_toplevel (surface)) + { + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); + + 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; + default: + g_assert_not_reached (); + } + } else - gdk_synthesize_surface_state (surface, 0, GDK_SURFACE_STATE_MAXIMIZED); + { + gdk_synthesize_surface_state (surface, 0, GDK_SURFACE_STATE_MAXIMIZED); + } } static void @@ -3024,15 +3583,32 @@ gdk_wayland_surface_unmaximize (GdkSurface *surface) if (GDK_SURFACE_DESTROYED (surface)) return; - if (impl->display_server.xdg_toplevel) - zxdg_toplevel_v6_unset_maximized (impl->display_server.xdg_toplevel); + if (is_realized_toplevel (surface)) + { + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); + + 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; + default: + g_assert_not_reached (); + } + } else - gdk_synthesize_surface_state (surface, GDK_SURFACE_STATE_MAXIMIZED, 0); + { + gdk_synthesize_surface_state (surface, GDK_SURFACE_STATE_MAXIMIZED, 0); + } } static void -gdk_wayland_surface_fullscreen_on_monitor (GdkSurface *surface, - GdkMonitor *monitor) +gdk_wayland_surface_fullscreen_on_monitor (GdkSurface *surface, + GdkMonitor *monitor) { GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); struct wl_output *output = ((GdkWaylandMonitor *)monitor)->output; @@ -3041,9 +3617,25 @@ gdk_wayland_surface_fullscreen_on_monitor (GdkSurface *surface, return; _gdk_wayland_surface_save_size (surface); - if (impl->display_server.xdg_toplevel) + + if (is_realized_toplevel (surface)) { - zxdg_toplevel_v6_set_fullscreen (impl->display_server.xdg_toplevel, output); + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); + + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_toplevel_set_fullscreen (impl->display_server.xdg_toplevel, + output); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_toplevel_v6_set_fullscreen (impl->display_server.zxdg_toplevel_v6, + output); + break; + default: + g_assert_not_reached (); + } } else { @@ -3063,10 +3655,30 @@ gdk_wayland_surface_fullscreen (GdkSurface *surface) impl->initial_fullscreen_output = NULL; _gdk_wayland_surface_save_size (surface); - if (impl->display_server.xdg_toplevel) - zxdg_toplevel_v6_set_fullscreen (impl->display_server.xdg_toplevel, NULL); + + if (is_realized_toplevel (surface)) + { + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); + + 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; + default: + g_assert_not_reached (); + } + } else - gdk_synthesize_surface_state (surface, 0, GDK_SURFACE_STATE_FULLSCREEN); + { + gdk_synthesize_surface_state (surface, 0, GDK_SURFACE_STATE_FULLSCREEN); + } } static void @@ -3079,19 +3691,38 @@ gdk_wayland_surface_unfullscreen (GdkSurface *surface) impl->initial_fullscreen_output = NULL; - if (impl->display_server.xdg_toplevel) - zxdg_toplevel_v6_unset_fullscreen (impl->display_server.xdg_toplevel); + if (is_realized_toplevel (surface)) + { + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); + + 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; + default: + g_assert_not_reached (); + } + } else - gdk_synthesize_surface_state (surface, GDK_SURFACE_STATE_FULLSCREEN, 0); + { + gdk_synthesize_surface_state (surface, GDK_SURFACE_STATE_FULLSCREEN, 0); + } } static void -gdk_wayland_surface_set_keep_above (GdkSurface *surface, gboolean setting) +gdk_wayland_surface_set_keep_above (GdkSurface *surface, + gboolean setting) { } static void -gdk_wayland_surface_set_keep_below (GdkSurface *surface, gboolean setting) +gdk_wayland_surface_set_keep_below (GdkSurface *surface, + gboolean setting) { } @@ -3103,39 +3734,40 @@ gdk_wayland_surface_get_group (GdkSurface *surface) static void gdk_wayland_surface_set_group (GdkSurface *surface, - GdkSurface *leader) + GdkSurface *leader) { } static void -gdk_wayland_surface_set_decorations (GdkSurface *surface, - GdkWMDecoration decorations) +gdk_wayland_surface_set_decorations (GdkSurface *surface, + GdkWMDecoration decorations) { } static gboolean -gdk_wayland_surface_get_decorations (GdkSurface *surface, - GdkWMDecoration *decorations) +gdk_wayland_surface_get_decorations (GdkSurface *surface, + GdkWMDecoration *decorations) { return FALSE; } static void -gdk_wayland_surface_set_functions (GdkSurface *surface, - GdkWMFunction functions) +gdk_wayland_surface_set_functions (GdkSurface *surface, + GdkWMFunction functions) { } static void gdk_wayland_surface_begin_resize_drag (GdkSurface *surface, - GdkSurfaceEdge edge, - GdkDevice *device, - gint button, - gint root_x, - gint root_y, - guint32 timestamp) + GdkSurfaceEdge edge, + GdkDevice *device, + gint button, + gint root_x, + gint root_y, + guint32 timestamp) { GdkSurfaceImplWayland *impl; + GdkWaylandDisplay *display_wayland; GdkEventSequence *sequence; uint32_t resize_edges, serial; @@ -3183,16 +3815,29 @@ gdk_wayland_surface_begin_resize_drag (GdkSurface *surface, } impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); + display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); - if (!impl->display_server.xdg_toplevel) + if (!is_realized_toplevel (surface)) 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; + default: + g_assert_not_reached (); + } if (sequence) gdk_wayland_device_unset_touch_grab (device, sequence); @@ -3205,13 +3850,14 @@ gdk_wayland_surface_begin_resize_drag (GdkSurface *surface, static void gdk_wayland_surface_begin_move_drag (GdkSurface *surface, - GdkDevice *device, - gint button, - gint root_x, - gint root_y, - guint32 timestamp) + GdkDevice *device, + gint button, + gint root_x, + gint root_y, + guint32 timestamp) { GdkSurfaceImplWayland *impl; + GdkWaylandDisplay *display_wayland; GdkEventSequence *sequence; uint32_t serial; @@ -3220,15 +3866,29 @@ gdk_wayland_surface_begin_move_drag (GdkSurface *surface, return; impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); + display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); - if (!impl->display_server.xdg_toplevel) + if (!is_realized_toplevel (surface)) 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; + default: + g_assert_not_reached (); + } + if (sequence) gdk_wayland_device_unset_touch_grab (device, sequence); @@ -3240,7 +3900,7 @@ gdk_wayland_surface_begin_move_drag (GdkSurface *surface, static void gdk_wayland_surface_set_opacity (GdkSurface *surface, - gdouble opacity) + gdouble opacity) { } @@ -3268,8 +3928,8 @@ gdk_wayland_surface_get_scale_factor (GdkSurface *surface) } static void -gdk_wayland_surface_set_opaque_region (GdkSurface *surface, - cairo_region_t *region) +gdk_wayland_surface_set_opaque_region (GdkSurface *surface, + cairo_region_t *region) { GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); @@ -3283,10 +3943,10 @@ gdk_wayland_surface_set_opaque_region (GdkSurface *surface, static void gdk_wayland_surface_set_shadow_width (GdkSurface *surface, - int left, - int right, - int top, - int bottom) + int left, + int right, + int top, + int bottom) { GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); gint new_width, new_height; @@ -3309,9 +3969,11 @@ gdk_wayland_surface_set_shadow_width (GdkSurface *surface, static gboolean gdk_wayland_surface_show_window_menu (GdkSurface *surface, - GdkEvent *event) + GdkEvent *event) { GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); struct wl_seat *seat; GdkWaylandDevice *device; double x, y; @@ -3328,7 +3990,7 @@ gdk_wayland_surface_show_window_menu (GdkSurface *surface, return FALSE; } - if (!impl->display_server.xdg_surface) + if (!is_realized_toplevel (surface)) return FALSE; device = GDK_WAYLAND_DEVICE (gdk_event_get_device (event)); @@ -3336,8 +3998,21 @@ gdk_wayland_surface_show_window_menu (GdkSurface *surface, 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; + default: + g_assert_not_reached (); + } + return TRUE; } @@ -3434,7 +4109,7 @@ _gdk_surface_impl_wayland_class_init (GdkSurfaceImplWaylandClass *klass) void _gdk_wayland_surface_set_grab_seat (GdkSurface *surface, - GdkSeat *seat) + GdkSeat *seat) { GdkSurfaceImplWayland *impl; @@ -3455,7 +4130,7 @@ _gdk_wayland_surface_set_grab_seat (GdkSurface *surface, **/ GdkSurface * gdk_wayland_surface_new_subsurface (GdkDisplay *display, - const GdkRectangle *position) + const GdkRectangle *position) { GdkSurfaceAttr attr; @@ -3522,7 +4197,7 @@ gdk_wayland_surface_get_wl_egl_window (GdkSurface *surface) EGLSurface gdk_wayland_surface_get_egl_surface (GdkSurface *surface, - EGLConfig config) + EGLConfig config) { GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); GdkSurfaceImplWayland *impl; @@ -3545,7 +4220,7 @@ gdk_wayland_surface_get_egl_surface (GdkSurface *surface, EGLSurface gdk_wayland_surface_get_dummy_egl_surface (GdkSurface *surface, - EGLConfig config) + EGLConfig config) { GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); GdkSurfaceImplWayland *impl; @@ -3662,13 +4337,13 @@ maybe_set_gtk_surface_dbus_properties (GdkSurface *surface) } void -gdk_wayland_surface_set_dbus_properties_libgtk_only (GdkSurface *surface, - const char *application_id, - const char *app_menu_path, - const char *menubar_path, - const char *window_object_path, - const char *application_object_path, - const char *unique_bus_name) +gdk_wayland_surface_set_dbus_properties_libgtk_only (GdkSurface *surface, + const char *application_id, + const char *app_menu_path, + const char *menubar_path, + const char *window_object_path, + const char *application_object_path, + const char *unique_bus_name) { GdkSurfaceImplWayland *impl; @@ -3689,8 +4364,8 @@ gdk_wayland_surface_set_dbus_properties_libgtk_only (GdkSurface *surface, void _gdk_wayland_surface_offset_next_wl_buffer (GdkSurface *surface, - int x, - int y) + int x, + int y) { GdkSurfaceImplWayland *impl; @@ -3768,9 +4443,9 @@ gdk_wayland_surface_is_exported (GdkSurface *surface) */ gboolean gdk_wayland_surface_export_handle (GdkSurface *surface, - GdkWaylandSurfaceExported callback, - gpointer user_data, - GDestroyNotify destroy_func) + GdkWaylandSurfaceExported callback, + gpointer user_data, + GDestroyNotify destroy_func) { GdkSurfaceImplWayland *impl; GdkWaylandDisplay *display_wayland; @@ -3871,7 +4546,7 @@ static const struct zxdg_imported_v1_listener xdg_imported_listener = { */ gboolean gdk_wayland_surface_set_transient_for_exported (GdkSurface *surface, - char *parent_handle_str) + char *parent_handle_str) { GdkSurfaceImplWayland *impl; GdkWaylandDisplay *display_wayland; @@ -3913,7 +4588,7 @@ gdk_wayland_surface_get_inhibitor (GdkSurfaceImplWayland *impl, void gdk_wayland_surface_inhibit_shortcuts (GdkSurface *surface, - GdkSeat *gdk_seat) + GdkSeat *gdk_seat) { GdkSurfaceImplWayland *impl= GDK_SURFACE_IMPL_WAYLAND (surface->impl); GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); @@ -3936,7 +4611,7 @@ gdk_wayland_surface_inhibit_shortcuts (GdkSurface *surface, void gdk_wayland_surface_restore_shortcuts (GdkSurface *surface, - GdkSeat *gdk_seat) + GdkSeat *gdk_seat) { GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); struct wl_seat *seat = gdk_wayland_seat_get_wl_seat (gdk_seat); diff --git a/gdk/wayland/meson.build b/gdk/wayland/meson.build index e6e66158bb..fc6bbdfd82 100644 --- a/gdk/wayland/meson.build +++ b/gdk/wayland/meson.build @@ -45,17 +45,18 @@ wayland_scanner = find_program('wayland-scanner') # Format: # - protocol name -# - protocol stability ('stable' or 'unstable') +# - protocol stability ('private', 'stable' or 'unstable') # - protocol version (if stability is 'unstable') proto_sources = [ - ['gtk-shell', 'stable', ], - ['gtk-primary-selection', 'stable', ], + ['gtk-shell', 'private', ], + ['gtk-primary-selection', 'private', ], ['pointer-gestures', 'unstable', 'v1', ], ['xdg-shell', 'unstable', 'v6', ], + ['xdg-shell', 'stable', ], ['xdg-foreign', 'unstable', 'v1', ], ['tablet', 'unstable', 'v2', ], ['keyboard-shortcuts-inhibit', 'unstable', 'v1', ], - ['server-decoration', 'stable' ], + ['server-decoration', 'private' ], ] gdk_wayland_gen_headers = [] @@ -66,6 +67,9 @@ foreach p: proto_sources if proto_stability == 'stable' output_base = proto_name + input = join_paths(proto_dir, '@0@/@1@/@2@.xml'.format(proto_stability, proto_name, output_base)) + elif proto_stability == 'private' + output_base = proto_name input = 'protocol/@0@.xml'.format(proto_name) else proto_version = p.get(2) diff --git a/meson.build b/meson.build index 921c6294a5..14ba3df876 100644 --- a/meson.build +++ b/meson.build @@ -32,7 +32,7 @@ atk_req = '>= 2.15.1' cairo_req = '>= 1.14.0' gdk_pixbuf_req = '>= 2.30.0' introspection_req = '>= 1.39.0' -wayland_proto_req = '>= 1.9' +wayland_proto_req = '>= 1.12' wayland_req = '>= 1.14.91' graphene_req = '>= 1.5.1' epoxy_req = '>= 1.4' |