From 14d99bacbcb2ff413746db368a3a751c8f9ac277 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Mon, 18 Sep 2023 22:04:32 +0200 Subject: [PATCH] gdk/wayland: Use toplevel surface for activation At the moment of launching/activating an application, the keyboard focus may be on a transient surface that quickly disappears after activation. If this happens, and the compositor handles surface destruction before the activated application gets to reply, the activation request may be deemed outdated, and the "demands attention" paths be taken. Peek the toplevel from the focus surface, as that has larger guarantees to remain valid for the whole duration of the operation. Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/5820 --- gdk/wayland/gdkapplaunchcontext-wayland.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/gdk/wayland/gdkapplaunchcontext-wayland.c b/gdk/wayland/gdkapplaunchcontext-wayland.c index 75742dd8e5..d6252b3e5a 100644 --- a/gdk/wayland/gdkapplaunchcontext-wayland.c +++ b/gdk/wayland/gdkapplaunchcontext-wayland.c @@ -46,6 +46,21 @@ static const struct xdg_activation_token_v1_listener token_listener = { token_done, }; +static struct wl_surface * +peek_launcher_toplevel (GdkSeat *seat) +{ + struct wl_surface *wl_surface = NULL; + GdkSurface *focus_surface; + + focus_surface = gdk_wayland_device_get_focus (gdk_seat_get_keyboard (seat)); + while (focus_surface && focus_surface->parent) + focus_surface = focus_surface->parent; + if (focus_surface) + wl_surface = gdk_wayland_surface_get_wl_surface (focus_surface); + + return wl_surface; +} + static char * gdk_wayland_app_launch_context_get_startup_notify_id (GAppLaunchContext *context, GAppInfo *info, @@ -62,7 +77,6 @@ gdk_wayland_app_launch_context_get_startup_notify_id (GAppLaunchContext *context struct wl_event_queue *event_queue; struct wl_surface *wl_surface = NULL; GdkWaylandSeat *seat; - GdkSurface *focus_surface; AppLaunchData app_launch_data = { 0 }; event_queue = wl_display_create_queue (display->wl_display); @@ -78,9 +92,7 @@ gdk_wayland_app_launch_context_get_startup_notify_id (GAppLaunchContext *context _gdk_wayland_seat_get_last_implicit_grab_serial (seat, NULL), gdk_wayland_seat_get_wl_seat (GDK_SEAT (seat))); - focus_surface = gdk_wayland_device_get_focus (gdk_seat_get_keyboard (GDK_SEAT (seat))); - if (focus_surface) - wl_surface = gdk_wayland_surface_get_wl_surface (focus_surface); + wl_surface = peek_launcher_toplevel (GDK_SEAT (seat)); if (wl_surface) xdg_activation_token_v1_set_surface (token, wl_surface);