[gtk-vnc-devel] PATCH: Fix keystate tracking



I believe I have discovered what was causing the problems with keyboard
state tracking.

In the codepath dealing with the 'release' event, we were matching on the
corresponding 'press' event, using keyvals.  There is, however, no rule
that the keyval for the release event, matches the keyval for the press
event. We mask out all the modifiers except shift, since RFB requires that
they be interpreted at the server side. The shift modifier, however, can
still cause the keyval to change. Consider trying to type a #  on a US
layout keyboard. There are 2 possible sequences

  Press 'shift'
  Press '3'
  Release '3'
  Release 'shift'

Or

  Press 'shift'
  Press '3'
  Release 'shift'
  Release '3'

In both scenarios the 'Press 3' event generates a keyval of '#' since the
shift modifier is applied. They differ in behaviour for the releae event.
If you release the shift key first, then 'Release 3' generates a keyval
of '3' instead of '#'. 

This patch simply tweaks the code to match on the hardware codecode instead
of the modified keyval.

Dan.

diff -r a5f3cb589f54 src/vncdisplay.c
--- a/src/vncdisplay.c	Fri Feb 22 08:30:27 2008 -0600
+++ b/src/vncdisplay.c	Mon Feb 25 16:11:18 2008 -0500
@@ -542,25 +542,6 @@ static gboolean key_event(GtkWidget *wid
 	if (priv->read_only)
 		return FALSE;
 
-	if (gvnc_using_raw_keycodes(priv->gvnc)) {
-		if (key->type == GDK_KEY_PRESS &&
-		    ((key->keyval == GDK_Control_L && (key->state & GDK_MOD1_MASK)) ||
-		     (key->keyval == GDK_Alt_L && (key->state & GDK_CONTROL_MASK)))) {
-			if (priv->in_pointer_grab)
-				do_pointer_ungrab(VNC_DISPLAY(widget), FALSE);
-			else
-				do_pointer_grab(VNC_DISPLAY(widget), FALSE);
-		}
-
-		if (key->type == GDK_KEY_PRESS)
-			gvnc_key_event(priv->gvnc, 1,
-				       key->keyval, key->hardware_keycode);
-		else
-			gvnc_key_event(priv->gvnc, 0,
-				       key->keyval, key->hardware_keycode);
-		return TRUE;
-	}
-
 	/*
 	 * Key handling in VNC is screwy. The event.keyval from GTK is
 	 * interpreted relative to modifier state. This really messes
@@ -606,13 +587,13 @@ static gboolean key_event(GtkWidget *wid
 	if (key->type == GDK_KEY_PRESS) {
 		int i;
 		for (i = 0 ; i < (int)(sizeof(priv->down_keyval)/sizeof(priv->down_keyval[0])) ; i++) {
-			if (priv->down_keyval[i] == 0) {
+			if (priv->down_scancode[i] == 0) {
 				priv->down_keyval[i] = keyval;
 				priv->down_scancode[i] = key->hardware_keycode;
 				/* Send the actual key event we're dealing with */
 				gvnc_key_event(priv->gvnc, 1, keyval, key->hardware_keycode);
 				break;
-			} else if (priv->down_keyval[i] == keyval) {
+			} else if (priv->down_scancode[i] == key->hardware_keycode) {
 				/* Got an press when we're already pressed ! Why ... ?
 				 *
 				 * Well, GTK merges sequential press+release pairs of the same
@@ -631,7 +612,7 @@ static gboolean key_event(GtkWidget *wid
 		int i;
 		for (i = 0 ; i < (int)(sizeof(priv->down_keyval)/sizeof(priv->down_keyval[0])) ; i++) {
 			/* We were pressed, and now we're released, so... */
-			if (priv->down_keyval[i] == keyval) {
+			if (priv->down_scancode[i] == key->hardware_keycode) {
 				priv->down_keyval[i] = 0;
 				priv->down_scancode[i] = 0;
 				/* ..send the key releae event we're dealing with */
@@ -699,7 +680,7 @@ static gboolean focus_event(GtkWidget *w
 
 	for (i = 0 ; i < (int)(sizeof(priv->down_keyval)/sizeof(priv->down_keyval[0])) ; i++) {
 		/* We are currently pressed so... */
-		if (priv->down_keyval[i] != 0) {
+		if (priv->down_scancode[i] != 0) {
 			/* ..send the fake key releae event to match */
 			gvnc_key_event(priv->gvnc, 0,
 				       priv->down_keyval[i], priv->down_scancode[i]);


-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 




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