From: Carlos Garnacho Date: Mon, 18 Sep 2023 20:04:32 +0000 (+0200) Subject: gdk/wayland: Use toplevel surface for activation X-Git-Tag: archive/raspbian/4.12.4+ds-3+rpi1^2~21^2~2^2~2 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=1f774e20445ab8fdf5e6c4086a29606e8b0597df;p=gtk4.git 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 --- 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);