[mutter/wip/carlosg/xdg-activation-with-x11-sequences] wayland: Handle xdg_activation_v1_activate on non XDG activation tokens




commit 32332fd53d938229a57c1e2f9d51f9e5628a64e7
Author: Carlos Garnacho <carlosg gnome org>
Date:   Mon Feb 28 14:01:34 2022 +0100

    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: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2314>

 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 d30fbd3d65..5741b958f9 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 = {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]