ui/vnc: Do not use console_select()
console_select() is shared by other displays and a console_select() call from one of them triggers console switching also in ui/curses, circumventing key state reinitialization that needs to be performed in preparation and resulting in stuck keys. Use its internal state to track the current active console to prevent such a surprise console switch. Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20240319-console-v2-2-3fd6feef321a@daynix.com>
This commit is contained in:
parent
271a197425
commit
d4c199566f
@ -413,6 +413,7 @@ void qemu_console_early_init(void);
|
|||||||
|
|
||||||
void qemu_console_set_display_gl_ctx(QemuConsole *con, DisplayGLCtx *ctx);
|
void qemu_console_set_display_gl_ctx(QemuConsole *con, DisplayGLCtx *ctx);
|
||||||
|
|
||||||
|
QemuConsole *qemu_console_lookup_default(void);
|
||||||
QemuConsole *qemu_console_lookup_by_index(unsigned int index);
|
QemuConsole *qemu_console_lookup_by_index(unsigned int index);
|
||||||
QemuConsole *qemu_console_lookup_by_device(DeviceState *dev, uint32_t head);
|
QemuConsole *qemu_console_lookup_by_device(DeviceState *dev, uint32_t head);
|
||||||
QemuConsole *qemu_console_lookup_by_device_name(const char *device_id,
|
QemuConsole *qemu_console_lookup_by_device_name(const char *device_id,
|
||||||
|
@ -99,4 +99,15 @@ bool qkbd_state_modifier_get(QKbdState *kbd, QKbdModifier mod);
|
|||||||
*/
|
*/
|
||||||
void qkbd_state_lift_all_keys(QKbdState *kbd);
|
void qkbd_state_lift_all_keys(QKbdState *kbd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qkbd_state_switch_console: Switch console.
|
||||||
|
*
|
||||||
|
* This sends key up events to the previous console for all keys which are in
|
||||||
|
* down state to prevent keys being stuck, and remembers the new console.
|
||||||
|
*
|
||||||
|
* @kbd: state tracker state.
|
||||||
|
* @con: new QemuConsole for this state tracker.
|
||||||
|
*/
|
||||||
|
void qkbd_state_switch_console(QKbdState *kbd, QemuConsole *con);
|
||||||
|
|
||||||
#endif /* QEMU_UI_KBD_STATE_H */
|
#endif /* QEMU_UI_KBD_STATE_H */
|
||||||
|
12
ui/console.c
12
ui/console.c
@ -1325,6 +1325,18 @@ void graphic_console_close(QemuConsole *con)
|
|||||||
dpy_gfx_replace_surface(con, surface);
|
dpy_gfx_replace_surface(con, surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QemuConsole *qemu_console_lookup_default(void)
|
||||||
|
{
|
||||||
|
QemuConsole *con;
|
||||||
|
|
||||||
|
QTAILQ_FOREACH(con, &consoles, next) {
|
||||||
|
if (QEMU_IS_GRAPHIC_CONSOLE(con)) {
|
||||||
|
return con;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QTAILQ_FIRST(&consoles);
|
||||||
|
}
|
||||||
|
|
||||||
QemuConsole *qemu_console_lookup_by_index(unsigned int index)
|
QemuConsole *qemu_console_lookup_by_index(unsigned int index)
|
||||||
{
|
{
|
||||||
QemuConsole *con;
|
QemuConsole *con;
|
||||||
|
@ -117,6 +117,12 @@ void qkbd_state_lift_all_keys(QKbdState *kbd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void qkbd_state_switch_console(QKbdState *kbd, QemuConsole *con)
|
||||||
|
{
|
||||||
|
qkbd_state_lift_all_keys(kbd);
|
||||||
|
kbd->con = con;
|
||||||
|
}
|
||||||
|
|
||||||
void qkbd_state_set_delay(QKbdState *kbd, int delay_ms)
|
void qkbd_state_set_delay(QKbdState *kbd, int delay_ms)
|
||||||
{
|
{
|
||||||
kbd->key_delay_ms = delay_ms;
|
kbd->key_delay_ms = delay_ms;
|
||||||
|
14
ui/vnc.c
14
ui/vnc.c
@ -1872,12 +1872,16 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym)
|
|||||||
/* QEMU console switch */
|
/* QEMU console switch */
|
||||||
switch (qcode) {
|
switch (qcode) {
|
||||||
case Q_KEY_CODE_1 ... Q_KEY_CODE_9: /* '1' to '9' keys */
|
case Q_KEY_CODE_1 ... Q_KEY_CODE_9: /* '1' to '9' keys */
|
||||||
if (vs->vd->dcl.con == NULL && down &&
|
if (down &&
|
||||||
qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_CTRL) &&
|
qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_CTRL) &&
|
||||||
qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_ALT)) {
|
qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_ALT)) {
|
||||||
/* Reset the modifiers sent to the current console */
|
QemuConsole *con = qemu_console_lookup_by_index(qcode - Q_KEY_CODE_1);
|
||||||
qkbd_state_lift_all_keys(vs->vd->kbd);
|
if (con) {
|
||||||
console_select(qcode - Q_KEY_CODE_1);
|
unregister_displaychangelistener(&vs->vd->dcl);
|
||||||
|
qkbd_state_switch_console(vs->vd->kbd, con);
|
||||||
|
vs->vd->dcl.con = con;
|
||||||
|
register_displaychangelistener(&vs->vd->dcl);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -4206,7 +4210,7 @@ void vnc_display_open(const char *id, Error **errp)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
con = NULL;
|
con = qemu_console_lookup_default();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (con != vd->dcl.con) {
|
if (con != vd->dcl.con) {
|
||||||
|
Loading…
Reference in New Issue
Block a user