Re: [gtk-vnc-devel] PATCH: sticky modifier keys



Daniel P. Berrange wrote:
Even with the use of a keyboard grab, there are certain key combinations
that are completely ungrabbable using regular GTK / X libraries. The prime
examples are  Ctrl-Alt-Backspace, and  Ctrl+Alt+Fn.  This isn't a problem
for traditional VNC servers, but when talking to a virtualed guest OS, then
you do need a way to send these combos to the guest OS.

This patch adds the 'sticky modifiers' concept currently used in virt-manager
Basically, if a Ctrl or Alt key is pressed 3 times in a row, then it is
treated as sticky until the next non-modifier key is released. This allows
you to type  'Ctrl Ctrl Ctrl Alt+F1'  to send 'Ctrl+Alt+F1' to the guest.
This is off by default.

Hrm, I don't like this very much. I'd prefer a sendkey like abstraction and then virt-manager could implement "stick modifiers" if it was desired.

I think a much more common way of addressing this problem will be to have a menu entry allowing certain combinations to be sent. The big usability problem with sticky modifiers is that if a user mistypes, something really bad could happen (like restarting X).

Regards,

Anthony Liguori

Dan.
------------------------------------------------------------------------

changeset:   27:3c2eb84af9ae
user:        "Daniel P. Berrange <berrange redhat com>"
date:        Fri Jul 06 13:39:41 2007 -0400
summary:     Added support for 'sticky' modifier keys

diff -r 06fb3b1e2320 -r 3c2eb84af9ae examples/gvncviewer.c
--- a/examples/gvncviewer.c	Fri Jul 06 11:40:33 2007 -0400
+++ b/examples/gvncviewer.c	Fri Jul 06 13:39:41 2007 -0400
@@ -124,6 +124,7 @@ int main(int argc, char **argv)
 	vnc_display_set_keyboard_grab(VNC_DISPLAY(vnc), TRUE);
 	vnc_display_set_pointer_grab(VNC_DISPLAY(vnc), TRUE);
 	//vnc_display_set_pointer_local(VNC_DISPLAY(vnc), TRUE);
+	vnc_display_set_sticky_modifiers(VNC_DISPLAY(vnc), TRUE);
 	vnc_display_open_name(VNC_DISPLAY(vnc), argv[1], argv[2]);
gtk_signal_connect(GTK_OBJECT(window), "delete-event",
diff -r 06fb3b1e2320 -r 3c2eb84af9ae examples/gvncviewer.py
--- a/examples/gvncviewer.py	Fri Jul 06 11:40:33 2007 -0400
+++ b/examples/gvncviewer.py	Fri Jul 06 13:39:41 2007 -0400
@@ -70,6 +70,7 @@ v.set_pointer_grab(True)
 v.set_pointer_grab(True)
 v.set_keyboard_grab(True)
 #v.set_pointer_local(True)
+v.set_sticky_modifiers(True)
if len(sys.argv) == 4:
     v.set_credential(gtkvnc.CREDENTIAL_PASSWORD, sys.argv[3])
diff -r 06fb3b1e2320 -r 3c2eb84af9ae src/libgtk-vnc_sym.version
--- a/src/libgtk-vnc_sym.version	Fri Jul 06 11:40:33 2007 -0400
+++ b/src/libgtk-vnc_sym.version	Fri Jul 06 13:39:41 2007 -0400
@@ -18,6 +18,7 @@
     vnc_display_set_pointer_local;
     vnc_display_set_pointer_grab;
     vnc_display_set_keyboard_grab;
+    vnc_display_set_sticky_modifiers;
vnc_display_get_width;
     vnc_display_get_height;
diff -r 06fb3b1e2320 -r 3c2eb84af9ae src/vncdisplay.c
--- a/src/vncdisplay.c	Fri Jul 06 11:40:33 2007 -0400
+++ b/src/vncdisplay.c	Fri Jul 06 13:39:41 2007 -0400
@@ -36,6 +36,9 @@ struct _VncDisplayPrivate
 	struct coroutine coroutine;
 	struct gvnc *gvnc;
+ guint last_keyval;
+	guint last_repeat;
+
 	gboolean in_pointer_grab;
 	gboolean in_keyboard_grab;
@@ -49,6 +52,7 @@ struct _VncDisplayPrivate
 	gboolean grab_pointer;
 	gboolean grab_keyboard;
 	gboolean local_pointer;
+	gboolean sticky_modifiers;
 };
