[Spice-devel] [PATCH spice-gtk] Release both shift keys in windows client

Pavel Grunt pgrunt at redhat.com
Tue Dec 2 01:16:37 PST 2014


In Windows shift key remains stuck when both shift keys are pressed
together. The solution is to release both shift keys when the modifier
for the shift key is not set.

https://bugs.freedesktop.org/show_bug.cgi?id=77259
---
 gtk/spice-widget.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c
index 3a2be87..41aef36 100644
--- a/gtk/spice-widget.c
+++ b/gtk/spice-widget.c
@@ -31,6 +31,7 @@
 #ifdef G_OS_WIN32
 #include <windows.h>
 #include <gdk/gdkwin32.h>
+#include <gdk/gdkkeysyms.h>
 #ifndef MAPVK_VK_TO_VSC /* may be undefined in older mingw-headers */
 #define MAPVK_VK_TO_VSC 0
 #endif
@@ -1322,6 +1323,7 @@ static gboolean key_event(GtkWidget *widget, GdkEventKey *key)
     int scancode;
 
 #ifdef G_OS_WIN32
+    static int both_shift_pressed[2]; /* stores scancodes for shift keys */
     /* on windows, we ought to ignore the reserved key event? */
     if (key->hardware_keycode == 0xff)
         return false;
@@ -1333,6 +1335,13 @@ static gboolean key_event(GtkWidget *widget, GdkEventKey *key)
             return false;
     }
 
+    if (both_shift_pressed[0] && !(key->state & GDK_SHIFT_MASK)) {
+        send_key(display, both_shift_pressed[0], SEND_KEY_RELEASE, 0);
+        if (both_shift_pressed[1])
+            send_key(display, both_shift_pressed[1], SEND_KEY_RELEASE, 0);
+        both_shift_pressed[0] = both_shift_pressed[1] = 0;
+    }
+
 #endif
     SPICE_DEBUG("%s %s: keycode: %d  state: %d  group %d modifier %d",
             __FUNCTION__, key->type == GDK_KEY_PRESS ? "press" : "release",
@@ -1369,6 +1378,13 @@ static gboolean key_event(GtkWidget *widget, GdkEventKey *key)
     /* MapVirtualKey doesn't return scancode with needed higher byte */
     scancode = MapVirtualKey(key->hardware_keycode, MAPVK_VK_TO_VSC) |
         (scancode & 0xff00);
+    if (key->type == GDK_KEY_PRESS && (key->state & GDK_SHIFT_MASK) &&
+        (key->keyval == GDK_KEY_Shift_L || key->keyval == GDK_KEY_Shift_R)) {
+        if (both_shift_pressed[0] == 0)
+            both_shift_pressed[0] = scancode;
+        else if (both_shift_pressed[1] == 0 && both_shift_pressed[0] != scancode)
+            both_shift_pressed[1] = scancode;
+    }
 #endif
 
     switch (key->type) {
-- 
1.9.3



More information about the Spice-devel mailing list