Changeset
configure                  |  6 ++++
include/ui/sdl2.h          |  1 +
include/ui/spice-display.h |  1 -
hw/display/qxl.c           |  1 -
ui/gtk.c                   |  5 +++
ui/input.c                 |  2 ++
ui/sdl2.c                  | 79 ++++++++++++++++++++++++++--------------------
ui/spice-core.c            | 14 ++------
ui/spice-display.c         |  2 --
qemu-doc.texi              |  9 ++++++
10 files changed, 70 insertions(+), 50 deletions(-)
Git apply log
Switched to a new branch '20180112145258.10578-1-kraxel@redhat.com'
Applying: input: fix memory leak
Applying: ui: deprecate use of GTK 2.x in favour of 3.x series
Applying: spice: remove QXLWorker interface field
Applying: spice: remove unused watch list
Applying: spice: remove only written event_mask field
Applying: spice: remove unused timer list
Applying: sdl2: Do not hide the cursor on auxilliary windows
Applying: sdl2 uses surface relative coordinates
Applying: sdl2: Ignore UI hotkeys after a focus change when GUI modifier is held
To https://github.com/patchew-project/qemu
 * [new tag]               patchew/20180112145258.10578-1-kraxel@redhat.com -> patchew/20180112145258.10578-1-kraxel@redhat.com
Test passed: docker

loading

Test passed: checkpatch

loading

Test passed: s390x

loading

Test passed: ppc

loading

[Qemu-devel] [PULL 0/9] Ui 20180112 patches
Posted by Gerd Hoffmann, 23 weeks ago
The following changes since commit 997eba28a3ed5400a80f754bf3a1c8044b75b9ff:

  Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20180111' into staging (2018-01-11 14:34:41 +0000)

are available in the git repository at:

  git://git.kraxel.org/qemu tags/ui-20180112-pull-request

for you to fetch changes up to 849bbe60356caf3d320202d45f1ddffeefae06c7:

  sdl2: Ignore UI hotkeys after a focus change when GUI modifier is held (2018-01-12 15:51:18 +0100)

----------------------------------------------------------------
sdl2: bugfixes.
spice: cleanups.
input: mem leak fix.
gtk: deprecate 2.x support.

----------------------------------------------------------------

Daniel P. Berrange (1):
  ui: deprecate use of GTK 2.x in favour of 3.x series

Frediano Ziglio (4):
  spice: remove QXLWorker interface field
  spice: remove unused watch list
  spice: remove only written event_mask field
  spice: remove unused timer list

Jindrich Makovicka (3):
  sdl2: Do not hide the cursor on auxilliary windows
  sdl2 uses surface relative coordinates
  sdl2: Ignore UI hotkeys after a focus change when GUI modifier is held

linzhecheng (1):
  input: fix memory leak

 configure                  |  6 ++++
 include/ui/sdl2.h          |  1 +
 include/ui/spice-display.h |  1 -
 hw/display/qxl.c           |  1 -
 ui/gtk.c                   |  5 +++
 ui/input.c                 |  2 ++
 ui/sdl2.c                  | 79 ++++++++++++++++++++++++++--------------------
 ui/spice-core.c            | 14 ++------
 ui/spice-display.c         |  2 --
 qemu-doc.texi              |  9 ++++++
 10 files changed, 70 insertions(+), 50 deletions(-)

-- 
2.9.3


Re: [Qemu-devel] [PULL 0/9] Ui 20180112 patches
Posted by Peter Maydell, 22 weeks ago
On 12 January 2018 at 14:52, Gerd Hoffmann <kraxel@redhat.com> wrote:
> The following changes since commit 997eba28a3ed5400a80f754bf3a1c8044b75b9ff:
>
>   Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20180111' into staging (2018-01-11 14:34:41 +0000)
>
> are available in the git repository at:
>
>   git://git.kraxel.org/qemu tags/ui-20180112-pull-request
>
> for you to fetch changes up to 849bbe60356caf3d320202d45f1ddffeefae06c7:
>
>   sdl2: Ignore UI hotkeys after a focus change when GUI modifier is held (2018-01-12 15:51:18 +0100)
>
> ----------------------------------------------------------------
> sdl2: bugfixes.
> spice: cleanups.
> input: mem leak fix.
> gtk: deprecate 2.x support.
>

