Merge branch 'wip/carlosg/startup-vs-focus' into 'main'

Consider startup vs focus requests for the Wayland platform

See merge request GNOME/gtk!5386
This commit is contained in:
Matthias Clasen 2023-01-03 15:14:35 +00:00
commit 604aafe15d
6 changed files with 71 additions and 35 deletions

View File

@ -1148,6 +1148,8 @@ _gdk_display_get_next_serial (GdkDisplay *display)
* with custom startup-notification identifier unless
* [method@Gtk.Window.set_auto_startup_notification]
* is called to disable that feature.
*
* Deprecated: 4.10. Using gdk_toplevel_set_startup_id() is sufficient.
*/
void
gdk_display_notify_startup_complete (GdkDisplay *display,

View File

@ -83,7 +83,7 @@ GdkClipboard * gdk_display_get_clipboard (GdkDisplay
GDK_AVAILABLE_IN_ALL
GdkClipboard * gdk_display_get_primary_clipboard (GdkDisplay *display);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10_FOR(gdk_toplevel_set_startup_id)
void gdk_display_notify_startup_complete (GdkDisplay *display,
const char *startup_id);
GDK_AVAILABLE_IN_ALL

View File

@ -3871,6 +3871,25 @@ static void
gdk_wayland_surface_set_startup_id (GdkSurface *surface,
const char *startup_id)
{
GdkWaylandSurface *wayland_surface = GDK_WAYLAND_SURFACE (surface);
GdkDisplay *display = gdk_surface_get_display (surface);
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
gchar *free_me = NULL;
if (!startup_id)
{
free_me = g_steal_pointer (&display_wayland->startup_notification_id);
startup_id = free_me;
}
if (startup_id)
{
xdg_activation_v1_activate (display_wayland->xdg_activation,
startup_id,
wayland_surface->display_server.wl_surface);
}
g_free (free_me);
}
static gboolean

View File

@ -2648,6 +2648,7 @@ gdk_x11_surface_set_startup_id (GdkSurface *surface,
const char *startup_id)
{
GdkDisplay *display;
char *free_this = NULL;
g_return_if_fail (GDK_IS_SURFACE (surface));
@ -2664,6 +2665,23 @@ gdk_x11_surface_set_startup_id (GdkSurface *surface,
else
XDeleteProperty (GDK_DISPLAY_XDISPLAY (display), GDK_SURFACE_XID (surface),
gdk_x11_get_xatom_by_name_for_display (display, "_NET_STARTUP_ID"));
if (startup_id == NULL)
{
GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
startup_id = free_this = display_x11->startup_notification_id;
display_x11->startup_notification_id = NULL;
if (startup_id == NULL)
return;
}
gdk_x11_display_broadcast_startup_message (display, "remove",
"ID", startup_id,
NULL);
g_free (free_this);
}
static void

View File

@ -342,17 +342,6 @@ static void
gtk_application_after_emit (GApplication *application,
GVariant *platform_data)
{
const char *startup_notification_id = NULL;
g_variant_lookup (platform_data, "desktop-startup-id", "&s", &startup_notification_id);
if (startup_notification_id)
{
GdkDisplay *display;
display = gdk_display_get_default ();
if (display)
gdk_display_notify_startup_complete (display, startup_notification_id);
}
}
static void

View File

@ -247,7 +247,7 @@ typedef struct
guint in_emit_close_request : 1;
guint move_focus : 1;
guint unset_default : 1;
guint in_present : 1;
GtkGesture *click_gesture;
GtkEventController *application_shortcut_controller;
@ -2265,11 +2265,9 @@ gtk_window_set_startup_id (GtkWindow *window,
gtk_window_present_with_time (window, timestamp);
else
{
gdk_toplevel_set_startup_id (GDK_TOPLEVEL (priv->surface), 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_display_notify_startup_complete (gtk_widget_get_display (widget), priv->startup_id);
gdk_toplevel_set_startup_id (GDK_TOPLEVEL (priv->surface), priv->startup_id);
}
}
@ -3895,6 +3893,28 @@ gtk_window_update_toplevel (GtkWindow *window,
gdk_toplevel_layout_unref (layout);
}
static void
gtk_window_notify_startup (GtkWindow *window)
{
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
if (!disable_startup_notification)
{
/* Do we have a custom startup-notification id? */
if (priv->startup_id != NULL)
{
/* Make sure we have a "real" id */
if (!startup_id_is_fake (priv->startup_id))
gdk_toplevel_set_startup_id (GDK_TOPLEVEL (priv->surface), priv->startup_id);
g_free (priv->startup_id);
priv->startup_id = NULL;
}
else
gdk_toplevel_set_startup_id (GDK_TOPLEVEL (priv->surface), NULL);
}
}
static void
gtk_window_map (GtkWidget *widget)
{
@ -3919,21 +3939,8 @@ gtk_window_map (GtkWidget *widget)
gtk_window_set_theme_variant (window);
if (!disable_startup_notification)
{
/* Do we have a custom startup-notification id? */
if (priv->startup_id != NULL)
{
/* Make sure we have a "real" id */
if (!startup_id_is_fake (priv->startup_id))
gdk_display_notify_startup_complete (gtk_widget_get_display (widget), priv->startup_id);
g_free (priv->startup_id);
priv->startup_id = NULL;
}
else
gdk_display_notify_startup_complete (gtk_widget_get_display (widget), NULL);
}
if (!priv->in_present)
gtk_window_notify_startup (window);
/* inherit from transient parent, so that a dialog that is
* opened via keynav shows focus initially
@ -4357,8 +4364,6 @@ gtk_window_realize (GtkWidget *widget)
gdk_x11_surface_set_user_time (surface, timestamp);
}
#endif
if (!startup_id_is_fake (priv->startup_id))
gdk_toplevel_set_startup_id (GDK_TOPLEVEL (surface), priv->startup_id);
}
#ifdef GDK_WINDOWING_X11
@ -5274,11 +5279,14 @@ gtk_window_present_with_time (GtkWindow *window,
else
{
priv->initial_timestamp = timestamp;
priv->in_present = TRUE;
gtk_widget_set_visible (widget, TRUE);
priv->in_present = FALSE;
}
g_assert (priv->surface != NULL);
gdk_toplevel_focus (GDK_TOPLEVEL (priv->surface), timestamp);
gtk_window_notify_startup (window);
}
/**
@ -5888,7 +5896,7 @@ _gtk_window_set_is_active (GtkWindow *window,
* Sets whether the window should request startup notification.
*
* By default, after showing the first `GtkWindow`, GTK calls
* [method@Gdk.Display.notify_startup_complete]. Call this function
* [method@Gdk.Toplevel.set_startup_id]. Call this function
* to disable the automatic startup notification. You might do this
* if your first window is a splash screen, and you want to delay
* notification until after your real main window has been shown,