From 25c15afe70ecd5b4b5affe5f10c5242380ab476f Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Fri, 13 Mar 2026 23:07:02 +0200 Subject: [PATCH 1/2] xwayland: Add support for wl_fixes.destroy_global Signed-off-by: Vlad Zahorodnii --- hw/xwayland/xwayland-input.c | 3 +++ hw/xwayland/xwayland-screen.c | 16 ++++++++++++++++ hw/xwayland/xwayland-screen.h | 2 ++ meson.build | 2 +- 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c index d940d604b..789a61166 100644 --- a/hw/xwayland/xwayland-input.c +++ b/hw/xwayland/xwayland-input.c @@ -3179,6 +3179,9 @@ input_handler(void *data, struct wl_registry *registry, uint32_t id, init_keyboard_shortcuts_inhibit(xwl_screen, id, version); } else if (strcmp(interface, xdg_system_bell_v1_interface.name) == 0) { init_system_bell(xwl_screen, id, version); + } else if (strcmp(interface, wl_fixes_interface.name) == 0) { + xwl_screen->input_fixes = + wl_registry_bind(registry, id, &wl_fixes_interface, 1); } } diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c index 44e4a8055..890c1d819 100644 --- a/hw/xwayland/xwayland-screen.c +++ b/hw/xwayland/xwayland-screen.c @@ -271,6 +271,18 @@ xwl_close_screen(ScreenPtr screen) RemoveNotifyFd(xwl_screen->wayland_fd); + if (xwl_screen->fixes) { + wl_fixes_destroy_registry(xwl_screen->fixes, xwl_screen->registry); + wl_fixes_destroy(xwl_screen->fixes); + } + if (xwl_screen->input_fixes) { + wl_fixes_destroy_registry(xwl_screen->input_fixes, xwl_screen->input_registry); + wl_fixes_destroy(xwl_screen->input_fixes); + } + + wl_registry_destroy(xwl_screen->registry); + wl_registry_destroy(xwl_screen->input_registry); + wl_display_disconnect(xwl_screen->display); screen->CloseScreen = xwl_screen->CloseScreen; @@ -557,6 +569,10 @@ registry_global(void *data, struct wl_registry *registry, uint32_t id, version); } #endif + else if (strcmp(interface, wl_fixes_interface.name) == 0) { + xwl_screen->fixes = + wl_registry_bind(registry, id, &wl_fixes_interface, 1); + } } static void diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h index ffbaa09e7..cccd1750c 100644 --- a/hw/xwayland/xwayland-screen.h +++ b/hw/xwayland/xwayland-screen.h @@ -98,7 +98,9 @@ struct xwl_screen { int wayland_fd; struct wl_display *display; struct wl_registry *registry; + struct wl_fixes *fixes; struct wl_registry *input_registry; + struct wl_fixes *input_fixes; struct wl_compositor *compositor; struct zwp_tablet_manager_v2 *tablet_manager; struct wl_shm *shm; diff --git a/meson.build b/meson.build index 1da05c48b..560ca6f3e 100644 --- a/meson.build +++ b/meson.build @@ -66,7 +66,7 @@ libdrm_req = '>= 2.4.116' libselinux_req = '>= 2.0.86' xext_req = '>= 1.0.99.4' xproto_req = '>= 7.0.31' -wayland_req = '>= 1.21.0' +wayland_req = '>= 1.23.91' wayland_protocols_req = '>= 1.38' gbm_req = '>= 10.2' xf86dgaproto_req = '>= 2.0.99.1' From 2ed37e6ed99ab9fbb619e9be5521911124247a3e Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Fri, 13 Mar 2026 23:11:44 +0200 Subject: [PATCH 2/2] xwayland: Add support for wl_fixes.ack_global_remove The wl_fixes.ack_global_remove request signals the compositor that the client will not bind the removed global. It can be used by the compositor to decide when it is safe to actually destroy the corresponding global. If a global is destroyed too soon, some clients may get disconnected. Signed-off-by: Vlad Zahorodnii --- hw/xwayland/xwayland-input.c | 6 +++++- hw/xwayland/xwayland-screen.c | 5 ++++- meson.build | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c index 789a61166..041b4faa6 100644 --- a/hw/xwayland/xwayland-input.c +++ b/hw/xwayland/xwayland-input.c @@ -3181,13 +3181,17 @@ input_handler(void *data, struct wl_registry *registry, uint32_t id, init_system_bell(xwl_screen, id, version); } else if (strcmp(interface, wl_fixes_interface.name) == 0) { xwl_screen->input_fixes = - wl_registry_bind(registry, id, &wl_fixes_interface, 1); + wl_registry_bind(registry, id, &wl_fixes_interface, min(version, 2)); } } static void global_remove(void *data, struct wl_registry *registry, uint32_t name) { + struct xwl_screen *xwl_screen = data; + + if (xwl_screen->input_fixes && wl_fixes_get_version(xwl_screen->input_fixes) >= WL_FIXES_ACK_GLOBAL_REMOVE_SINCE_VERSION) + wl_fixes_ack_global_remove(xwl_screen->input_fixes, xwl_screen->input_registry, name); } static const struct wl_registry_listener input_listener = { diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c index 890c1d819..a5067f884 100644 --- a/hw/xwayland/xwayland-screen.c +++ b/hw/xwayland/xwayland-screen.c @@ -571,7 +571,7 @@ registry_global(void *data, struct wl_registry *registry, uint32_t id, #endif else if (strcmp(interface, wl_fixes_interface.name) == 0) { xwl_screen->fixes = - wl_registry_bind(registry, id, &wl_fixes_interface, 1); + wl_registry_bind(registry, id, &wl_fixes_interface, min(version, 2)); } } @@ -597,6 +597,9 @@ global_remove(void *data, struct wl_registry *registry, uint32_t name) break; } } + + if (xwl_screen->fixes && wl_fixes_get_version(xwl_screen->fixes) >= WL_FIXES_ACK_GLOBAL_REMOVE_SINCE_VERSION) + wl_fixes_ack_global_remove(xwl_screen->fixes, registry, name); } static const struct wl_registry_listener registry_listener = { diff --git a/meson.build b/meson.build index 560ca6f3e..7551ddafe 100644 --- a/meson.build +++ b/meson.build @@ -66,7 +66,7 @@ libdrm_req = '>= 2.4.116' libselinux_req = '>= 2.0.86' xext_req = '>= 1.0.99.4' xproto_req = '>= 7.0.31' -wayland_req = '>= 1.23.91' +wayland_req = '>= 1.25.90' wayland_protocols_req = '>= 1.38' gbm_req = '>= 10.2' xf86dgaproto_req = '>= 2.0.99.1'