Applied, thanks.

Please can you add some text to the "Build Dependencies" section
of the changelog for the GTK2 deprecation?
 https://wiki.qemu.org/index.php?title=ChangeLog/2.12

-- PMM

[Qemu-devel] [PULL 1/9] input: fix memory leak
Posted by Gerd Hoffmann, 23 weeks ago
From: linzhecheng <linzhecheng@huawei.com>

If kbd_queue is not empty and queue_count >= queue_limit,
we should free evt.

Change-Id: Ieeacf90d5e7e370a40452ec79031912d8b864d83
Signed-off-by: linzhecheng <linzhecheng@huawei.com>
Message-id: 20171225023730.5512-1-linzhecheng@huawei.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/input.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/ui/input.c b/ui/input.c
index 3e2d324278..e5b78aae9e 100644
--- a/ui/input.c
+++ b/ui/input.c
@@ -421,6 +421,8 @@ void qemu_input_event_send_key(QemuConsole *src, KeyValue *key, bool down)
     } else if (queue_count < queue_limit) {
         qemu_input_queue_event(&kbd_queue, src, evt);
         qemu_input_queue_sync(&kbd_queue);
+    } else {
+        qapi_free_InputEvent(evt);
     }
 }
 
-- 
2.9.3


[Qemu-devel] [PULL 2/9] ui: deprecate use of GTK 2.x in favour of 3.x series
Posted by Gerd Hoffmann, 23 weeks ago
From: "Daniel P. Berrange" <berrange@redhat.com>

The GTK 3.0 release was made in Feb, 2011:

  https://blog.gtk.org/2011/02/10/gtk-3-0-released/

That will soon be 7 years ago, which is enough time to consider
the 3.x series widely supported.

Thus we deprecate the GTK 2.x support, which will allow us to
delete it in the last release of 2018. By this time, GTK 3.x
will be almost 8 years old.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Message-id: 20171212113440.16483-1-berrange@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 configure     | 6 ++++++
 ui/gtk.c      | 5 +++++
 qemu-doc.texi | 9 +++++++++
 3 files changed, 20 insertions(+)

diff --git a/configure b/configure
index 89bd662a6a..b272a0336b 100755
--- a/configure
+++ b/configure
@@ -5629,6 +5629,12 @@ if test "$sdl_too_old" = "yes"; then
 echo "-> Your SDL version is too old - please upgrade to have SDL support"
 fi
 
+if test "$gtkabi" = "2.0"; then
+    echo
+    echo "WARNING: Use of GTK 2.0 is deprecated and will be removed in"
+    echo "WARNING: future releases. Please switch to using GTK 3.0"
+fi
+
 if test "$supported_cpu" = "no"; then
     echo
     echo "WARNING: SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!"
diff --git a/ui/gtk.c b/ui/gtk.c
index 342e96fbe9..f3b7567984 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -2248,6 +2248,11 @@ void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover)
         exit(1);
     }
 
+#if !GTK_CHECK_VERSION(3, 0, 0)
+    g_printerr("Running QEMU with GTK 2.x is deprecated, and will be removed\n"
+               "in a future release. Please switch to GTK 3.x instead\n");
+#endif
+
     s->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 #if GTK_CHECK_VERSION(3, 2, 0)
     s->vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
diff --git a/qemu-doc.texi b/qemu-doc.texi
index a3d2054c90..3e9eb819a6 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -2587,6 +2587,15 @@ they were first deprecated in the 2.10.0 release.
 What follows is a list of all features currently marked as
 deprecated.
 
+@section Build options
+
+@subsection GTK 2.x
+
+Previously QEMU has supported building against both GTK 2.x
+and 3.x series APIs. Support for the GTK 2.x builds will be
+discontinued, so maintainers should switch to using GTK 3.x,
+which is the default.
+
 @section System emulator command line arguments
 
 @subsection -tdf (since 1.3.0)
-- 
2.9.3


[Qemu-devel] [PULL 3/9] spice: remove QXLWorker interface field
Posted by Gerd Hoffmann, 23 weeks ago
From: Frediano Ziglio <fziglio@redhat.com>

This fields points to an old interface that is no more
used in the current code.

Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Message-id: 20171122135625.16625-1-fziglio@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/spice-display.h | 1 -
 hw/display/qxl.c           | 1 -
 ui/spice-display.c         | 2 --
 3 files changed, 4 deletions(-)

diff --git a/include/ui/spice-display.h b/include/ui/spice-display.h
index aaf2019889..6b5c73b21c 100644
--- a/include/ui/spice-display.h
+++ b/include/ui/spice-display.h
@@ -86,7 +86,6 @@ struct SimpleSpiceDisplay {
     DisplayChangeListener dcl;
     void *buf;
     int bufsize;
-    QXLWorker *worker;
     QXLInstance qxl;
     uint32_t unique;
     pixman_image_t *surface;
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index 99365c3e8f..b9fa067f6e 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -518,7 +518,6 @@ static void interface_attach_worker(QXLInstance *sin, QXLWorker *qxl_worker)
     PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
 
     trace_qxl_interface_attach_worker(qxl->id);
-    qxl->ssd.worker = qxl_worker;
 }
 
 static void interface_set_compression_level(QXLInstance *sin, int level)
diff --git a/ui/spice-display.c b/ui/spice-display.c
index ad1ceafb3f..85a72fe76a 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -519,7 +519,6 @@ static void interface_attach_worker(QXLInstance *sin, QXLWorker *qxl_worker)
     SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
 
     dprint(1, "%s/%d:\n", __func__, ssd->qxl.id);
-    ssd->worker = qxl_worker;
 }
 
 static void interface_set_compression_level(QXLInstance *sin, int level)
@@ -1028,7 +1027,6 @@ static void qemu_spice_display_init_one(QemuConsole *con)
 
     ssd->qxl.base.sif = &dpy_interface.base;
     qemu_spice_add_display_interface(&ssd->qxl, con);
-    assert(ssd->worker);
     qemu_spice_create_host_memslot(ssd);
 
     register_displaychangelistener(&ssd->dcl);
-- 
2.9.3


[Qemu-devel] [PULL 4/9] spice: remove unused watch list
Posted by Gerd Hoffmann, 23 weeks ago
From: Frediano Ziglio <fziglio@redhat.com>

Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Message-id: 20171122135625.16625-2-fziglio@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/spice-core.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/ui/spice-core.c b/ui/spice-core.c
index ea04dc69b5..85b9ea2127 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -92,9 +92,7 @@ struct SpiceWatch {
     int event_mask;
     SpiceWatchFunc func;
     void *opaque;
-    QTAILQ_ENTRY(SpiceWatch) next;
 };
-static QTAILQ_HEAD(, SpiceWatch) watches = QTAILQ_HEAD_INITIALIZER(watches);
 
 static void watch_read(void *opaque)
 {
@@ -131,7 +129,6 @@ static SpiceWatch *watch_add(int fd, int event_mask, SpiceWatchFunc func, void *
     watch->fd     = fd;
     watch->func   = func;
     watch->opaque = opaque;
-    QTAILQ_INSERT_TAIL(&watches, watch, next);
 
     watch_update_mask(watch, event_mask);
     return watch;
@@ -140,7 +137,6 @@ static SpiceWatch *watch_add(int fd, int event_mask, SpiceWatchFunc func, void *
 static void watch_remove(SpiceWatch *watch)
 {
     qemu_set_fd_handler(watch->fd, NULL, NULL, NULL);
-    QTAILQ_REMOVE(&watches, watch, next);
     g_free(watch);
 }
 
-- 
2.9.3


[Qemu-devel] [PULL 5/9] spice: remove only written event_mask field
Posted by Gerd Hoffmann, 23 weeks ago
From: Frediano Ziglio <fziglio@redhat.com>

Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Message-id: 20171122135625.16625-3-fziglio@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/spice-core.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/ui/spice-core.c b/ui/spice-core.c
index 85b9ea2127..6d579faaae 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -89,7 +89,6 @@ static void timer_remove(SpiceTimer *timer)
 
 struct SpiceWatch {
     int fd;
-    int event_mask;
     SpiceWatchFunc func;
     void *opaque;
 };
@@ -111,11 +110,10 @@ static void watch_update_mask(SpiceWatch *watch, int event_mask)
     IOHandler *on_read = NULL;
     IOHandler *on_write = NULL;
 
-    watch->event_mask = event_mask;
-    if (watch->event_mask & SPICE_WATCH_EVENT_READ) {
+    if (event_mask & SPICE_WATCH_EVENT_READ) {
         on_read = watch_read;
     }
-    if (watch->event_mask & SPICE_WATCH_EVENT_WRITE) {
+    if (event_mask & SPICE_WATCH_EVENT_WRITE) {
         on_write = watch_write;
     }
     qemu_set_fd_handler(watch->fd, on_read, on_write, watch);
-- 
2.9.3


[Qemu-devel] [PULL 6/9] spice: remove unused timer list
Posted by Gerd Hoffmann, 23 weeks ago
From: Frediano Ziglio <fziglio@redhat.com>

Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Message-id: 20171122135625.16625-4-fziglio@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/spice-core.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/ui/spice-core.c b/ui/spice-core.c
index 6d579faaae..2baf0c7120 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -55,9 +55,7 @@ static QemuThread me;
 
 struct SpiceTimer {
     QEMUTimer *timer;
-    QTAILQ_ENTRY(SpiceTimer) next;
 };
-static QTAILQ_HEAD(, SpiceTimer) timers = QTAILQ_HEAD_INITIALIZER(timers);
 
 static SpiceTimer *timer_add(SpiceTimerFunc func, void *opaque)
 {
@@ -65,7 +63,6 @@ static SpiceTimer *timer_add(SpiceTimerFunc func, void *opaque)
 
     timer = g_malloc0(sizeof(*timer));
     timer->timer = timer_new_ms(QEMU_CLOCK_REALTIME, func, opaque);
-    QTAILQ_INSERT_TAIL(&timers, timer, next);
     return timer;
 }
 
@@ -83,7 +80,6 @@ static void timer_remove(SpiceTimer *timer)
 {
     timer_del(timer->timer);
     timer_free(timer->timer);
-    QTAILQ_REMOVE(&timers, timer, next);
     g_free(timer);
 }
 
-- 
2.9.3


[Qemu-devel] [PULL 7/9] sdl2: Do not hide the cursor on auxilliary windows
Posted by Gerd Hoffmann, 23 weeks ago
From: Jindrich Makovicka <makovick@gmail.com>

Signed-off-by: Jindrich Makovicka <makovick@gmail.com>
Message-Id: <20171117112258.5888-2-makovick@gmail.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/sdl2.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/ui/sdl2.c b/ui/sdl2.c
index 8718cf36b5..62a75318dd 100644
--- a/ui/sdl2.c
+++ b/ui/sdl2.c
@@ -466,6 +466,10 @@ static void handle_mousemotion(SDL_Event *ev)
     int max_x, max_y;
     struct sdl2_console *scon = get_scon_from_window(ev->key.windowID);
 
+    if (!qemu_console_is_graphic(scon->dcl.con)) {
+        return;
+    }
+
     if (qemu_input_is_absolute() || absolute_enabled) {
         int scr_w, scr_h;
         SDL_GetWindowSize(scon->real_window, &scr_w, &scr_h);
@@ -494,6 +498,10 @@ static void handle_mousebutton(SDL_Event *ev)
     SDL_MouseButtonEvent *bev;
     struct sdl2_console *scon = get_scon_from_window(ev->key.windowID);
 
+    if (!qemu_console_is_graphic(scon->dcl.con)) {
+        return;
+    }
+
     bev = &ev->button;
     if (!gui_grab && !qemu_input_is_absolute()) {
         if (ev->type == SDL_MOUSEBUTTONUP && bev->button == SDL_BUTTON_LEFT) {
@@ -516,6 +524,10 @@ static void handle_mousewheel(SDL_Event *ev)
     SDL_MouseWheelEvent *wev = &ev->wheel;
     InputButton btn;
 
+    if (!qemu_console_is_graphic(scon->dcl.con)) {
+        return;
+    }
+
     if (wev->y > 0) {
         btn = INPUT_BUTTON_WHEEL_UP;
     } else if (wev->y < 0) {
@@ -657,6 +669,11 @@ static void sdl_mouse_warp(DisplayChangeListener *dcl,
                            int x, int y, int on)
 {
     struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
+
+    if (!qemu_console_is_graphic(scon->dcl.con)) {
+        return;
+    }
+
     if (on) {
         if (!guest_cursor) {
             sdl_show_cursor();
-- 
2.9.3


[Qemu-devel] [PULL 8/9] sdl2 uses surface relative coordinates
Posted by Gerd Hoffmann, 23 weeks ago
From: Jindrich Makovicka <makovick@gmail.com>

This patch fixes mouse positioning with -device usb-tablet and fullscreen
or resized window.

Fixes: 46522a82236ea0cf9011b89896d2d8f8ddaf2443
Signed-off-by: Jindrich Makovicka <makovick@gmail.com>
Message-Id: <20171117112258.5888-3-makovick@gmail.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/sdl2.c | 30 ++++--------------------------
 1 file changed, 4 insertions(+), 26 deletions(-)

diff --git a/ui/sdl2.c b/ui/sdl2.c
index 62a75318dd..8a0bd9149b 100644
--- a/ui/sdl2.c
+++ b/ui/sdl2.c
@@ -276,32 +276,10 @@ static void sdl_send_mouse_event(struct sdl2_console *scon, int dx, int dy,
     }
 
     if (qemu_input_is_absolute()) {
-        int scr_w, scr_h;
-        int max_w = 0, max_h = 0;
-        int off_x = 0, off_y = 0;
-        int cur_off_x = 0, cur_off_y = 0;
-        int i;
-
-        for (i = 0; i < sdl2_num_outputs; i++) {
-            struct sdl2_console *thiscon = &sdl2_console[i];
-            if (thiscon->real_window && thiscon->surface) {
-                SDL_GetWindowSize(thiscon->real_window, &scr_w, &scr_h);
-                cur_off_x = thiscon->x;
-                cur_off_y = thiscon->y;
-                if (scr_w + cur_off_x > max_w) {
-                    max_w = scr_w + cur_off_x;
-                }
-                if (scr_h + cur_off_y > max_h) {
-                    max_h = scr_h + cur_off_y;
-                }
-                if (i == scon->idx) {
-                    off_x = cur_off_x;
-                    off_y = cur_off_y;
-                }
-            }
-        }
-        qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_X, off_x + x, 0, max_w);
-        qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_Y, off_y + y, 0, max_h);
+        qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_X,
+                             x, 0, surface_width(scon->surface));
+        qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_Y,
+                             y, 0, surface_height(scon->surface));
     } else {
         if (guest_cursor) {
             x -= guest_x;
-- 
2.9.3


[Qemu-devel] [PULL 9/9] sdl2: Ignore UI hotkeys after a focus change when GUI modifier is held
Posted by Gerd Hoffmann, 23 weeks ago
From: Jindrich Makovicka <makovick@gmail.com>

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>
---
 include/ui/sdl2.h |  1 +
 ui/sdl2.c         | 32 ++++++++++++++++++++++++--------
 2 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/include/ui/sdl2.h b/include/ui/sdl2.h
index b29cf803c9..51084e6320 100644
--- a/include/ui/sdl2.h
+++ b/include/ui/sdl2.h
@@ -24,6 +24,7 @@ struct sdl2_console {
     int opengl;
     int updates;
     int idle_counter;
+    int ignore_hotkeys;
     SDL_GLContext winctx;
 #ifdef CONFIG_OPENGL
     QemuGLShader *gls;
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) {
-- 
2.9.3