ui/cocoa: Do not use console_select()
ui/cocoa needs to update the UI info and reset the keyboard state tracker when switching the console, or the new console will see the stale UI info or keyboard state. Previously, updating the UI info was done with cocoa_switch(), but it is meant to be called when the surface is being replaced, and may be called even when not switching the console. ui/cocoa never reset the keyboard state, which resulted in stuck keys. Add ui/cocoa's own implementation of console_select(), which updates the UI info and resets the keyboard state tracker. Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20240319-console-v2-3-3fd6feef321a@daynix.com>
This commit is contained in:
parent
d4c199566f
commit
ca3de7b5af
37
ui/cocoa.m
37
ui/cocoa.m
@ -102,6 +102,7 @@ static const DisplayChangeListenerOps dcl_ops = {
|
|||||||
static DisplayChangeListener dcl = {
|
static DisplayChangeListener dcl = {
|
||||||
.ops = &dcl_ops,
|
.ops = &dcl_ops,
|
||||||
};
|
};
|
||||||
|
static QKbdState *kbd;
|
||||||
static int cursor_hide = 1;
|
static int cursor_hide = 1;
|
||||||
static int left_command_key_enabled = 1;
|
static int left_command_key_enabled = 1;
|
||||||
static bool swap_opt_cmd;
|
static bool swap_opt_cmd;
|
||||||
@ -309,7 +310,6 @@ static void handleAnyDeviceErrors(Error * err)
|
|||||||
NSTrackingArea *trackingArea;
|
NSTrackingArea *trackingArea;
|
||||||
QEMUScreen screen;
|
QEMUScreen screen;
|
||||||
pixman_image_t *pixman_image;
|
pixman_image_t *pixman_image;
|
||||||
QKbdState *kbd;
|
|
||||||
BOOL isMouseGrabbed;
|
BOOL isMouseGrabbed;
|
||||||
BOOL isAbsoluteEnabled;
|
BOOL isAbsoluteEnabled;
|
||||||
CFMachPortRef eventsTap;
|
CFMachPortRef eventsTap;
|
||||||
@ -361,7 +361,6 @@ static CGEventRef handleTapEvent(CGEventTapProxy proxy, CGEventType type, CGEven
|
|||||||
|
|
||||||
screen.width = frameRect.size.width;
|
screen.width = frameRect.size.width;
|
||||||
screen.height = frameRect.size.height;
|
screen.height = frameRect.size.height;
|
||||||
kbd = qkbd_state_init(dcl.con);
|
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_14_0
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_14_0
|
||||||
[self setClipsToBounds:YES];
|
[self setClipsToBounds:YES];
|
||||||
#endif
|
#endif
|
||||||
@ -378,8 +377,6 @@ static CGEventRef handleTapEvent(CGEventTapProxy proxy, CGEventType type, CGEven
|
|||||||
pixman_image_unref(pixman_image);
|
pixman_image_unref(pixman_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
qkbd_state_free(kbd);
|
|
||||||
|
|
||||||
if (eventsTap) {
|
if (eventsTap) {
|
||||||
CFRelease(eventsTap);
|
CFRelease(eventsTap);
|
||||||
}
|
}
|
||||||
@ -429,6 +426,20 @@ static CGEventRef handleTapEvent(CGEventTapProxy proxy, CGEventType type, CGEven
|
|||||||
[self removeTrackingRect];
|
[self removeTrackingRect];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) selectConsoleLocked:(unsigned int)index
|
||||||
|
{
|
||||||
|
QemuConsole *con = qemu_console_lookup_by_index(index);
|
||||||
|
if (!con) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unregister_displaychangelistener(&dcl);
|
||||||
|
qkbd_state_switch_console(kbd, con);
|
||||||
|
dcl.con = con;
|
||||||
|
register_displaychangelistener(&dcl);
|
||||||
|
[self updateUIInfo];
|
||||||
|
}
|
||||||
|
|
||||||
- (void) hideCursor
|
- (void) hideCursor
|
||||||
{
|
{
|
||||||
if (!cursor_hide) {
|
if (!cursor_hide) {
|
||||||
@ -718,7 +729,8 @@ static CGEventRef handleTapEvent(CGEventTapProxy proxy, CGEventType type, CGEven
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (keysym) {
|
if (keysym) {
|
||||||
qemu_text_console_put_keysym(NULL, keysym);
|
QemuTextConsole *con = QEMU_TEXT_CONSOLE(dcl.con);
|
||||||
|
qemu_text_console_put_keysym(con, keysym);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -898,7 +910,7 @@ static CGEventRef handleTapEvent(CGEventTapProxy proxy, CGEventType type, CGEven
|
|||||||
|
|
||||||
// enable graphic console
|
// enable graphic console
|
||||||
case '1' ... '9':
|
case '1' ... '9':
|
||||||
console_select(key - '0' - 1); /* ascii math */
|
[self selectConsoleLocked:key - '0' - 1]; /* ascii math */
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// release the mouse grab
|
// release the mouse grab
|
||||||
@ -909,7 +921,7 @@ static CGEventRef handleTapEvent(CGEventTapProxy proxy, CGEventType type, CGEven
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qemu_console_is_graphic(NULL)) {
|
if (qemu_console_is_graphic(dcl.con)) {
|
||||||
qkbd_state_key_event(kbd, keycode, true);
|
qkbd_state_key_event(kbd, keycode, true);
|
||||||
} else {
|
} else {
|
||||||
[self handleMonitorInput: event];
|
[self handleMonitorInput: event];
|
||||||
@ -924,7 +936,7 @@ static CGEventRef handleTapEvent(CGEventTapProxy proxy, CGEventType type, CGEven
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qemu_console_is_graphic(NULL)) {
|
if (qemu_console_is_graphic(dcl.con)) {
|
||||||
qkbd_state_key_event(kbd, keycode, false);
|
qkbd_state_key_event(kbd, keycode, false);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -1374,7 +1386,7 @@ static CGEventRef handleTapEvent(CGEventTapProxy proxy, CGEventType type, CGEven
|
|||||||
- (void)displayConsole:(id)sender
|
- (void)displayConsole:(id)sender
|
||||||
{
|
{
|
||||||
with_bql(^{
|
with_bql(^{
|
||||||
console_select([sender tag]);
|
[cocoaView selectConsoleLocked:[sender tag]];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1945,7 +1957,6 @@ static void cocoa_switch(DisplayChangeListener *dcl,
|
|||||||
pixman_image_ref(image);
|
pixman_image_ref(image);
|
||||||
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
[cocoaView updateUIInfo];
|
|
||||||
[cocoaView switchSurface:image];
|
[cocoaView switchSurface:image];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1955,7 +1966,7 @@ static void cocoa_refresh(DisplayChangeListener *dcl)
|
|||||||
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
COCOA_DEBUG("qemu_cocoa: cocoa_refresh\n");
|
COCOA_DEBUG("qemu_cocoa: cocoa_refresh\n");
|
||||||
graphic_hw_update(NULL);
|
graphic_hw_update(dcl->con);
|
||||||
|
|
||||||
if (qemu_input_is_absolute(dcl->con)) {
|
if (qemu_input_is_absolute(dcl->con)) {
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
@ -2039,8 +2050,12 @@ static void cocoa_display_init(DisplayState *ds, DisplayOptions *opts)
|
|||||||
add_console_menu_entries();
|
add_console_menu_entries();
|
||||||
addRemovableDevicesMenuItems();
|
addRemovableDevicesMenuItems();
|
||||||
|
|
||||||
|
dcl.con = qemu_console_lookup_default();
|
||||||
|
kbd = qkbd_state_init(dcl.con);
|
||||||
|
|
||||||
// register vga output callbacks
|
// register vga output callbacks
|
||||||
register_displaychangelistener(&dcl);
|
register_displaychangelistener(&dcl);
|
||||||
|
[cocoaView updateUIInfo];
|
||||||
|
|
||||||
qemu_event_init(&cbevent, false);
|
qemu_event_init(&cbevent, false);
|
||||||
cbowner = [[QemuCocoaPasteboardTypeOwner alloc] init];
|
cbowner = [[QemuCocoaPasteboardTypeOwner alloc] init];
|
||||||
|
Loading…
Reference in New Issue
Block a user