GtkApplication: avoid using stale timestamps

Avoid using a stale timestamp (from the last user interaction with the
application) when a message arrives from D-Bus requesting that a new
window be created.

In this case the most-correct thing that we can do is to use no
timestamp at all.

We modify gdk_x11_display_set_startup_notification_id() to allow a NULL
value to mean "reset everything" and then call this function
unconditionally on receipt of D-Bus activation requests.  The result
will be that a missing desktop-startup-id in the platform-data struct
will reset the timestamp.

Under their default configuration metacity and mutter will both map
windows presented with no timestamp in the foreground.  This could
result in false-positive, but there is very little we can do about that
without the original timestamp from the user event.

https://bugzilla.gnome.org/show_bug.cgi?id=752000
This commit is contained in:
Ryan Lortie 2015-07-06 14:08:11 -04:00 committed by Jasper St. Pierre
parent 18dbe181fb
commit a00a5ed210
2 changed files with 38 additions and 30 deletions

View File

@ -2388,33 +2388,44 @@ gdk_x11_display_set_startup_notification_id (GdkDisplay *display,
g_free (display_x11->startup_notification_id);
display_x11->startup_notification_id = g_strdup (startup_id);
/* Find the launch time from the startup_id, if it's there. Newer spec
* states that the startup_id is of the form <unique>_TIME<timestamp>
*/
time_str = g_strrstr (startup_id, "_TIME");
if (time_str != NULL)
if (startup_id != NULL)
{
gulong retval;
gchar *end;
errno = 0;
/* Find the launch time from the startup_id, if it's there. Newer spec
* states that the startup_id is of the form <unique>_TIME<timestamp>
*/
time_str = g_strrstr (startup_id, "_TIME");
if (time_str != NULL)
{
gulong retval;
gchar *end;
errno = 0;
/* Skip past the "_TIME" part */
time_str += 5;
/* Skip past the "_TIME" part */
time_str += 5;
retval = strtoul (time_str, &end, 0);
if (end != time_str && errno == 0)
display_x11->user_time = retval;
retval = strtoul (time_str, &end, 0);
if (end != time_str && errno == 0)
display_x11->user_time = retval;
}
else
display_x11->user_time = 0;
/* Set the startup id on the leader window so it
* applies to all windows we create on this display
*/
XChangeProperty (display_x11->xdisplay,
display_x11->leader_window,
gdk_x11_get_xatom_by_name_for_display (display, "_NET_STARTUP_ID"),
gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
PropModeReplace,
(guchar *)startup_id, strlen (startup_id));
}
else
{
XDeleteProperty (display_x11->xdisplay, display_x11->leader_window,
gdk_x11_get_xatom_by_name_for_display (display, "_NET_STARTUP_ID"));
display_x11->user_time = 0;
}
/* Set the startup id on the leader window so it
* applies to all windows we create on this display
*/
XChangeProperty (display_x11->xdisplay,
display_x11->leader_window,
gdk_x11_get_xatom_by_name_for_display (display, "_NET_STARTUP_ID"),
gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
PropModeReplace,
(guchar *)startup_id, strlen (startup_id));
}
static gboolean

View File

@ -82,14 +82,11 @@ static void
gtk_application_impl_x11_before_emit (GtkApplicationImpl *impl,
GVariant *platform_data)
{
const char *startup_notification_id;
const char *startup_notification_id = NULL;
if (g_variant_lookup (platform_data, "desktop-startup-id",
"&s", &startup_notification_id))
{
gdk_x11_display_set_startup_notification_id (gdk_display_get_default (),
startup_notification_id);
}
g_variant_lookup (platform_data, "desktop-startup-id", "&s", &startup_notification_id);
gdk_x11_display_set_startup_notification_id (gdk_display_get_default (), startup_notification_id);
}
static void