[gtk-vnc-devel] PATCH: Fix event propagation



Two changesets added to GTK-VNC made it so that we return FALSE from
the mouse and keyboard event handlers, even when we handled the event
ourselves

  changeset:   89:c95f7f37df07
  user:        Anthony Liguori <anthony codemonkey ws>
  date:        Fri Dec 14 10:15:55 2007 -0600
  summary:     Propagate mouse events.


  changeset:   182:3b33ba158827
  user:        Anthony Liguori <anthony codemonkey ws>
  date:        Tue Mar 11 13:29:41 2008 -0500
  summary:     Propagate key press events.  This is needed for kvm-test.


The mouse one is reasonably harmless, but the keypress event propagation
has caused a world of pain. Since we tell GTK we didn't handle the event
it passes to the container widget, which may pass it up again, and again,
etc typically reaching the top level window. In the virt-manager case at
some point in this propagation the key event gets passed to a widget which
interprets TAB, UP, DOWN, LEFT & RIGHT key presses are a way to shift
input focus between widgets. So every time you use the arrow keys in a 
guest, focus gets taken away from the VNC widget.

I believe the problem is that we are setting up our event handlers in 
the wrong way. We are using the g_signal_connect() method for them, which 
is really intended for users of the widget.

All the standard GTK widgets register their event handlers statically in
their class object.

This patch switches GTK-VNC todo the same, and prevents the bogus event
propagation issues which cause loss of input focus.

Daniel

diff -r 6a869ca98aeb src/vncdisplay.c
--- a/src/vncdisplay.c	Thu Jun 05 14:11:20 2008 -0300
+++ b/src/vncdisplay.c	Fri Aug 01 13:40:01 2008 +0100
@@ -268,8 +268,7 @@
 	return cursor;
 }
 
-static gboolean expose_event(GtkWidget *widget, GdkEventExpose *expose,
-			     gpointer data G_GNUC_UNUSED)
+static gboolean expose_event(GtkWidget *widget, GdkEventExpose *expose)
 {
 	VncDisplay *obj = VNC_DISPLAY(widget);
 	VncDisplayPrivate *priv = obj->priv;
@@ -488,8 +487,7 @@
 		do_pointer_ungrab(obj, FALSE);
 }
 
-static gboolean button_event(GtkWidget *widget, GdkEventButton *button,
-			     gpointer data G_GNUC_UNUSED)
+static gboolean button_event(GtkWidget *widget, GdkEventButton *button)
 {
 	VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
 	int n;
@@ -520,11 +518,10 @@
 				   0x7FFF, 0x7FFF);
 	}
 
-	return FALSE;
+	return TRUE;
 }
 
-static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *scroll,
-			     gpointer data G_GNUC_UNUSED)
+static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *scroll)
 {
 	VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
 	int mask;
@@ -558,11 +555,10 @@
 				   0x7FFF, 0x7FFF);
 	}
 
-	return FALSE;
+	return TRUE;
 }
 
-static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion,
-			     gpointer data G_GNUC_UNUSED)
+static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion)
 {
 	VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
 	int dx, dy;
@@ -637,11 +633,10 @@
 	priv->last_x = (int)motion->x;
 	priv->last_y = (int)motion->y;
 
-	return FALSE;
+	return TRUE;
 }
 
-static gboolean key_event(GtkWidget *widget, GdkEventKey *key,
-			  gpointer data G_GNUC_UNUSED)
+static gboolean key_event(GtkWidget *widget, GdkEventKey *key)
 {
 	VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
 	guint keyval;
@@ -747,19 +742,18 @@
 			do_pointer_grab(VNC_DISPLAY(widget), FALSE);
 	}
 
-	return FALSE;
+	return TRUE;
 }
 
-static gboolean enter_event(GtkWidget *widget, GdkEventCrossing *crossing,
-                            gpointer data G_GNUC_UNUSED)
+static gboolean enter_event(GtkWidget *widget, GdkEventCrossing *crossing)
 {
         VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
 
         if (priv->gvnc == NULL || !gvnc_is_initialized(priv->gvnc))
-                return TRUE;
+                return FALSE;
 
         if (crossing->mode != GDK_CROSSING_NORMAL)
-                return TRUE;
+                return FALSE;
 
         if (priv->grab_keyboard)
                 do_keyboard_grab(VNC_DISPLAY(widget), FALSE);
@@ -767,16 +761,15 @@
         return TRUE;
 }
 
