#898772 qemu: Keys get "stuck" when window loses focus

Package:
src:qemu
Source:
qemu
Submitter:
Benjamin Moody
Date:
2022-04-24 08:21:03 UTC
Severity:
normal
Tags:
#898772#5
Date:
2018-05-15 18:41:53 UTC
From:
To:
Dear Maintainer,

when running qemu in the default graphical mode, it does not correctly
handle what happens when the window loses keyboard focus.

For example:

 * The window manager is configured to switch focus when Super+Tab is
   pressed.

 * A qemu window is focused.

 * I press Super; a KeyPress event is sent to qemu, and the
   corresponding keycode is sent to the guest OS.

 * I press Tab, which is grabbed by the window manager; the WM
   switches focus to another window.

 * I release both keys; the KeyRelease events are now delivered to
   that other window, and not to qemu.

 * The guest OS still believes the Super key is pressed, and will
   continue to believe so until I re-focus the qemu window, and press
   and release Super while the window is focused.

The result can be quite frustrating because qemu doesn't give any
visual indication of what keys it believes are currently pressed, and
in most cases neither does the guest OS.  Fixing the problem requires
the user to realize what has happened (which isn't obvious) and then
to press keys one at a time until they become un-wedged.


It appears that qemu will actually keep track of which "modifier" keys
are pressed, and automatically release *those* particular keys when
the window loses focus.  However:

 - It is limited to left and right Shift, Control, and Alt.

 - It is based on qemu's idea of what physical keycodes correspond to
   modifiers, which may have nothing to do with what keys are actually
   mapped as X modifiers.

 - There's no particular reason that the underlying problem is limited
   to modifiers in the first place (there are plenty of other ways
   that the window can lose focus while one or more keys are pressed.)


Below is a patch to fix this behavior for the SDL interface used in
stretch.

It looks like the latest version of the package, in unstable, has
removed the SDL interface in favor of GTK+.  I haven't tested it, but
from a quick skim of the source, it appears that the GTK+ interface
will have the same problem (see gd_key_event() and
gtk_release_modifiers() in ui/gtk.c.)
--- qemu-2.8+dfsg.orig/ui/sdl.c
+++ qemu-2.8+dfsg/ui/sdl.c
@@ -328,17 +328,6 @@ static void sdl_process_key(SDL_Keyboard
         /* sent when leaving window: reset the modifiers state */
         reset_keys();
         return;
-    case 0x2a:                          /* Left Shift */
-    case 0x36:                          /* Right Shift */
-    case 0x1d:                          /* Left CTRL */
-    case 0x9d:                          /* Right CTRL */
-    case 0x38:                          /* Left ALT */
-    case 0xb8:                         /* Right ALT */
-        if (ev->type == SDL_KEYUP)
-            modifiers_state[keycode] = 0;
-        else
-            modifiers_state[keycode] = 1;
-        break;
 #define QEMU_SDL_VERSION ((SDL_MAJOR_VERSION << 8) + SDL_MINOR_VERSION)
 #if QEMU_SDL_VERSION < 0x102 || QEMU_SDL_VERSION == 0x102 && SDL_PATCHLEVEL < 14
         /* SDL versions before 1.2.14 don't support key up for caps/num lock. */
@@ -351,6 +340,12 @@ static void sdl_process_key(SDL_Keyboard
 #endif
     }

+    assert(keycode >= 0 && keycode < ARRAY_SIZE(modifiers_state));
+    if (ev->type == SDL_KEYUP)
+        modifiers_state[keycode] = 0;
+    else
+        modifiers_state[keycode] = 1;
+
     /* now send the key code */
     qemu_input_event_send_key_number(dcl->con, keycode,
                                      ev->type == SDL_KEYDOWN);

#898772#10
Date:
2019-02-26 23:18:19 UTC
From:
To:
This bug does affect qemu 1:3.1+dfsg-4, except that the list of
known modifier keys is expanded to include "META_L" and "META_R".
The issue is thus somewhat less severe but still present.

An easy way to see the problem is that if a qemu window is
focused, and the user holds down the "G" key while pressing
Super+Tab, the guest OS will continue to believe that "G" is
pressed even after the window loses focus.

Here is a patch to fix this issue for qemu 3.1:
--- qemu-3.1+dfsg.orig/ui/gtk.c
+++ qemu-3.1+dfsg/ui/gtk.c
@@ -122,17 +122,6 @@

 #define HOTKEY_MODIFIERS        (GDK_CONTROL_MASK | GDK_MOD1_MASK)

#898772#17
Date:
2022-04-24 08:16:36 UTC
From:
To:
Control: tag -1 + moreinfo - patch

Hi Benjamin!

Just come across this your bugreport against qemu 3.1.
It looks like this bugreport received no love at all.
I guess it is because such things are better be addressed upstream,
not to debian, - so everyone will benefit from the changes.  Did
you try bringing this upstream?  Is it still a problem with current
qemu (6.2 or 7.0)?  It looks like the patch does not apply to the
current qemu, and they removed modifier_keycode[] definition too.

Thanks,

/mjt