From nobody Mon Feb 9 02:12:23 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1549364324794787.2689275122129; Tue, 5 Feb 2019 02:58:44 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B8E3CC01DE09; Tue, 5 Feb 2019 10:58:42 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 351D718A5A; Tue, 5 Feb 2019 10:58:42 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id CD96518033A5; Tue, 5 Feb 2019 10:58:41 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x15Aw7n4025091 for ; Tue, 5 Feb 2019 05:58:07 -0500 Received: by smtp.corp.redhat.com (Postfix) id CADB11048116; Tue, 5 Feb 2019 10:58:07 +0000 (UTC) Received: from sirius.home.kraxel.org (ovpn-116-249.ams2.redhat.com [10.36.116.249]) by smtp.corp.redhat.com (Postfix) with ESMTP id 45C721055009; Tue, 5 Feb 2019 10:58:07 +0000 (UTC) Received: by sirius.home.kraxel.org (Postfix, from userid 1000) id 511A07853; Tue, 5 Feb 2019 11:57:59 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Tue, 5 Feb 2019 11:57:58 +0100 Message-Id: <20190205105758.4230-15-kraxel@redhat.com> In-Reply-To: <20190205105758.4230-1-kraxel@redhat.com> References: <20190205105758.4230-1-kraxel@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-loop: libvir-list@redhat.com Cc: libvir-list@redhat.com, Paolo Bonzini , Gerd Hoffmann , Peter Maydell Subject: [libvirt] [PULL 14/14] keymap: fix keyup mappings X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Tue, 05 Feb 2019 10:58:43 +0000 (UTC) It is possible that the modifier state on keyup is different from the modifier state on keydown. In that case the keycode lookup can end up with different keys in case multiple keysym -> keycode mappings exist, because it picks the mapping depending on modifier state. To fix that change the lookup logic for keyup events. Instead of looking at the modifier state check the key state and prefer a keycodes where the key is in "down" state right now. Fixes: abb4f2c965 keymap: consider modifier state when picking a mapping Buglink: https://bugs.launchpad.net/bugs/1738283 Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=3D1658676 Signed-off-by: Gerd Hoffmann Reviewed-by: Daniel P. Berrang=C3=A9 Message-id: 20190122092814.14919-9-kraxel@redhat.com --- ui/keymaps.h | 2 +- ui/curses.c | 2 +- ui/keymaps.c | 55 ++++++++++++++++++++++++++++++++++--------------------- ui/vnc.c | 2 +- 4 files changed, 37 insertions(+), 24 deletions(-) diff --git a/ui/keymaps.h b/ui/keymaps.h index d8652b8a5a..b6d48aac40 100644 --- a/ui/keymaps.h +++ b/ui/keymaps.h @@ -56,7 +56,7 @@ typedef struct kbd_layout_t kbd_layout_t; kbd_layout_t *init_keyboard_layout(const name2keysym_t *table, const char *language, Error **errp); int keysym2scancode(kbd_layout_t *k, int keysym, - QKbdState *kbd); + QKbdState *kbd, bool down); int keycode_is_keypad(kbd_layout_t *k, int keycode); int keysym_is_numlock(kbd_layout_t *k, int keysym); =20 diff --git a/ui/curses.c b/ui/curses.c index 54687589d4..6e0091c3b2 100644 --- a/ui/curses.c +++ b/ui/curses.c @@ -273,7 +273,7 @@ static void curses_refresh(DisplayChangeListener *dcl) } =20 keycode =3D keysym2scancode(kbd_layout, keysym & KEYSYM_MASK, - NULL); + NULL, false); if (keycode =3D=3D 0) continue; =20 diff --git a/ui/keymaps.c b/ui/keymaps.c index c8b2135340..544b55c27b 100644 --- a/ui/keymaps.c +++ b/ui/keymaps.c @@ -28,6 +28,7 @@ #include "trace.h" #include "qemu/error-report.h" #include "qapi/error.h" +#include "ui/input.h" =20 struct keysym2code { uint32_t count; @@ -188,7 +189,7 @@ kbd_layout_t *init_keyboard_layout(const name2keysym_t = *table, =20 =20 int keysym2scancode(kbd_layout_t *k, int keysym, - QKbdState *kbd) + QKbdState *kbd, bool down) { static const uint32_t mask =3D SCANCODE_SHIFT | SCANCODE_ALTGR | SCANCODE_CTRL; @@ -212,27 +213,39 @@ int keysym2scancode(kbd_layout_t *k, int keysym, return keysym2code->keycodes[0]; } =20 - /* - * We have multiple keysym -> keycode mappings. - * - * Check whenever we find one mapping where the modifier state of - * the mapping matches the current user interface modifier state. - * If so, prefer that one. - */ - mods =3D 0; - if (kbd && qkbd_state_modifier_get(kbd, QKBD_MOD_SHIFT)) { - mods |=3D SCANCODE_SHIFT; - } - if (kbd && qkbd_state_modifier_get(kbd, QKBD_MOD_ALTGR)) { - mods |=3D SCANCODE_ALTGR; - } - if (kbd && qkbd_state_modifier_get(kbd, QKBD_MOD_CTRL)) { - mods |=3D SCANCODE_CTRL; - } + /* We have multiple keysym -> keycode mappings. */ + if (down) { + /* + * On keydown: Check whenever we find one mapping where the + * modifier state of the mapping matches the current user + * interface modifier state. If so, prefer that one. + */ + mods =3D 0; + if (kbd && qkbd_state_modifier_get(kbd, QKBD_MOD_SHIFT)) { + mods |=3D SCANCODE_SHIFT; + } + if (kbd && qkbd_state_modifier_get(kbd, QKBD_MOD_ALTGR)) { + mods |=3D SCANCODE_ALTGR; + } + if (kbd && qkbd_state_modifier_get(kbd, QKBD_MOD_CTRL)) { + mods |=3D SCANCODE_CTRL; + } =20 - for (i =3D 0; i < keysym2code->count; i++) { - if ((keysym2code->keycodes[i] & mask) =3D=3D mods) { - return keysym2code->keycodes[i]; + for (i =3D 0; i < keysym2code->count; i++) { + if ((keysym2code->keycodes[i] & mask) =3D=3D mods) { + return keysym2code->keycodes[i]; + } + } + } else { + /* + * On keyup: Try find a key which is actually down. + */ + for (i =3D 0; i < keysym2code->count; i++) { + QKeyCode qcode =3D qemu_input_key_number_to_qcode + (keysym2code->keycodes[i]); + if (kbd && qkbd_state_key_get(kbd, qcode)) { + return keysym2code->keycodes[i]; + } } } return keysym2code->keycodes[0]; diff --git a/ui/vnc.c b/ui/vnc.c index f66ed53094..0fef646fc4 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -1981,7 +1981,7 @@ static void key_event(VncState *vs, int down, uint32_= t sym) } =20 keycode =3D keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF, - vs->vd->kbd) & SCANCODE_KEYMASK; + vs->vd->kbd, down) & SCANCODE_KEYMASK; trace_vnc_key_event_map(down, sym, keycode, code2name(keycode)); do_key_event(vs, down, keycode, sym); } --=20 2.9.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list