qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v3 5/5] keymap: consider modifier state when pic


From: Daniel P . Berrangé
Subject: Re: [Qemu-devel] [PATCH v3 5/5] keymap: consider modifier state when picking a mapping
Date: Tue, 18 Dec 2018 18:45:32 +0000
User-agent: Mutt/1.10.1 (2018-07-13)


On Thu, Feb 22, 2018 at 08:05:13AM +0100, Gerd Hoffmann wrote:
> Pass the modifier state to the keymap lookup function.  In case multiple
> keysym -> keycode mappings exist look at the modifier state and prefer
> the mapping where the modifier state matches.
> 
> Signed-off-by: Gerd Hoffmann <address@hidden>
> Reviewed-by: Daniel P. Berrangé <address@hidden>
> ---
>  ui/keymaps.h |  3 ++-
>  ui/curses.c  |  3 ++-
>  ui/keymaps.c | 33 ++++++++++++++++++++++++++++++++-
>  ui/sdl.c     |  6 +++++-
>  ui/vnc.c     |  9 +++++++--
>  5 files changed, 48 insertions(+), 6 deletions(-)

[snip]

> diff --git a/ui/vnc.c b/ui/vnc.c
> index a77b568b57..d19f86c7f4 100644
> --- a/ui/vnc.c
> +++ b/ui/vnc.c
> @@ -1734,7 +1734,8 @@ static void reset_keys(VncState *vs)
>  
>  static void press_key(VncState *vs, int keysym)
>  {
> -    int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & 
> SCANCODE_KEYMASK;
> +    int keycode = keysym2scancode(vs->vd->kbd_layout, keysym,
> +                                  false, false, false) & SCANCODE_KEYMASK;
>      qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
>      qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
>      qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
> @@ -1993,6 +1994,9 @@ static const char *code2name(int keycode)
>  
>  static void key_event(VncState *vs, int down, uint32_t sym)
>  {
> +    bool shift = vs->modifiers_state[0x2a] || vs->modifiers_state[0x36];
> +    bool altgr = vs->modifiers_state[0xb8];
> +    bool ctrl  = vs->modifiers_state[0x1d] || vs->modifiers_state[0x9d];
>      int keycode;
>      int lsym = sym;
>  
> @@ -2000,7 +2004,8 @@ static void key_event(VncState *vs, int down, uint32_t 
> sym)
>          lsym = lsym - 'A' + 'a';
>      }
>  
> -    keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & 
> SCANCODE_KEYMASK;
> +    keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF,
> +                              shift, altgr, ctrl) & SCANCODE_KEYMASK;
>      trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
>      do_key_event(vs, down, keycode, sym);
>  }

It looks like this patch is causing some buggy input handling behaviour
with VNC (and probably SDL though I didn't test)


Consider the user wants to type a "<" character.  There are two valid
key sequences for this

 down  0xffe1      (shift)
 down  0x3c        (dot)
 up    0x3c        (dot)
 up    0xffe1      (shift)

Or

 down  0xffe1      (shift)
 down  0x3c        (dot)
 up    0xffe1      (shift)
 up    0x3c        (dot)


With the original code, the "dot" character would be intepreted the
same way in both sequences.

With this patch applied, the "dot", the second sequence is broken.
The "dot" character is interpreted with no modifiers on down, and
interpreted with the shift modifier on release. This is then causing
QEMU to see a different QKeyCode on down vs up.

The trace events show the problem:

Before this patch, the two sequences show:

  address@hidden:vnc_key_event_map down 1, sym 0xffe1 -> keycode 0x2a [shift]
  address@hidden:vnc_key_event_map down 1, sym 0x3c -> keycode 0x56 [less]
  address@hidden:vnc_key_event_map down 0, sym 0x3c -> keycode 0x56 [less]
  address@hidden:vnc_key_event_map down 0, sym 0xffe1 -> keycode 0x2a [shift]

  address@hidden:vnc_key_event_map down 1, sym 0xffe1 -> keycode 0x2a [shift]
  address@hidden:vnc_key_event_map down 1, sym 0x3c -> keycode 0x56 [less]
  address@hidden:vnc_key_event_map down 0, sym 0xffe1 -> keycode 0x2a [shift]
  address@hidden:vnc_key_event_map down 0, sym 0x3c -> keycode 0x56 [less]

IOW, in both sequences we have matched pairs of events


After this patch the two sequences now show:

  address@hidden:vnc_key_event_map down 1, sym 0xffe1 -> keycode 0x2a [shift]
  address@hidden:vnc_key_event_map down 1, sym 0x3c -> keycode 0x33 [comma]
  address@hidden:vnc_key_event_map down 0, sym 0x3c -> keycode 0x33 [comma]
  address@hidden:vnc_key_event_map down 0, sym 0xffe1 -> keycode 0x2a [shift]

  address@hidden:vnc_key_event_map down 1, sym 0xffe1 -> keycode 0x2a [shift]
  address@hidden:vnc_key_event_map down 1, sym 0x3c -> keycode 0x33 [comma]
  address@hidden:vnc_key_event_map down 0, sym 0xffe1 -> keycode 0x2a [shift]
  address@hidden:vnc_key_event_map down 0, sym 0x3c -> keycode 0x56 [less]

Notice how we sent a "down(comma)" and paired it with an "up(less)". This
causes the guest to consider the key stuck down, so next time you type
a "<" it will get lost.

This is easily reproduced with gtk-vnc and the following QEMU command
line:

  ./x86_64-softmmu/qemu-system-x86_64 -vnc :1 -d trace:vnc* 


I don't see any nice way to fix the problem without having to keep a
memory of modifier state with every "down" event, so you can use the
same modifier state with the later "up" event to ensure you get a
matching key up.  This is quite horrible though. I'm more inclined
to revert this patch and find another way to fix the original problem
which won't require the UI frontends to track modifier state.

This problem is reported in

  https://bugs.launchpad.net/bugs/1738283
  https://bugzilla.redhat.com/show_bug.cgi?id=1658676

Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



reply via email to

[Prev in Thread] Current Thread [Next in Thread]