Patch: re-enable XSetInputFocus() timestamps



I have resurrected John Harper's patch to use event timestamps for
XSetInputFocus() in bonobo-socket.  I added some bits that copy over
GTK+ 1.3's get_server_time() function so that we can actually use
correct timestamps.

I have tested this with Sawfish from CVS and it seems to work OK.

Is this OK to commit?

  Federico

Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/bonobo/ChangeLog,v
retrieving revision 1.1150
diff -u -r1.1150 ChangeLog
--- ChangeLog	2001/11/16 15:56:50	1.1150
+++ ChangeLog	2001/12/10 20:28:19
@@ -1,3 +1,13 @@
+2001-12-10  Federico Mena Quintero  <federico ximian com>
+
+	* bonobo/bonobo-socket.c (bonobo_socket_focus_in_event): Use the
+	last_x_time_stamp instead of CurrentTime for XSetInputFocus().
+	(bonobo_socket_focus_out_event): Likewise.
+	(claim_focus): Likewise.
+	(get_server_time): New function, copied from GTK+ 1.3, to get a
+	good-enough timestamp from the X server.  We use this timestamp
+	with XSetInputFocus().
+
 2001-11-16  Frederic Crozat  <fcrozat mandrakesoft com>
 
 	* bonobo/bonobo-arg.c: (bonobo_arg_copy):
Index: bonobo/bonobo-socket.c
===================================================================
RCS file: /cvs/gnome/bonobo/bonobo/bonobo-socket.c,v
retrieving revision 1.22
diff -u -r1.22 bonobo-socket.c
--- bonobo/bonobo-socket.c	2001/11/12 22:08:21	1.22
+++ bonobo/bonobo-socket.c	2001/12/10 20:28:29
@@ -58,6 +58,7 @@
 
 /* Last timestamp we got from the X server, for use with XSetInputFocus() */
 static guint32 last_x_time_stamp = CurrentTime;
+static Atom timestamp_prop_atom;
 
 /* Forward declararations */
 
@@ -281,7 +282,7 @@
 	attributes.wclass = GDK_INPUT_OUTPUT;
 	attributes.visual = gtk_widget_get_visual (widget);
 	attributes.colormap = gtk_widget_get_colormap (widget);
-	attributes.event_mask = GDK_FOCUS_CHANGE_MASK;
+	attributes.event_mask = GDK_FOCUS_CHANGE_MASK | GDK_PROPERTY_CHANGE_MASK;
 
 	attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
 
@@ -477,7 +478,49 @@
 	}
 }
 
+/* Copied from GTK+ 1.3, used as a predicate for XIfEvent() */
+static Bool
+timestamp_predicate (Display *display,
+		     XEvent  *xevent,
+		     XPointer arg)
+{
+	Window xwindow = GPOINTER_TO_UINT (arg);
+
+	if (xevent->type == PropertyNotify &&
+	    xevent->xproperty.window == xwindow &&
+	    xevent->xproperty.atom == timestamp_prop_atom)
+		return True;
+
+	return False;
+}
+
 /*
+ * Copied from GTK+ 1.3, used to get an event timestamp from the server by
+ * frobbing a property on a window and waiting for the PropertyNotify event.
+ */
+static guint32
+get_server_time (GdkWindow *window)
+{
+	Window   xwindow;
+	guchar c = 'a';
+	XEvent xevent;
+
+	if (!timestamp_prop_atom)
+		timestamp_prop_atom = XInternAtom (GDK_DISPLAY (), "GDK_TIMESTAMP_PROP", FALSE);
+
+	xwindow = GDK_WINDOW_XWINDOW (window);
+
+	XChangeProperty (GDK_DISPLAY (), xwindow,
+			 timestamp_prop_atom, timestamp_prop_atom,
+			 8, PropModeReplace, &c, 1);
+
+	XIfEvent (GDK_DISPLAY (), &xevent,
+		  timestamp_predicate, GUINT_TO_POINTER (xwindow));
+
+	return xevent.xproperty.time;
+}
+
+/*
  * Focus_in_event handler for the socket widget.  If we had previously given the
  * focus to the child window, we give it the focus again.  This is so that
  * unfocusing the toplevel window and focusing it back again will restore the
@@ -496,11 +539,17 @@
 
 	priv = socket->priv;
 
+	/*
+	 * Focus events do not come with a timestamp, so we fetch a good-enough
+	 * timestamp by hand.
+	 */
+	last_x_time_stamp = get_server_time (GTK_WIDGET (socket)->window);
+
 	if (priv->gave_focus && priv->plug_window) {
 		gdk_error_trap_push ();
 		XSetInputFocus (GDK_DISPLAY (),
 				GDK_WINDOW_XWINDOW (priv->plug_window),
-				RevertToParent, CurrentTime);
+				RevertToParent, last_x_time_stamp);
 		gdk_flush();
 		gdk_error_trap_pop ();
 	}
@@ -519,6 +568,12 @@
 	socket = BONOBO_SOCKET (widget);
 	priv = socket->priv;
 
+	/*
+	 * Focus events do not come with a timestamp, so we fetch a good-enough
+	 * timestamp by hand.
+	 */
+	last_x_time_stamp = get_server_time (GTK_WIDGET (socket)->window);
+
 	toplevel = gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW);
 
 	if (toplevel && GTK_WIDGET_MAPPED (toplevel)) {
@@ -531,7 +586,7 @@
 		gdk_error_trap_push ();
 		XSetInputFocus (GDK_DISPLAY (),
 				GDK_WINDOW_XWINDOW (toplevel->window),
-				RevertToParent, CurrentTime);
+				RevertToParent, last_x_time_stamp);
 		gdk_flush();
 		gdk_error_trap_pop ();
 	}
@@ -564,7 +619,7 @@
 		gdk_error_trap_push ();
 		XSetInputFocus (GDK_DISPLAY (),
 				GDK_WINDOW_XWINDOW (priv->plug_window),
-				RevertToParent, CurrentTime);
+				RevertToParent, last_x_time_stamp);
 		gdk_flush ();
 		gdk_error_trap_pop ();
 	}
@@ -775,7 +830,7 @@
 			if (toplevel)
 				XSetInputFocus (GDK_DISPLAY (),
 						GDK_WINDOW_XWINDOW (toplevel->window),
-						RevertToParent, CurrentTime);
+						RevertToParent, last_x_time_stamp);
 #endif
 		}
 


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