Merge branch 'gtk-gtk-3-24-xdg-foreign-v2' into 'gtk-3-24'

wayland: Add support for v2 of xdg_foreign protocol

See merge request GNOME/gtk!7440
This commit is contained in:
Matthias Clasen 2024-07-14 19:52:37 +00:00
commit 02cec9b8c9
4 changed files with 146 additions and 47 deletions

View File

@ -47,6 +47,7 @@
#include "tablet-unstable-v2-client-protocol.h" #include "tablet-unstable-v2-client-protocol.h"
#include "xdg-shell-unstable-v6-client-protocol.h" #include "xdg-shell-unstable-v6-client-protocol.h"
#include "xdg-foreign-unstable-v1-client-protocol.h" #include "xdg-foreign-unstable-v1-client-protocol.h"
#include "xdg-foreign-unstable-v2-client-protocol.h"
#include "server-decoration-client-protocol.h" #include "server-decoration-client-protocol.h"
#ifdef HAVE_TOPLEVEL_STATE_SUSPENDED #ifdef HAVE_TOPLEVEL_STATE_SUSPENDED
@ -493,16 +494,28 @@ gdk_registry_handle_global (void *data,
} }
else if (strcmp (interface, "zxdg_exporter_v1") == 0) else if (strcmp (interface, "zxdg_exporter_v1") == 0)
{ {
display_wayland->xdg_exporter = display_wayland->xdg_exporter_v1 =
wl_registry_bind (display_wayland->wl_registry, id, wl_registry_bind (display_wayland->wl_registry, id,
&zxdg_exporter_v1_interface, 1); &zxdg_exporter_v1_interface, 1);
} }
else if (strcmp (interface, "zxdg_importer_v1") == 0) else if (strcmp (interface, "zxdg_importer_v1") == 0)
{ {
display_wayland->xdg_importer = display_wayland->xdg_importer_v1 =
wl_registry_bind (display_wayland->wl_registry, id, wl_registry_bind (display_wayland->wl_registry, id,
&zxdg_importer_v1_interface, 1); &zxdg_importer_v1_interface, 1);
} }
else if (strcmp (interface, "zxdg_exporter_v2") == 0)
{
display_wayland->xdg_exporter_v2 =
wl_registry_bind (display_wayland->wl_registry, id,
&zxdg_exporter_v2_interface, 1);
}
else if (strcmp (interface, "zxdg_importer_v2") == 0)
{
display_wayland->xdg_importer_v2 =
wl_registry_bind (display_wayland->wl_registry, id,
&zxdg_importer_v2_interface, 1);
}
else if (strcmp (interface, "zwp_keyboard_shortcuts_inhibit_manager_v1") == 0) else if (strcmp (interface, "zwp_keyboard_shortcuts_inhibit_manager_v1") == 0)
{ {
display_wayland->keyboard_shortcuts_inhibit = display_wayland->keyboard_shortcuts_inhibit =

View File

@ -32,6 +32,7 @@
#include <gdk/wayland/xdg-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-shell-unstable-v6-client-protocol.h>
#include <gdk/wayland/xdg-foreign-unstable-v1-client-protocol.h> #include <gdk/wayland/xdg-foreign-unstable-v1-client-protocol.h>
#include <gdk/wayland/xdg-foreign-unstable-v2-client-protocol.h>
#include <gdk/wayland/keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h> #include <gdk/wayland/keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h>
#include <gdk/wayland/server-decoration-client-protocol.h> #include <gdk/wayland/server-decoration-client-protocol.h>
#include <gdk/wayland/xdg-output-unstable-v1-client-protocol.h> #include <gdk/wayland/xdg-output-unstable-v1-client-protocol.h>
@ -96,8 +97,10 @@ struct _GdkWaylandDisplay
struct gtk_primary_selection_device_manager *gtk_primary_selection_manager; struct gtk_primary_selection_device_manager *gtk_primary_selection_manager;
struct zwp_primary_selection_device_manager_v1 *zwp_primary_selection_manager_v1; struct zwp_primary_selection_device_manager_v1 *zwp_primary_selection_manager_v1;
struct zwp_tablet_manager_v2 *tablet_manager; struct zwp_tablet_manager_v2 *tablet_manager;
struct zxdg_exporter_v1 *xdg_exporter; struct zxdg_exporter_v1 *xdg_exporter_v1;
struct zxdg_importer_v1 *xdg_importer; struct zxdg_importer_v1 *xdg_importer_v1;
struct zxdg_exporter_v2 *xdg_exporter_v2;
struct zxdg_importer_v2 *xdg_importer_v2;
struct zwp_keyboard_shortcuts_inhibit_manager_v1 *keyboard_shortcuts_inhibit; struct zwp_keyboard_shortcuts_inhibit_manager_v1 *keyboard_shortcuts_inhibit;
struct org_kde_kwin_server_decoration_manager *server_decoration_manager; struct org_kde_kwin_server_decoration_manager *server_decoration_manager;
struct zxdg_output_manager_v1 *xdg_output_manager; struct zxdg_output_manager_v1 *xdg_output_manager;

View File

@ -133,7 +133,8 @@ struct _GdkWindowImplWayland
struct wl_subsurface *wl_subsurface; struct wl_subsurface *wl_subsurface;
struct wl_egl_window *egl_window; struct wl_egl_window *egl_window;
struct wl_egl_window *dummy_egl_window; struct wl_egl_window *dummy_egl_window;
struct zxdg_exported_v1 *xdg_exported; struct zxdg_exported_v1 *xdg_exported_v1;
struct zxdg_exported_v2 *xdg_exported_v2;
struct org_kde_kwin_server_decoration *server_decoration; struct org_kde_kwin_server_decoration *server_decoration;
} display_server; } display_server;
@ -236,7 +237,8 @@ struct _GdkWindowImplWayland
guint idle_source_id; guint idle_source_id;
} exported; } exported;
struct zxdg_imported_v1 *imported_transient_for; struct zxdg_imported_v1 *imported_v1_transient_for;
struct zxdg_imported_v2 *imported_v2_transient_for;
GHashTable *shortcuts_inhibitors; GHashTable *shortcuts_inhibitors;
struct wl_callback *surface_callback; struct wl_callback *surface_callback;
@ -1323,15 +1325,20 @@ gdk_wayland_window_sync_parent_of_imported (GdkWindow *window)
if (!impl->display_server.wl_surface) if (!impl->display_server.wl_surface)
return; return;
if (!impl->imported_transient_for)
return;
if (!is_realized_toplevel (window)) if (!is_realized_toplevel (window))
return; return;
zxdg_imported_v1_set_parent_of (impl->imported_transient_for, if (impl->imported_v2_transient_for)
{
zxdg_imported_v2_set_parent_of (impl->imported_v2_transient_for,
impl->display_server.wl_surface); impl->display_server.wl_surface);
} }
else if (impl->imported_v1_transient_for)
{
zxdg_imported_v1_set_parent_of (impl->imported_v1_transient_for,
impl->display_server.wl_surface);
}
}
static void static void
gdk_wayland_window_update_dialogs (GdkWindow *window) gdk_wayland_window_update_dialogs (GdkWindow *window)
@ -5418,7 +5425,7 @@ invoke_exported_closures (GdkWindow *window)
} }
static void static void
xdg_exported_handle (void *data, xdg_exported_v1_handle (void *data,
struct zxdg_exported_v1 *zxdg_exported_v1, struct zxdg_exported_v1 *zxdg_exported_v1,
const char *handle) const char *handle)
{ {
@ -5430,8 +5437,20 @@ xdg_exported_handle (void *data,
invoke_exported_closures (window); invoke_exported_closures (window);
} }
static const struct zxdg_exported_v1_listener xdg_exported_listener = { static const struct zxdg_exported_v1_listener xdg_exported_v1_listener = {
xdg_exported_handle xdg_exported_v1_handle
};
static void
xdg_exported_v2_handle (void *data,
struct zxdg_exported_v2 *zxdg_exported_v2,
const char *handle)
{
xdg_exported_v1_handle(data, NULL, handle);
}
static const struct zxdg_exported_v2_listener xdg_exported_v2_listener = {
xdg_exported_v2_handle
}; };
/** /**
@ -5453,7 +5472,7 @@ gdk_wayland_window_is_exported (GdkWindow *window)
{ {
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
return !!impl->display_server.xdg_exported; return impl->display_server.xdg_exported_v2 || impl->display_server.xdg_exported_v1;
} }
static gboolean static gboolean
@ -5520,24 +5539,44 @@ gdk_wayland_window_export_handle (GdkWindow *window,
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
display_wayland = GDK_WAYLAND_DISPLAY (display); display_wayland = GDK_WAYLAND_DISPLAY (display);
if (!display_wayland->xdg_exporter) if (display_wayland->xdg_exporter_v2)
{
if (!impl->display_server.xdg_exported_v2)
{
struct zxdg_exported_v2 *xdg_exported_v2;
xdg_exported_v2 =
zxdg_exporter_v2_export_toplevel (display_wayland->xdg_exporter_v2,
impl->display_server.wl_surface);
zxdg_exported_v2_add_listener (xdg_exported_v2,
&xdg_exported_v2_listener,
window);
impl->display_server.xdg_exported_v2 = xdg_exported_v2;
}
}
else if (display_wayland->xdg_exporter_v1)
{
if (!impl->display_server.xdg_exported_v1)
{
struct zxdg_exported_v1 *xdg_exported_v1;
xdg_exported_v1 =
zxdg_exporter_v1_export (display_wayland->xdg_exporter_v1,
impl->display_server.wl_surface);
zxdg_exported_v1_add_listener (xdg_exported_v1,
&xdg_exported_v1_listener,
window);
impl->display_server.xdg_exported_v1 = xdg_exported_v1;
}
}
else
{ {
g_warning ("Server is missing xdg_foreign support"); g_warning ("Server is missing xdg_foreign support");
return FALSE; return FALSE;
} }
if (!impl->display_server.xdg_exported)
{
struct zxdg_exported_v1 *xdg_exported;
xdg_exported = zxdg_exporter_v1_export (display_wayland->xdg_exporter,
impl->display_server.wl_surface);
zxdg_exported_v1_add_listener (xdg_exported,
&xdg_exported_listener,
window);
impl->display_server.xdg_exported = xdg_exported;
}
closure = g_new0 (ExportedClosure, 1); closure = g_new0 (ExportedClosure, 1);
closure->callback = callback; closure->callback = callback;
@ -5559,8 +5598,16 @@ gdk_wayland_window_unexport (GdkWindow *window)
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
GList *l; GList *l;
g_clear_pointer (&impl->display_server.xdg_exported, if (impl->display_server.xdg_exported_v2)
{
g_clear_pointer (&impl->display_server.xdg_exported_v2,
zxdg_exported_v2_destroy);
}
else if (impl->display_server.xdg_exported_v1)
{
g_clear_pointer (&impl->display_server.xdg_exported_v1,
zxdg_exported_v1_destroy); zxdg_exported_v1_destroy);
}
for (l = impl->exported.closures; l; l = l->next) for (l = impl->exported.closures; l; l = l->next)
{ {
@ -5605,7 +5652,8 @@ gdk_wayland_window_unexport_handle (GdkWindow *window)
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
g_return_if_fail (impl->display_server.xdg_exported); g_return_if_fail (impl->display_server.xdg_exported_v2 ||
impl->display_server.xdg_exported_v1);
impl->exported.export_count--; impl->exported.export_count--;
if (impl->exported.export_count == 0) if (impl->exported.export_count == 0)
@ -5617,11 +5665,20 @@ unset_transient_for_exported (GdkWindow *window)
{ {
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
g_clear_pointer (&impl->imported_transient_for, zxdg_imported_v1_destroy); if (impl->imported_v2_transient_for)
{
g_clear_pointer (&impl->imported_v2_transient_for,
zxdg_imported_v2_destroy);
}
else if (impl->imported_v1_transient_for)
{
g_clear_pointer (&impl->imported_v1_transient_for,
zxdg_imported_v1_destroy);
}
} }
static void static void
xdg_imported_destroyed (void *data, xdg_imported_v1_destroyed (void *data,
struct zxdg_imported_v1 *zxdg_imported_v1) struct zxdg_imported_v1 *zxdg_imported_v1)
{ {
GdkWindow *window = data; GdkWindow *window = data;
@ -5629,8 +5686,19 @@ xdg_imported_destroyed (void *data,
unset_transient_for_exported (window); unset_transient_for_exported (window);
} }
static const struct zxdg_imported_v1_listener xdg_imported_listener = { static const struct zxdg_imported_v1_listener xdg_imported_v1_listener = {
xdg_imported_destroyed, xdg_imported_v1_destroyed,
};
static void
xdg_imported_v2_destroyed (void *data,
struct zxdg_imported_v2 *zxdg_imported_v2)
{
xdg_imported_v1_destroyed (data, NULL);
}
static const struct zxdg_imported_v2_listener xdg_imported_v2_listener = {
xdg_imported_v2_destroyed,
}; };
/** /**
@ -5666,20 +5734,34 @@ gdk_wayland_window_set_transient_for_exported (GdkWindow *window,
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
display_wayland = GDK_WAYLAND_DISPLAY (display); display_wayland = GDK_WAYLAND_DISPLAY (display);
if (!display_wayland->xdg_importer) if (display_wayland->xdg_importer_v2)
{
gdk_window_set_transient_for (window, NULL);
impl->imported_v2_transient_for =
zxdg_importer_v2_import_toplevel (display_wayland->xdg_importer_v2,
parent_handle_str);
zxdg_imported_v2_add_listener (impl->imported_v2_transient_for,
&xdg_imported_v2_listener,
window);
}
else if (display_wayland->xdg_importer_v1)
{
gdk_window_set_transient_for (window, NULL);
impl->imported_v1_transient_for =
zxdg_importer_v1_import (display_wayland->xdg_importer_v1,
parent_handle_str);
zxdg_imported_v1_add_listener (impl->imported_v1_transient_for,
&xdg_imported_v1_listener,
window);
}
else
{ {
g_warning ("Server is missing xdg_foreign support"); g_warning ("Server is missing xdg_foreign support");
return FALSE; return FALSE;
} }
gdk_window_set_transient_for (window, NULL);
impl->imported_transient_for =
zxdg_importer_v1_import (display_wayland->xdg_importer, parent_handle_str);
zxdg_imported_v1_add_listener (impl->imported_transient_for,
&xdg_imported_listener,
window);
gdk_wayland_window_sync_parent_of_imported (window); gdk_wayland_window_sync_parent_of_imported (window);
return TRUE; return TRUE;

View File

@ -53,6 +53,7 @@ proto_sources = [
['xdg-shell', 'unstable', 'v6', ], ['xdg-shell', 'unstable', 'v6', ],
['xdg-shell', 'stable', ], ['xdg-shell', 'stable', ],
['xdg-foreign', 'unstable', 'v1', ], ['xdg-foreign', 'unstable', 'v1', ],
['xdg-foreign', 'unstable', 'v2', ],
['tablet', 'unstable', 'v2', ], ['tablet', 'unstable', 'v2', ],
['keyboard-shortcuts-inhibit', 'unstable', 'v1', ], ['keyboard-shortcuts-inhibit', 'unstable', 'v1', ],
['server-decoration', 'private' ], ['server-decoration', 'private' ],