From 32332fd53d938229a57c1e2f9d51f9e5628a64e7 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Mon, 28 Feb 2022 14:01:34 +0100 Subject: [PATCH] wayland: Handle xdg_activation_v1_activate on non XDG activation tokens The XDG activation support was missing interoperability with other startup sequences, notably those coming from other means than XDG activation. In order to play nice with X11 startup sequence IDs, we not just have to check for the startup ID being in the general pool, but we also need to fallback into X11-style timestamp comparison so the window ends up properly focused. Part-of: --- src/wayland/meta-wayland-activation.c | 35 +++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/src/wayland/meta-wayland-activation.c b/src/wayland/meta-wayland-activation.c index d30fbd3d6..5741b958f 100644 --- a/src/wayland/meta-wayland-activation.c +++ b/src/wayland/meta-wayland-activation.c @@ -283,6 +283,18 @@ token_can_activate (MetaXdgActivationToken *token) FALSE, NULL, NULL); } +static gboolean +startup_sequence_is_recent (MetaDisplay *display, + MetaStartupSequence *sequence) +{ + uint32_t seq_timestamp_ms, last_user_time_ms; + + seq_timestamp_ms = meta_startup_sequence_get_timestamp (sequence); + last_user_time_ms = meta_display_get_last_user_time (display); + + return seq_timestamp_ms >= last_user_time_ms; +} + static void activation_activate (struct wl_client *client, struct wl_resource *resource, @@ -291,7 +303,9 @@ activation_activate (struct wl_client *client, { MetaWaylandActivation *activation = wl_resource_get_user_data (resource); MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + MetaDisplay *display = meta_get_display (); MetaXdgActivationToken *token; + MetaStartupSequence *sequence; MetaWindow *window; window = meta_wayland_surface_get_window (surface); @@ -299,16 +313,27 @@ activation_activate (struct wl_client *client, return; token = g_hash_table_lookup (activation->tokens, token_str); - if (!token) + if (token) + { + sequence = token->sequence; + } + else + { + sequence = meta_startup_notification_lookup_sequence (display->startup_notification, + token_str); + } + + if (!sequence) return; - if (token_can_activate (token)) + if ((token && token_can_activate (token)) || + (!token && startup_sequence_is_recent (display, sequence))) { uint32_t timestamp; int32_t workspace_idx; - workspace_idx = meta_startup_sequence_get_workspace (token->sequence); - timestamp = meta_startup_sequence_get_timestamp (token->sequence); + workspace_idx = meta_startup_sequence_get_workspace (sequence); + timestamp = meta_startup_sequence_get_timestamp (sequence); if (workspace_idx >= 0) meta_window_change_workspace_by_index (window, workspace_idx, TRUE); @@ -321,7 +346,7 @@ activation_activate (struct wl_client *client, meta_window_set_demands_attention (window); } - meta_startup_sequence_complete (token->sequence); + meta_startup_sequence_complete (sequence); } static const struct xdg_activation_v1_interface activation_interface = {