From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:45057) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RvnQj-00009z-WE for qemu-devel@nongnu.org; Fri, 10 Feb 2012 05:10:20 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RvnQc-0004Rk-Di for qemu-devel@nongnu.org; Fri, 10 Feb 2012 05:10:13 -0500 Received: from mx1.redhat.com ([209.132.183.28]:47430) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RvnQc-0004Qc-6f for qemu-devel@nongnu.org; Fri, 10 Feb 2012 05:10:06 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q1AAA4jZ022265 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 10 Feb 2012 05:10:05 -0500 From: Gerd Hoffmann Date: Fri, 10 Feb 2012 11:10:00 +0100 Message-Id: <1328868600-9025-5-git-send-email-kraxel@redhat.com> In-Reply-To: <1328868600-9025-1-git-send-email-kraxel@redhat.com> References: <1328868600-9025-1-git-send-email-kraxel@redhat.com> Subject: [Qemu-devel] [PATCH 4/4] vnc: lift modifier keys on client disconnect. List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Gerd Hoffmann For any modifier key (shift, ctrl, alt) still pressed on disconnect inject a key-up event into the guest. The vnc client is gone, it will not do that, so qemu has to do it instead. Without this keys will get stuck, making the guest act in weird ways after reconnecting. Reproducer: exit vnc client via Alt-F4, guest continues to see the pressed alt key and will not react to key events in any useful way until you tap the alt key once to unstuck it. Signed-off-by: Gerd Hoffmann --- ui/vnc.c | 25 +++++++++++++++++++++++++ 1 files changed, 25 insertions(+), 0 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index 83a9b15..02b71bc 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -46,6 +46,7 @@ static VncDisplay *vnc_display; /* needed for info vnc */ static DisplayChangeListener *dcl; static int vnc_cursor_define(VncState *vs); +static void vnc_release_modifiers(VncState *vs); static void vnc_set_share_mode(VncState *vs, VncShareMode mode) { @@ -1051,6 +1052,7 @@ static void vnc_disconnect_finish(VncState *vs) vnc_sasl_client_cleanup(vs); #endif /* CONFIG_VNC_SASL */ audio_del(vs); + vnc_release_modifiers(vs); QTAILQ_REMOVE(&vs->vd->clients, vs, next); @@ -1679,6 +1681,29 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym) } } +static void vnc_release_modifiers(VncState *vs) +{ + static const int keycodes[] = { + /* shift, control, alt keys, both left & right */ + 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8, + }; + int i, keycode; + + if (!is_graphic_console()) { + return; + } + for (i = 0; i < ARRAY_SIZE(keycodes); i++) { + keycode = keycodes[i]; + if (!vs->modifiers_state[keycode]) { + continue; + } + if (keycode & SCANCODE_GREY) { + kbd_put_keycode(SCANCODE_EMUL0); + } + kbd_put_keycode(keycode | SCANCODE_UP); + } +} + static void key_event(VncState *vs, int down, uint32_t sym) { int keycode; -- 1.7.1