From cf8c3be0307c3e044d23658d0cd9f0d501f01ee3 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Sun, 21 Jan 2024 13:28:46 +0100 Subject: [PATCH] gdk/wayland: Implement support for xdg-dialog Wayland protocol This protocol lifts some functionality from the gtk-shell protocol, namely the ability to tag dialogs as modal. Ensure to use this new protocol if available for the task, instead of the gtk-shell protocol. --- gdk/wayland/gdkdisplay-wayland.c | 8 +++++++ gdk/wayland/gdkdisplay-wayland.h | 2 ++ gdk/wayland/gdktoplevel-wayland.c | 37 ++++++++++++++++++++++++++++-- gdk/wayland/meson.build | 5 ++++ meson.build | 2 +- subprojects/wayland-protocols.wrap | 2 +- 6 files changed, 52 insertions(+), 4 deletions(-) diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index 4e6f0d8727..1c187e0091 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -97,6 +97,7 @@ #define OUTPUT_VERSION_WITH_DONE 2 #define NO_XDG_OUTPUT_DONE_SINCE_VERSION 3 #define OUTPUT_VERSION 3 +#define XDG_WM_DIALOG_VERSION 1 #ifdef HAVE_TOPLEVEL_STATE_SUSPENDED #define XDG_WM_BASE_VERSION 6 @@ -382,6 +383,13 @@ gdk_registry_handle_global (void *data, { display_wayland->zxdg_shell_v6_id = id; } + else if (strcmp (interface, "xdg_wm_dialog_v1") == 0) + { + display_wayland->xdg_wm_dialog = + wl_registry_bind (display_wayland->wl_registry, id, + &xdg_wm_dialog_v1_interface, + MIN (version, XDG_WM_DIALOG_VERSION)); + } else if (strcmp (interface, "gtk_shell1") == 0) { display_wayland->gtk_shell = diff --git a/gdk/wayland/gdkdisplay-wayland.h b/gdk/wayland/gdkdisplay-wayland.h index 3000c47f81..d7d8828d07 100644 --- a/gdk/wayland/gdkdisplay-wayland.h +++ b/gdk/wayland/gdkdisplay-wayland.h @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -102,6 +103,7 @@ struct _GdkWaylandDisplay DmabufFormatsInfo *dmabuf_formats_info; struct xdg_wm_base *xdg_wm_base; struct zxdg_shell_v6 *zxdg_shell_v6; + struct xdg_wm_dialog_v1 *xdg_wm_dialog; struct gtk_shell1 *gtk_shell; struct wl_data_device_manager *data_device_manager; struct wl_subcompositor *subcompositor; diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index d1924cc534..9105c2f589 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -84,6 +85,7 @@ struct _GdkWaylandToplevel struct gtk_surface1 *gtk_surface; struct xdg_toplevel *xdg_toplevel; struct zxdg_toplevel_v6 *zxdg_toplevel_v6; + struct xdg_dialog_v1 *xdg_dialog; } display_server; GdkWaylandToplevel *transient_for; @@ -205,6 +207,7 @@ gdk_wayland_toplevel_clear_saved_size (GdkWaylandToplevel *toplevel) static void maybe_set_gtk_surface_dbus_properties (GdkWaylandToplevel *wayland_toplevel); static void maybe_set_gtk_surface_modal (GdkWaylandToplevel *wayland_toplevel); +static gboolean maybe_set_xdg_dialog_modal (GdkWaylandToplevel *wayland_toplevel); static void gdk_wayland_toplevel_hide_surface (GdkWaylandSurface *wayland_surface) @@ -215,6 +218,7 @@ gdk_wayland_toplevel_hide_surface (GdkWaylandSurface *wayland_surface) g_clear_pointer (&toplevel->display_server.xdg_toplevel, xdg_toplevel_destroy); g_clear_pointer (&toplevel->display_server.zxdg_toplevel_v6, zxdg_toplevel_v6_destroy); + g_clear_pointer (&toplevel->display_server.xdg_dialog, xdg_dialog_v1_destroy); if (toplevel->display_server.gtk_surface) { @@ -877,7 +881,8 @@ gdk_wayland_surface_create_xdg_toplevel (GdkWaylandToplevel *wayland_toplevel) gdk_wayland_toplevel_set_application_id (GDK_TOPLEVEL (wayland_toplevel), app_id); maybe_set_gtk_surface_dbus_properties (wayland_toplevel); - maybe_set_gtk_surface_modal (wayland_toplevel); + if (!maybe_set_xdg_dialog_modal (wayland_toplevel)) + maybe_set_gtk_surface_modal (wayland_toplevel); gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "Wayland surface commit", NULL); wl_surface_commit (wayland_surface->display_server.wl_surface); @@ -1089,12 +1094,40 @@ maybe_set_gtk_surface_modal (GdkWaylandToplevel *wayland_toplevel) } +static gboolean +maybe_set_xdg_dialog_modal (GdkWaylandToplevel *wayland_toplevel) +{ + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (wayland_toplevel))); + + if (!display_wayland->xdg_wm_dialog) + return FALSE; + if (!is_realized_toplevel (GDK_WAYLAND_SURFACE (wayland_toplevel))) + return FALSE; + + if (!wayland_toplevel->display_server.xdg_dialog) + { + wayland_toplevel->display_server.xdg_dialog = + xdg_wm_dialog_v1_get_xdg_dialog (display_wayland->xdg_wm_dialog, + wayland_toplevel->display_server.xdg_toplevel); + } + + if (GDK_SURFACE (wayland_toplevel)->modal_hint) + xdg_dialog_v1_set_modal (wayland_toplevel->display_server.xdg_dialog); + else + xdg_dialog_v1_unset_modal (wayland_toplevel->display_server.xdg_dialog); + + return TRUE; +} + static void gdk_wayland_toplevel_set_modal_hint (GdkWaylandToplevel *wayland_toplevel, gboolean modal) { GDK_SURFACE (wayland_toplevel)->modal_hint = modal; - maybe_set_gtk_surface_modal (wayland_toplevel); + + if (!maybe_set_xdg_dialog_modal (wayland_toplevel)) + maybe_set_gtk_surface_modal (wayland_toplevel); } void diff --git a/gdk/wayland/meson.build b/gdk/wayland/meson.build index e06b3bdb21..e7561d43d7 100644 --- a/gdk/wayland/meson.build +++ b/gdk/wayland/meson.build @@ -140,6 +140,11 @@ proto_sources = [ 'stability': 'staging', 'version': 1, }, + { + 'name': 'xdg-dialog', + 'stability': 'staging', + 'version': 1, + }, ] gdk_wayland_gen_headers = [] diff --git a/meson.build b/meson.build index cd76d4ba33..035273e923 100644 --- a/meson.build +++ b/meson.build @@ -18,7 +18,7 @@ harfbuzz_req = '>= 2.6.0' fribidi_req = '>= 1.0.6' cairo_req = '>= 1.18.0' gdk_pixbuf_req = '>= 2.30.0' -wayland_proto_req = '>= 1.31' +wayland_proto_req = '>= 1.36' wayland_req = '>= 1.21.0' graphene_req = '>= 1.10.0' epoxy_req = '>= 1.4' diff --git a/subprojects/wayland-protocols.wrap b/subprojects/wayland-protocols.wrap index 3768be5082..8e82a5b768 100644 --- a/subprojects/wayland-protocols.wrap +++ b/subprojects/wayland-protocols.wrap @@ -1,5 +1,5 @@ [wrap-git] directory=wayland-protocols url=https://gitlab.freedesktop.org/wayland/wayland-protocols.git -revision=1.31 +revision=1.36 depth=1