-static gboolean leave_event(GtkWidget *widget, GdkEventCrossing *crossing,
-                            gpointer data G_GNUC_UNUSED)
+static gboolean leave_event(GtkWidget *widget, GdkEventCrossing *crossing)
 {
         VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
 
         if (priv->gvnc == NULL || !gvnc_is_initialized(priv->gvnc))
-                return TRUE;
+                return FALSE;
 
         if (crossing->mode != GDK_CROSSING_NORMAL)
-                return TRUE;
+                return FALSE;
 
         if (priv->grab_keyboard)
                 do_keyboard_ungrab(VNC_DISPLAY(widget), FALSE);
@@ -788,14 +781,13 @@
 }
 
 
-static gboolean focus_event(GtkWidget *widget, GdkEventFocus *focus G_GNUC_UNUSED,
-                            gpointer data G_GNUC_UNUSED)
+static gboolean focus_event(GtkWidget *widget, GdkEventFocus *focus G_GNUC_UNUSED)
 {
         VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
 	int i;
 
         if (priv->gvnc == NULL || !gvnc_is_initialized(priv->gvnc))
-                return TRUE;
+                return FALSE;
 
 	for (i = 0 ; i < (int)(sizeof(priv->down_keyval)/sizeof(priv->down_keyval[0])) ; i++) {
 		/* We are currently pressed so... */
@@ -812,9 +804,11 @@
 }
 
 #if WITH_GTKGLEXT
-static void realize_event(GtkWidget *widget, gpointer data G_GNUC_UNUSED)
+static void realize_event(GtkWidget *widget)
 {
 	VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
+
+	GTK_WIDGET_CLASS (vnc_display_parent_class)->realize(widget);
 
 	if (priv->gl_config == NULL)
 		return;
@@ -1228,8 +1222,7 @@
 	}
 }
 
-static gboolean configure_event(GtkWidget *widget, GdkEventConfigure *configure,
-				gpointer data G_GNUC_UNUSED)
+static gboolean configure_event(GtkWidget *widget, GdkEventConfigure *configure)
 {
 	VncDisplay *obj = VNC_DISPLAY(widget);
 	VncDisplayPrivate *priv = obj->priv;
@@ -1808,6 +1801,23 @@
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 	GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (klass);
+	GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS (klass);
+
+	gtkwidget_class->expose_event = expose_event;
+	gtkwidget_class->motion_notify_event = motion_event;
+	gtkwidget_class->button_press_event = button_event;
+	gtkwidget_class->button_release_event = button_event;
+	gtkwidget_class->scroll_event = scroll_event;
+	gtkwidget_class->key_press_event = key_event;
+	gtkwidget_class->key_release_event = key_event;
+	gtkwidget_class->enter_notify_event = enter_event;
+	gtkwidget_class->leave_notify_event = leave_event;
+	gtkwidget_class->focus_out_event = focus_event;
+#if WITH_GTKGLEXT
+	gtkwidget_class->realize = realize_event;
+	gtkwidget_class->configure_event = configure_event;
+#endif
+
 
 	object_class->finalize = vnc_display_finalize;
 	object_class->get_property = vnc_display_get_property;
@@ -2088,33 +2098,6 @@
 	GtkObject *obj = GTK_OBJECT(display);
 	GtkWidget *widget = GTK_WIDGET(display);
 	VncDisplayPrivate *priv;
-
-	g_signal_connect(obj, "expose-event",
-			 G_CALLBACK(expose_event), NULL);
-	g_signal_connect(obj, "motion-notify-event",
-			 G_CALLBACK(motion_event), NULL);
-	g_signal_connect(obj, "button-press-event",
-			 G_CALLBACK(button_event), NULL);
-	g_signal_connect(obj, "button-release-event",
-			 G_CALLBACK(button_event), NULL);
-	g_signal_connect(obj, "scroll-event",
-			 G_CALLBACK(scroll_event), NULL);
-	g_signal_connect(obj, "key-press-event",
-			 G_CALLBACK(key_event), NULL);
-	g_signal_connect(obj, "key-release-event",
-			 G_CALLBACK(key_event), NULL);
-	g_signal_connect(obj, "enter-notify-event",
-			 G_CALLBACK(enter_event), NULL);
-	g_signal_connect(obj, "leave-notify-event",
-			 G_CALLBACK(leave_event), NULL);
-	g_signal_connect(obj, "focus-out-event",
-			 G_CALLBACK(focus_event), NULL);
-#if WITH_GTKGLEXT
-	g_signal_connect(obj, "realize",
-			 G_CALLBACK(realize_event), NULL);
-	g_signal_connect(obj, "configure-event",
-			 G_CALLBACK(configure_event), NULL);
-#endif
 
 	GTK_WIDGET_SET_FLAGS(obj, GTK_CAN_FOCUS);
 


-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|




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