aboutsummaryrefslogtreecommitdiff
path: root/ui/sdl2.c
diff options
context:
space:
mode:
authorJindrich Makovicka <makovick@gmail.com>2017-11-17 12:22:58 +0100
committerGerd Hoffmann <kraxel@redhat.com>2018-01-12 15:51:18 +0100
commit849bbe60356caf3d320202d45f1ddffeefae06c7 (patch)
tree6c6b9c2ea858efebef6969a0fd477b114d325b9c /ui/sdl2.c
parentd9f0626280fb5224071415e6fd82cc0c2e9d6590 (diff)
sdl2: Ignore UI hotkeys after a focus change when GUI modifier is held
When SDL2 windows change focus while a key is held, the window that receives the focus also receives a new KeyDown event, without an autorepeat flag. This means that if a WM places the qemu console over the main window after Ctrl-Alt-2, the console closes immediately after opening. Then, the main window receives the KeyDown event again and the whole process repeats. This patch makes the SDL2 UI ignore the KeyDown events on a window that just received the focus, if the GUI modifier was held. The ignore flag is reset on a first KeyUp event. This effectively works around the issue above. Signed-off-by: Jindrich Makovicka <makovick@gmail.com> Message-Id: <20171117112258.5888-4-makovick@gmail.com> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'ui/sdl2.c')
-rw-r--r--ui/sdl2.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/ui/sdl2.c b/ui/sdl2.c
index 8a0bd9149b..89c6a2633c 100644
--- a/ui/sdl2.c
+++ b/ui/sdl2.c
@@ -312,22 +312,28 @@ static void toggle_full_screen(struct sdl2_console *scon)
sdl2_redraw(scon);
}
-static void handle_keydown(SDL_Event *ev)
+static int get_mod_state(void)
{
- int mod_state, win;
- struct sdl2_console *scon = get_scon_from_window(ev->key.windowID);
+ SDL_Keymod mod = SDL_GetModState();
if (alt_grab) {
- mod_state = (SDL_GetModState() & (gui_grab_code | KMOD_LSHIFT)) ==
+ return (mod & (gui_grab_code | KMOD_LSHIFT)) ==
(gui_grab_code | KMOD_LSHIFT);
} else if (ctrl_grab) {
- mod_state = (SDL_GetModState() & KMOD_RCTRL) == KMOD_RCTRL;
+ return (mod & KMOD_RCTRL) == KMOD_RCTRL;
} else {
- mod_state = (SDL_GetModState() & gui_grab_code) == gui_grab_code;
+ return (mod & gui_grab_code) == gui_grab_code;
}
- gui_key_modifier_pressed = mod_state;
+}
- if (gui_key_modifier_pressed) {
+static void handle_keydown(SDL_Event *ev)
+{
+ int win;
+ struct sdl2_console *scon = get_scon_from_window(ev->key.windowID);
+
+ gui_key_modifier_pressed = get_mod_state();
+
+ if (!scon->ignore_hotkeys && gui_key_modifier_pressed && !ev->key.repeat) {
switch (ev->key.keysym.scancode) {
case SDL_SCANCODE_2:
case SDL_SCANCODE_3:
@@ -401,6 +407,8 @@ static void handle_keyup(SDL_Event *ev)
int mod_state;
struct sdl2_console *scon = get_scon_from_window(ev->key.windowID);
+ scon->ignore_hotkeys = false;
+
if (!alt_grab) {
mod_state = (ev->key.keysym.mod & gui_grab_code);
} else {
@@ -547,6 +555,14 @@ static void handle_windowevent(SDL_Event *ev)
if (!gui_grab && (qemu_input_is_absolute() || absolute_enabled)) {
absolute_mouse_grab(scon);
}
+ /* If a new console window opened using a hotkey receives the
+ * focus, SDL sends another KEYDOWN event to the new window,
+ * closing the console window immediately after.
+ *
+ * Work around this by ignoring further hotkey events until a
+ * key is released.
+ */
+ scon->ignore_hotkeys = get_mod_state();
break;
case SDL_WINDOWEVENT_FOCUS_LOST:
if (gui_grab && !gui_fullscreen) {