/* Signals */
@@ -308,16 +312,56 @@ static gboolean key_event(GtkWidget *wid
 	VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
 	int down;
- if (priv->gvnc == NULL)
-		return TRUE;
-	
+	if (priv->gvnc == NULL || !gvnc_is_connected(priv->gvnc))
+		return TRUE;
+
+	/* Sticky key down processing */
+	if (key->type == GDK_KEY_PRESS && priv->sticky_modifiers) {
+		if (key->keyval == GDK_Control_L ||
+		    key->keyval == GDK_Control_R ||
+		    key->keyval == GDK_Alt_L ||
+		    key->keyval == GDK_Alt_R) {
+			/* Got a modifier, start counting presses */
+			if (priv->last_keyval == key->keyval) {
+				priv->last_repeat++;
+			} else {
+				priv->last_keyval = key->keyval;
+				priv->last_repeat = 1;
+			}
+		} else if (priv->last_keyval != 0 && priv->last_repeat >= 3) {
+			/* Got a non-modifier & a sticky key was active, so
+			 * send a fake key down event */
+			gvnc_key_event(priv->gvnc, 1, priv->last_keyval);
+		}
+	}
+
+
 	if (key->type == GDK_KEY_PRESS)
 		down = 1;
 	else
 		down = 0;
+ /* Send this real event */
 	gvnc_key_event(priv->gvnc, down, key->keyval);
+ /* Sticky key up processing */
+	if (key->type == GDK_KEY_RELEASE && priv->sticky_modifiers) {
+		/* If non-modifier need some sticky key processing */
+		if (key->keyval != GDK_Control_L &&
+		    key->keyval != GDK_Control_R &&
+		    key->keyval != GDK_Alt_L &&
+		    key->keyval != GDK_Alt_R) {
+			/* Have a sticky key, might need a fake key up */
+			if (priv->last_keyval != 0 &&
+			    priv->last_repeat >= 3)
+				gvnc_key_event(priv->gvnc, 0, priv->last_keyval);
+
+			/* Clear sticky key if any non-modifier was released */
+			priv->last_keyval = 0;
+		}
+	}
+
+	/* Release pointer grab with Ctrl+Alt */
 	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)))) {
@@ -840,6 +884,11 @@ void vnc_display_set_keyboard_grab(VncDi
 		do_keyboard_ungrab(obj);
 }
+void vnc_display_set_sticky_modifiers(VncDisplay *obj, gboolean enable)
+{
+	obj->priv->sticky_modifiers = enable;
+}
+
GType vnc_display_get_type(void)
 {
diff -r 06fb3b1e2320 -r 3c2eb84af9ae src/vncdisplay.h
--- a/src/vncdisplay.h	Fri Jul 06 11:40:33 2007 -0400
+++ b/src/vncdisplay.h	Fri Jul 06 13:39:41 2007 -0400
@@ -78,6 +78,7 @@ void		vnc_display_set_pointer_local(VncD
 void		vnc_display_set_pointer_local(VncDisplay *obj, gboolean enable);
 void		vnc_display_set_pointer_grab(VncDisplay *obj, gboolean enable);
 void		vnc_display_set_keyboard_grab(VncDisplay *obj, gboolean enable);
+void		vnc_display_set_sticky_modifiers(VncDisplay *obj, gboolean enable);
GdkPixbuf * vnc_display_get_pixbuf(VncDisplay *obj); ------------------------------------------------------------------------

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
------------------------------------------------------------------------

_______________________________________________
Gtk-vnc-devel mailing list
Gtk-vnc-devel lists sourceforge net
https://lists.sourceforge.net/lists/listinfo/gtk-vnc-devel





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