I noticed Linux GNOME desktop hangs up when Windows virt-viewer connects to the desktop and type some specific keys on JP keyboard. Server: GNOME desktop and IBus in RHEL 7 Client virt-viewer in Windows 7 with JP 106 keyboard When I see the key events with 'xev' command in GNOME desktop, I observed the unlimited too many key events of Zenkaku_Hankaku key and it caused the desktop freeze. The attached three patches resolves the desktop issues. 1. spice-gtk-1311820-01-zkhk.patch Zenkaku_Hankaku key has the different virtual-key codes between WM_KEYDOWN and WM_KEYUP and MapVirtualKey() cannot get the scancode from virtual-key code of WM_KEYDOWN (VK_OEM_ENLW) and spice-gtk didn't send the key press events and caused the desktop freeze with unlimited key release events. The fix is to get the scancode from virtual-key code of WM_KEYUP (VK_OEM_AUTO) and Zenkaku_Hankaku key works fine. Alt + Zenkaku_Hankaku key also has the different virtual-key code and MapVirtualKey() cannot get the scancode from the virtual-key and spice-gtk didn't send the key press events and Alt+Zenkaku_Hankaku could not be used. The fix is to get the scancode from virtual-key code of Zenkaku_Hankaku key (VK_OEM_AUTO). VK_CAPITAL, VK_OEM_BACKTAB are also applied the similar fixes. 2. spice-gtk-1311820-02-freeze.patch After spice-gtk-1311820-01-zkhk.patch is applied, WM_KEYDOWN of Alt+Zenkaku_Hankaku (VK_KANJI) can be sent with spice-gtk but Alt+Zenkaku_Hankaku did not send the WM_KEYUP event in Windows and it caused Linux desktop freeze with unlimited key press events. The fix is to send the key release event in spice-gtk. VK_OEM_ATTN, VK_OEM_COPY, VK_OEM_BACKTAB are applied the similar fixes. 3. spice-gtk-1311820-03-hangul.patch This is an additional fix. Korean keyboard assigns Hangul key on the position of Right Alt and Left Alt and Hangul keys have the different scancodes but MapVirtualKey() returned the same scancode and could not use Hangul key on Linux desktop. The fix is to send the right scancode of VK_HANGUL. Thanks, Fujiwara
>From d3e750a254e3ba5fc6332616a49ff9da42f77d46 Mon Sep 17 00:00:00 2001 From: Takao Fujiwara <tfujiwar@xxxxxxxxxx> Date: Thu, 31 Mar 2016 19:38:07 +0900 Subject: [PATCH] Send Zenkaku_Hankaku key in JP keyboard. MapVirtualKey() returns the scancode of the released Zenkaku_Hankaku key but does not pressed one and modifiered one. Any cases should be sent to use input method engines. --- src/spice-widget-priv.h | 1 + src/spice-widget.c | 37 +++++++++++++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/spice-widget-priv.h b/src/spice-widget-priv.h index 95bca8a..05f6a90 100644 --- a/src/spice-widget-priv.h +++ b/src/spice-widget-priv.h @@ -119,6 +119,7 @@ struct _SpiceDisplayPrivate { HHOOK keyboard_hook; int win_mouse[3]; int win_mouse_speed; + HKL keyboard_layout; #endif guint keypress_delay; gint zoom_level; diff --git a/src/spice-widget.c b/src/spice-widget.c index f605439..4e026f3 100644 --- a/src/spice-widget.c +++ b/src/spice-widget.c @@ -644,6 +644,9 @@ static void spice_display_init(SpiceDisplay *display) d->grabseq = spice_grab_sequence_new_from_string("Control_L+Alt_L"); d->activeseq = g_new0(gboolean, d->grabseq->nkeysyms); d->mouse_cursor = get_blank_cursor(); +#ifdef G_OS_WIN32 + d->keyboard_layout = GetKeyboardLayout(0); +#endif } static GObject * @@ -1418,6 +1421,7 @@ static gboolean key_event(GtkWidget *widget, GdkEventKey *key) SpiceDisplay *display = SPICE_DISPLAY(widget); SpiceDisplayPrivate *d = display->priv; int scancode; + int native_scancode; #ifdef G_OS_WIN32 /* on windows, we ought to ignore the reserved key event? */ @@ -1464,9 +1468,38 @@ static gboolean key_event(GtkWidget *widget, GdkEventKey *key) scancode = vnc_display_keymap_gdk2xtkbd(d->keycode_map, d->keycode_maplen, key->hardware_keycode); #ifdef G_OS_WIN32 + native_scancode = MapVirtualKey(key->hardware_keycode, MAPVK_VK_TO_VSC); + + /* Some OEM virtual-key codes are missed in MapVirtualKey(). */ + switch (HIWORD(d->keyboard_layout)) { + case 0x411: /* JP keyboard */ + if (native_scancode == 0) { + switch (key->hardware_keycode) { + case VK_OEM_ENLW: /* from Pressed Zenkaku_Hankaku */ + case VK_KANJI: /* from Alt + Zenkaku_Hankaku */ + scancode = MapVirtualKey(VK_OEM_AUTO, MAPVK_VK_TO_VSC); + /* to Released Zenkaku_Hankaku */ + goto got_scancode; + case VK_CAPITAL: /* from Alt + Eisu_toggle */ + scancode = MapVirtualKey(VK_OEM_ATTN, MAPVK_VK_TO_VSC); + /* to Eisu_toggle */ + goto got_scancode; + case VK_OEM_BACKTAB: /* from Alt + Hiragana_Katakana */ + scancode = MapVirtualKey(VK_OEM_COPY, MAPVK_VK_TO_VSC); + /* to Hiragana_Katakana */ + goto got_scancode; + default:; + } + } + break; + default:; + } + /* MapVirtualKey doesn't return scancode with needed higher byte */ - scancode = MapVirtualKey(key->hardware_keycode, MAPVK_VK_TO_VSC) | - (scancode & 0xff00); + scancode = native_scancode | (scancode & 0xff00); + +got_scancode: + #endif switch (key->type) { -- 2.5.0
>From e58345f9c3744dabb4316cffd3707d1534aacaf5 Mon Sep 17 00:00:00 2001 From: Takao Fujiwara <tfujiwar@xxxxxxxxxx> Date: Thu, 31 Mar 2016 19:42:02 +0900 Subject: [PATCH] Send key release event for some keys in JP keyboard. Some of the keys in JP keyboard do no send WM_KEYUP and it causes unlimited key events on Linux desktop. This sends the virtual key release events to avoid the desktop hangup. --- src/spice-widget.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/spice-widget.c b/src/spice-widget.c index 4e026f3..5e71d1b 100644 --- a/src/spice-widget.c +++ b/src/spice-widget.c @@ -1422,6 +1422,7 @@ static gboolean key_event(GtkWidget *widget, GdkEventKey *key) SpiceDisplayPrivate *d = display->priv; int scancode; int native_scancode; + gboolean no_key_release = FALSE; #ifdef G_OS_WIN32 /* on windows, we ought to ignore the reserved key event? */ @@ -1500,11 +1501,28 @@ static gboolean key_event(GtkWidget *widget, GdkEventKey *key) got_scancode: + /* Some keys do not send WM_KEYUP */ + switch (HIWORD(d->keyboard_layout)) { + case 0x411: /* JP keyboard */ + switch (key->hardware_keycode) { + case VK_KANJI: /* Alt + Zenkaku_Hankaku */ + case VK_OEM_ATTN: /* Eisu_toggle */ + case VK_OEM_COPY: /* Hiragana_Katakana */ + case VK_OEM_BACKTAB: /* Alt + Hiragana_Katakana */ + no_key_release = TRUE; + break; + default:; + } + break; + default:; + } #endif switch (key->type) { case GDK_KEY_PRESS: send_key(display, scancode, SEND_KEY_PRESS, !key->is_modifier); + if (no_key_release) + send_key(display, scancode, SEND_KEY_RELEASE, !key->is_modifier); break; case GDK_KEY_RELEASE: send_key(display, scancode, SEND_KEY_RELEASE, !key->is_modifier); -- 2.5.0
>From 5742f3057dbac181190d71796906d897fcd1f2c4 Mon Sep 17 00:00:00 2001 From: Takao Fujiwara <tfujiwar@xxxxxxxxxx> Date: Thu, 31 Mar 2016 19:43:49 +0900 Subject: [PATCH] Send key release event for some keys in JP keyboard. Some of the keys in JP keyboard do no send WM_KEYUP and it causes unlimited key events on Linux desktop. This sends the virtual key release events to avoid the desktop hangup. --- src/spice-widget.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/spice-widget.c b/src/spice-widget.c index 5e71d1b..c5a4530 100644 --- a/src/spice-widget.c +++ b/src/spice-widget.c @@ -1493,6 +1493,15 @@ static gboolean key_event(GtkWidget *widget, GdkEventKey *key) } } break; + case 0x412: /* KR keyboard */ + if (key->hardware_keycode == VK_HANGUL && native_scancode == 0x38) { + /* Left Alt (VK_MENU) has the scancode 0x38 but Hangul (VK_HANGUL) + * has the scancode 0x138 + */ + scancode = native_scancode | 0x100; + goto got_scancode; + } + break; default:; } -- 2.5.0
_______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel