Re: startup-notification support for nautilus as a launchee



On Fri, 18 Feb 2005 18:32:01 -0700, Elijah Newren <newren gmail com> wrote:
> On Tue, 15 Feb 2005 10:26:57 +0100, Alexander Larsson <alexl redhat com> wrote:
> > On Mon, 2005-02-14 at 16:51 -0700, Elijah Newren wrote:
> >
> > > As Crispin pointed out, though, perhaps an ugly hack is in order--if
> > > no startup-id is provided then ping the xserver for a timestamp
> > > (gdk_x11_get_server_time) and use that for the new window instead of
> > > spewing a warning.  It'd still partially break
> > > focus-stealing-prevention (since the timestamp would be too late), but
> > > given that nautilus windows (hopefully) are only ever launched due to
> > > user interaction, it may be better than the alternative.  I can code
> > > it up if you want, it'd only be a few lines.
> >
> > I'm not sure how this will affect things, so I don't know if I want this
> > or not. Do I? :)

Yes, it's probably to late to fix bug 166722 and that means that
nautilus can sometimes be launched without startup notification.  This
means that some windows are being launched and not getting focus when
they should.  For example, click on the "Desktop" entry in the
"Places" menu of the panel.  I believe this also holds for bookmarks
made in the filechooser due to comments from Dennis in bug 166242,
though I have never made any such things.

I covered the basic idea behind this patch in my previous email, but I
have a much more succinct way to put it: although in these cases
nautilus can't know the timestamp of the event that caused it to
launch, it can at least approximate it far better than gtk+ can, and
it should therefore override the gtk+ default.

Anyway, patch attached to do this.  I can run it by the release team
after getting approval here.
Index: src/nautilus-application.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/nautilus-application.c,v
retrieving revision 1.231
diff -p -u -r1.231 nautilus-application.c
--- src/nautilus-application.c	22 Feb 2005 08:46:38 -0000	1.231
+++ src/nautilus-application.c	28 Feb 2005 19:26:47 -0000
@@ -1034,8 +1034,14 @@ end_startup_notification (GtkWidget  *wi
 					   gdk_screen_get_number (screen),
 					   startup_id);
 
-	sn_launchee_context_setup_window (context,
-					  GDK_WINDOW_XWINDOW (widget->window));
+	/* Handle the setup for the window if the startup_id is valid;
+	 * I don't think it can hurt to do this even if it was
+	 * invalid, but why do the extra work...
+	 */
+	if (strncmp (sn_launchee_context_get_startup_id (context), "_TIME", 5) != 0) {
+		sn_launchee_context_setup_window (context,
+						  GDK_WINDOW_XWINDOW (widget->window));
+	}
 
 	/* Now, set the _NET_WM_USER_TIME for the new window to the timestamp
 	 * that caused the window to be launched.
Index: src/nautilus-main.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/nautilus-main.c,v
retrieving revision 1.144
diff -p -u -r1.144 nautilus-main.c
--- src/nautilus-main.c	14 Feb 2005 10:59:23 -0000	1.144
+++ src/nautilus-main.c	28 Feb 2005 19:26:47 -0000
@@ -54,6 +54,7 @@
 #include <libxml/parser.h>
 #include <popt.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 
 /* Keeps track of everyone who wants the main event loop kept active */
@@ -188,6 +189,59 @@ register_icons (void)
 	
 }
 
+/* Copied from libnautilus/nautilus-program-choosing.c; In this case,
+ * though, it's really needed because we have no real alternative when
+ * no DESKTOP_STARTUP_ID (with its accompanying timestamp) is
+ * provided...
+ */
+static Time
+slowly_and_stupidly_obtain_timestamp (Display *xdisplay)
+{
+	Window xwindow;
+	XEvent event;
+	
+	{
+		XSetWindowAttributes attrs;
+		Atom atom_name;
+		Atom atom_type;
+		char* name;
+		
+		attrs.override_redirect = True;
+		attrs.event_mask = PropertyChangeMask | StructureNotifyMask;
+		
+		xwindow =
+			XCreateWindow (xdisplay,
+				       RootWindow (xdisplay, 0),
+				       -100, -100, 1, 1,
+				       0,
+				       CopyFromParent,
+				       CopyFromParent,
+				       CopyFromParent,
+				       CWOverrideRedirect | CWEventMask,
+				       &attrs);
+		
+		atom_name = XInternAtom (xdisplay, "WM_NAME", TRUE);
+		g_assert (atom_name != None);
+		atom_type = XInternAtom (xdisplay, "STRING", TRUE);
+		g_assert (atom_type != None);
+		
+		name = "Fake Window";
+		XChangeProperty (xdisplay, 
+				 xwindow, atom_name,
+				 atom_type,
+				 8, PropModeReplace, name, strlen (name));
+	}
+	
+	XWindowEvent (xdisplay,
+		      xwindow,
+		      PropertyChangeMask,
+		      &event);
+	
+	XDestroyWindow(xdisplay, xwindow);
+	
+	return event.xproperty.time;
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -276,6 +330,15 @@ main (int argc, char *argv[])
 				      GNOME_PARAM_POPT_TABLE, options,
 				      GNOME_PARAM_HUMAN_READABLE_NAME, _("Nautilus"),
 				      NULL);
+
+	/* Do this here so that gdk_display is initialized */
+	if (startup_id_copy == NULL) {
+		/* Create a fake one containing a timestamp that we can use */
+		Time timestamp;
+		timestamp = slowly_and_stupidly_obtain_timestamp (gdk_display);
+		startup_id_copy = g_strdup_printf ("_TIME%lu",
+						   timestamp);
+	}
 
 	register_icons ();
 


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