Source: qemu Version: 1:2.8+dfsg-6+deb9u3 Severity: normal Tags: patch 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); -- System Information: Debian Release: 9.4 APT prefers stable APT policy: (990, 'stable'), (500, 'stable-updates'), (500, 'stable-debug') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 4.9.0-6-amd64 (SMP w/40 CPU cores) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system)