ui/cocoa used to release all mouse buttons when it sees NSEventTypeLeftMouseUp, NSEventTypeRightMouseUp, or NSEventTypeOtherMouseUp, but it can instead release specific one according to the delivered event.
Signed-off-by: Akihiko Odaki <akihiko.od...@daynix.com> --- ui/cocoa.m | 132 ++++++++++++++++++++++++++----------------------------------- 1 file changed, 55 insertions(+), 77 deletions(-) diff --git a/ui/cocoa.m b/ui/cocoa.m index eb99064beeb4..fe0eb74b0743 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -99,7 +99,6 @@ static void cocoa_switch(DisplayChangeListener *dcl, static DisplayChangeListener dcl = { .ops = &dcl_ops, }; -static int last_buttons; static int cursor_hide = 1; static int left_command_key_enabled = 1; static bool swap_opt_cmd; @@ -801,8 +800,6 @@ - (bool) handleEventLocked:(NSEvent *)event COCOA_DEBUG("QemuCocoaView: handleEvent\n"); int buttons = 0; int keycode = 0; - bool mouse_event = false; - // Location of event in virtual screen coordinates NSPoint p = [self screenLocationOfEvent:event]; NSUInteger modifiers = [event modifierFlags]; @@ -883,25 +880,25 @@ - (bool) handleEventLocked:(NSEvent *)event if (!!(modifiers & NSEventModifierFlagShift)) { [self toggleKey:Q_KEY_CODE_SHIFT]; } - break; + return true; case kVK_RightShift: if (!!(modifiers & NSEventModifierFlagShift)) { [self toggleKey:Q_KEY_CODE_SHIFT_R]; } - break; + return true; case kVK_Control: if (!!(modifiers & NSEventModifierFlagControl)) { [self toggleKey:Q_KEY_CODE_CTRL]; } - break; + return true; case kVK_RightControl: if (!!(modifiers & NSEventModifierFlagControl)) { [self toggleKey:Q_KEY_CODE_CTRL_R]; } - break; + return true; case kVK_Option: if (!!(modifiers & NSEventModifierFlagOption)) { @@ -911,7 +908,7 @@ - (bool) handleEventLocked:(NSEvent *)event [self toggleKey:Q_KEY_CODE_ALT]; } } - break; + return true; case kVK_RightOption: if (!!(modifiers & NSEventModifierFlagOption)) { @@ -921,7 +918,7 @@ - (bool) handleEventLocked:(NSEvent *)event [self toggleKey:Q_KEY_CODE_ALT_R]; } } - break; + return true; /* Don't pass command key changes to guest unless mouse is grabbed */ case kVK_Command: @@ -934,7 +931,7 @@ - (bool) handleEventLocked:(NSEvent *)event [self toggleKey:Q_KEY_CODE_META_L]; } } - break; + return true; case kVK_RightCommand: if (isMouseGrabbed && @@ -945,9 +942,11 @@ - (bool) handleEventLocked:(NSEvent *)event [self toggleKey:Q_KEY_CODE_META_R]; } } - break; + return true; + + default: + return true; } - break; case NSEventTypeKeyDown: keycode = cocoa_keycode_to_qemu([event keyCode]); @@ -983,7 +982,7 @@ - (bool) handleEventLocked:(NSEvent *)event } else { [self handleMonitorInput: event]; } - break; + return true; case NSEventTypeKeyUp: keycode = cocoa_keycode_to_qemu([event keyCode]); @@ -996,7 +995,7 @@ - (bool) handleEventLocked:(NSEvent *)event if (qemu_console_is_graphic(NULL)) { qkbd_state_key_event(kbd, keycode, false); } - break; + return true; case NSEventTypeMouseMoved: if (isAbsoluteEnabled) { // Cursor re-entered into a window might generate events bound to screen coordinates @@ -1012,34 +1011,18 @@ - (bool) handleEventLocked:(NSEvent *)event } } } - mouse_event = true; - break; + return [self handleMouseEvent:event]; case NSEventTypeLeftMouseDown: - buttons |= MOUSE_EVENT_LBUTTON; - mouse_event = true; - break; + return [self handleMouseEvent:event button:MOUSE_EVENT_LBUTTON down:true]; case NSEventTypeRightMouseDown: - buttons |= MOUSE_EVENT_RBUTTON; - mouse_event = true; - break; - case NSEventTypeOtherMouseDown: - buttons |= MOUSE_EVENT_MBUTTON; - mouse_event = true; - break; + return [self handleMouseEvent:event button:MOUSE_EVENT_RBUTTON down:true]; case NSEventTypeLeftMouseDragged: - buttons |= MOUSE_EVENT_LBUTTON; - mouse_event = true; - break; + return [self handleMouseEvent:event button:MOUSE_EVENT_LBUTTON down:true]; case NSEventTypeRightMouseDragged: - buttons |= MOUSE_EVENT_RBUTTON; - mouse_event = true; - break; + return [self handleMouseEvent:event button:MOUSE_EVENT_RBUTTON down:true]; case NSEventTypeOtherMouseDragged: - buttons |= MOUSE_EVENT_MBUTTON; - mouse_event = true; - break; + return [self handleMouseEvent:event button:MOUSE_EVENT_MBUTTON down:true]; case NSEventTypeLeftMouseUp: - mouse_event = true; if (!isMouseGrabbed && [self screenContainsPoint:p]) { /* * In fullscreen mode, the window of cocoaView may not be the @@ -1050,13 +1033,11 @@ - (bool) handleEventLocked:(NSEvent *)event [self grabMouse]; } } - break; + return [self handleMouseEvent:event button:MOUSE_EVENT_LBUTTON down:false]; case NSEventTypeRightMouseUp: - mouse_event = true; - break; + return [self handleMouseEvent:event button:MOUSE_EVENT_RBUTTON down:false]; case NSEventTypeOtherMouseUp: - mouse_event = true; - break; + return [self handleMouseEvent:event button:MOUSE_EVENT_MBUTTON down:false]; case NSEventTypeScrollWheel: /* * Send wheel events to the guest regardless of window focus. @@ -1087,52 +1068,49 @@ - (bool) handleEventLocked:(NSEvent *)event * Since deltaX/deltaY also report scroll wheel events we prevent mouse * movement code from executing. */ - mouse_event = false; - break; + return true; default: return false; } +} + +- (bool) handleMouseEvent:(NSEvent *)event +{ + if (!isMouseGrabbed) { + return false; + } - if (mouse_event) { - /* Don't send button events to the guest unless we've got a - * mouse grab or window focus. If we have neither then this event - * is the user clicking on the background window to activate and - * bring us to the front, which will be done by the sendEvent - * call below. We definitely don't want to pass that click through - * to the guest. + if (isAbsoluteEnabled) { + NSPoint p = [self screenLocationOfEvent:event]; + /* Note that the origin for Cocoa mouse coords is bottom left, not top left. + * The check on screenContainsPoint is to avoid sending out of range values for + * clicks in the titlebar. */ - if ((isMouseGrabbed || [[self window] isKeyWindow]) && - (last_buttons != buttons)) { - static uint32_t bmap[INPUT_BUTTON__MAX] = { - [INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON, - [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON, - [INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON - }; - qemu_input_update_buttons(dcl.con, bmap, last_buttons, buttons); - last_buttons = buttons; - } - if (isMouseGrabbed) { - if (isAbsoluteEnabled) { - /* Note that the origin for Cocoa mouse coords is bottom left, not top left. - * The check on screenContainsPoint is to avoid sending out of range values for - * clicks in the titlebar. - */ - if ([self screenContainsPoint:p]) { - qemu_input_queue_abs(dcl.con, INPUT_AXIS_X, p.x, 0, screen.width); - qemu_input_queue_abs(dcl.con, INPUT_AXIS_Y, screen.height - p.y, 0, screen.height); - } - } else { - qemu_input_queue_rel(dcl.con, INPUT_AXIS_X, (int)[event deltaX]); - qemu_input_queue_rel(dcl.con, INPUT_AXIS_Y, (int)[event deltaY]); - } - } else { - return false; + if ([self screenContainsPoint:p]) { + qemu_input_queue_abs(dcl.con, INPUT_AXIS_X, p.x, 0, screen.width); + qemu_input_queue_abs(dcl.con, INPUT_AXIS_Y, screen.height - p.y, 0, screen.height); } - qemu_input_event_sync(); + } else { + qemu_input_queue_rel(dcl.con, INPUT_AXIS_X, (int)[event deltaX]); + qemu_input_queue_rel(dcl.con, INPUT_AXIS_Y, (int)[event deltaY]); } + + qemu_input_event_sync(); + return true; } +- (bool) handleMouseEvent:(NSEvent *)event button:(InputButton)button down:(bool)down +{ + if (!isMouseGrabbed && ![[self window] isKeyWindow]) { + return false; + } + + qemu_input_queue_btn(dcl.con, button, down); + + return [self handleMouseEvent:event]; +} + - (void) grabMouse { COCOA_DEBUG("QemuCocoaView: grabMouse\n"); -- 2.43.1