From: Gerd Hoffmann <kraxel@redhat.com>
To: qemu-devel@nongnu.org
Cc: berrange@redhat.com, Gerd Hoffmann <kraxel@redhat.com>
Subject: [Qemu-devel] [RFC PATCH v3 8/8] keymap: fix keyup mappings
Date: Tue, 22 Jan 2019 10:28:14 +0100 [thread overview]
Message-ID: <20190122092814.14919-9-kraxel@redhat.com> (raw)
In-Reply-To: <20190122092814.14919-1-kraxel@redhat.com>
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=1658676
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@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);
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)
}
keycode = keysym2scancode(kbd_layout, keysym & KEYSYM_MASK,
- NULL);
+ NULL, false);
if (keycode == 0)
continue;
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"
struct keysym2code {
uint32_t count;
@@ -188,7 +189,7 @@ kbd_layout_t *init_keyboard_layout(const name2keysym_t *table,
int keysym2scancode(kbd_layout_t *k, int keysym,
- QKbdState *kbd)
+ QKbdState *kbd, bool down)
{
static const uint32_t mask =
SCANCODE_SHIFT | SCANCODE_ALTGR | SCANCODE_CTRL;
@@ -212,27 +213,39 @@ int keysym2scancode(kbd_layout_t *k, int keysym,
return keysym2code->keycodes[0];
}
- /*
- * 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 = 0;
- if (kbd && qkbd_state_modifier_get(kbd, QKBD_MOD_SHIFT)) {
- mods |= SCANCODE_SHIFT;
- }
- if (kbd && qkbd_state_modifier_get(kbd, QKBD_MOD_ALTGR)) {
- mods |= SCANCODE_ALTGR;
- }
- if (kbd && qkbd_state_modifier_get(kbd, QKBD_MOD_CTRL)) {
- mods |= 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 = 0;
+ if (kbd && qkbd_state_modifier_get(kbd, QKBD_MOD_SHIFT)) {
+ mods |= SCANCODE_SHIFT;
+ }
+ if (kbd && qkbd_state_modifier_get(kbd, QKBD_MOD_ALTGR)) {
+ mods |= SCANCODE_ALTGR;
+ }
+ if (kbd && qkbd_state_modifier_get(kbd, QKBD_MOD_CTRL)) {
+ mods |= SCANCODE_CTRL;
+ }
- for (i = 0; i < keysym2code->count; i++) {
- if ((keysym2code->keycodes[i] & mask) == mods) {
- return keysym2code->keycodes[i];
+ for (i = 0; i < keysym2code->count; i++) {
+ if ((keysym2code->keycodes[i] & mask) == mods) {
+ return keysym2code->keycodes[i];
+ }
+ }
+ } else {
+ /*
+ * On keyup: Try find a key which is actually down.
+ */
+ for (i = 0; i < keysym2code->count; i++) {
+ QKeyCode qcode = 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 fc41f9b318..bc730496ae 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -1962,7 +1962,7 @@ static void key_event(VncState *vs, int down, uint32_t sym)
}
keycode = 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);
}
--
2.9.3
prev parent reply other threads:[~2019-01-22 9:38 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-01-22 9:28 [Qemu-devel] [RFC PATCH v3 0/8] ui: add generic keyboard state tracker, fix keymap Gerd Hoffmann
2019-01-22 9:28 ` [Qemu-devel] [RFC PATCH v3 1/8] kbd-state: add keyboard state tracker Gerd Hoffmann
2019-01-22 9:47 ` Daniel P. Berrangé
2019-01-22 9:28 ` [Qemu-devel] [RFC PATCH v3 2/8] sdl2: remove sdl2_reset_keys() function Gerd Hoffmann
2019-01-22 9:28 ` [Qemu-devel] [RFC PATCH v3 3/8] kbd-state: use state tracker for sdl2 Gerd Hoffmann
2019-01-22 9:28 ` [Qemu-devel] [RFC PATCH v3 4/8] sdl2: use only QKeyCode in sdl2_process_key() Gerd Hoffmann
2019-01-22 9:28 ` [Qemu-devel] [RFC PATCH v3 5/8] kbd-state: use state tracker for gtk Gerd Hoffmann
2019-01-22 9:28 ` [Qemu-devel] [RFC PATCH v3 6/8] kbd-state: use state tracker for vnc Gerd Hoffmann
2019-01-22 9:47 ` Daniel P. Berrangé
2019-01-22 9:28 ` [Qemu-devel] [RFC PATCH v3 7/8] keymap: pass full keyboard state to keysym2scancode Gerd Hoffmann
2019-01-22 9:28 ` Gerd Hoffmann [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190122092814.14919-9-kraxel@redhat.com \
--to=kraxel@redhat.com \
--cc=berrange@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).