gtkwindow: Shuffle gdk_window_set_startup_id() calls
authorCarlos Garnacho <carlosg@gnome.org>
Wed, 18 Jan 2023 20:01:00 +0000 (21:01 +0100)
committerCarlos Garnacho <carlosg@gnome.org>
Wed, 25 Jan 2023 10:22:40 +0000 (11:22 +0100)
While this used to be tangential to windows showing or requesting
focus, the xdg-activation Wayland protocol does merge both concepts
together.

But also, for a correct interaction with the compositor, the
toolkit should ideally merge the activation request resulting from
both into the same one, so that the gdk_window_focus() request
replies to the startup token that started the application and
correct focus-stealing prevention/etc happens, instead making up
one just in time for the focus request.

This kind of requires doing things in the right order, a show()
request on the GtkWindow should activate any pending activation
token on the toplevel, a present() request should additionally
create a new token if there was none pending. And
xdg_activation_v1_activate() should happen once on both.

Shuffle the gdk_window_set_startup_id() calls so that this
happens in the right order for Wayland, while making X11 happy
too.

(cherry-picked from commit e8adfa2a889cd45ee0ce0727d7eae0a61fdb7dce)

gtk/gtkwindow.c

index 4e341f654bc3a451c8843fe8c44f770a9abffcd2..e1b09a3658e4cc218a217f1dc66fd6d9b49cb1cb 100644 (file)
@@ -266,6 +266,8 @@ struct _GtkWindowPrivate
 
   guint    use_subsurface            : 1;
 
+  guint    in_present                : 1;
+
   GdkWindowTypeHint type_hint;
 
   GtkGesture *multipress_gesture;
@@ -2563,15 +2565,12 @@ gtk_window_set_startup_id (GtkWindow   *window,
        */
       if (startup_id_is_fake (priv->startup_id))
        gtk_window_present_with_time (window, timestamp);
-      else 
+      else
         {
-          gdk_window_set_startup_id (gdk_window,
-                                     priv->startup_id);
-          
-          /* If window is mapped, terminate the startup-notification too */
+          /* If window is mapped, terminate the startup-notification */
           if (_gtk_widget_get_mapped (widget) &&
               !disable_startup_notification)
-            gdk_notify_startup_complete_with_id (priv->startup_id);
+            gdk_window_set_startup_id (gdk_window, priv->startup_id);
         }
     }
 
@@ -6380,7 +6379,8 @@ gtk_window_map (GtkWidget *widget)
 
   gdk_window_show (gdk_window);
 
-  gtk_window_notify_startup (window);
+  if (!priv->in_present)
+    gtk_window_notify_startup (window);
 
   /* if mnemonics visible is not already set
    * (as in the case of popup menus), then hide mnemonics initially
@@ -7622,8 +7622,6 @@ gtk_window_realize (GtkWidget *widget)
             gdk_x11_window_set_user_time (gdk_window, timestamp);
         }
 #endif
-      if (!startup_id_is_fake (priv->startup_id))
-        gdk_window_set_startup_id (gdk_window, priv->startup_id);
     }
 
 #ifdef GDK_WINDOWING_X11
@@ -10605,8 +10603,12 @@ gtk_window_present_with_time (GtkWindow *window,
   else
     {
       priv->initial_timestamp = timestamp;
+      priv->in_present = TRUE;
       gtk_widget_show (widget);
+      priv->in_present = FALSE;
     }
+
+  gtk_window_notify_startup (window);
 }
 
 /**