[gedit/wip/gtkapp] Add startup notification timestamp hack



commit 0c662d00bab227ecd78bb0ae64a948bbb5b0a16b
Author: Ryan Lortie <desrt desrt ca>
Date:   Tue Nov 27 16:23:04 2012 -0500

    Add startup notification timestamp hack
    
    In the case that we are invoked with a DISPLAY but not a
    DESKTOP_STARTUP_ID, "steal" the current timestamp out of the server and
    act like it's the one we were invokved with.
    
    This deals with the case of launching gedit from a terminal and
    expecting the existing window to raise itself.

 gedit/gedit-app.c |   65 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 65 insertions(+), 0 deletions(-)
---
diff --git a/gedit/gedit-app.c b/gedit/gedit-app.c
index 42148bf..aa85fe4 100644
--- a/gedit/gedit-app.c
+++ b/gedit/gedit-app.c
@@ -530,6 +530,7 @@ gedit_app_activate (GeditApp *app)
 	}
 
 	g_slist_free_full (file_list, g_object_unref);
+	gtk_window_present (window);
 }
 
 static GOptionContext *
@@ -929,6 +930,67 @@ gedit_app_create_window_impl (GeditApp *app)
 	return window;
 }
 
+#ifdef GDK_WINDOWING_X11
+
+#include <X11/Xatom.h>
+#include <X11/Xlib.h>
+
+static void
+gedit_app_add_platform_data (GApplication    *app,
+                             GVariantBuilder *builder)
+{
+  G_APPLICATION_CLASS (gedit_app_parent_class)->add_platform_data (app, builder);
+
+  /* In the event that we are launched from a terminal we will probably
+   * see that we have DISPLAY set, but not DESKTOP_STARTUP_ID.
+   *
+   * If we are the second instance, we want to bring the window of the
+   * existing instance forward.  Unfortunately, without
+   * DESKTOP_STARTUP_ID being set, we have no timestamp on which to base
+   * the claim that we are the representative of the user's last
+   * interaction.
+   *
+   * We need to fake it by finding out the current timestamp of the
+   * server and sending that along as if we had DESKTOP_STARTUP_ID given
+   * in the first place.
+   *
+   * We want to do this without initialising all of Gtk+, so we can just
+   * talk directly to the X server to find out...
+   *
+   * In order to get the current timestamp, we need to see a
+   * timestamp-tagged event sent by the server.  Property change
+   * notifications are probably the easiest to generate.  We create our
+   * own window so that we don't spam other people who may be watching
+   * for property notifies on the root window...
+   *
+   * We could use any property at all, but we may as well use the
+   * "_NET_WM_USER_TIME_WINDOW" one since that's what we're doing
+   * here...
+   */
+  if (!g_getenv ("DESKTOP_STARTUP_ID") && g_getenv ("DISPLAY"))
+    {
+      gchar *startup_id;
+      Display *display;
+      Window window;
+      XEvent event;
+      Atom atom;
+
+      display = XOpenDisplay (0);
+      window = XCreateWindow (display, DefaultRootWindow (display), 0, 0, 1, 1, 0, 0, InputOnly, 0, 0, NULL);
+      XSelectInput (display, window, PropertyChangeMask);
+      atom = XInternAtom (display, "_NET_WM_USER_TIME_WINDOW", False);
+      XChangeProperty (display, window, atom, XA_WINDOW, 32, PropModeReplace, (void *) &window, 1);
+      XNextEvent (display, &event);
+      g_assert (event.type == PropertyNotify);
+      XCloseDisplay (display);
+
+      startup_id = g_strdup_printf ("_TIME%u", (guint) ((XPropertyEvent *) &event)->time);
+      g_variant_builder_add (builder, "{sv}", "desktop-startup-id", g_variant_new_string (startup_id));
+      g_free (startup_id);
+    }
+#endif
+}
+
 static void
 gedit_app_class_init (GeditAppClass *klass)
 {
@@ -945,6 +1007,9 @@ gedit_app_class_init (GeditAppClass *klass)
 	app_class->command_line = gedit_app_command_line;
 	app_class->local_command_line = gedit_app_local_command_line;
 	app_class->shutdown = gedit_app_shutdown;
+#ifdef GDK_WINDOWING_X11
+	app_class->add_platform_data = gedit_app_add_platform_data;
+#endif
 
 	klass->show_help = gedit_app_show_help_impl;
 	klass->help_link_id = gedit_app_help_link_id_impl;



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