aboutsummaryrefslogtreecommitdiff
path: root/ui/cocoa.m
diff options
context:
space:
mode:
Diffstat (limited to 'ui/cocoa.m')
-rw-r--r--ui/cocoa.m75
1 files changed, 46 insertions, 29 deletions
diff --git a/ui/cocoa.m b/ui/cocoa.m
index 1a626e215f..06951d03f0 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -256,7 +256,7 @@ static int cocoa_keycode_to_qemu(int keycode)
BOOL isMouseGrabbed;
BOOL isFullscreen;
BOOL isAbsoluteEnabled;
- BOOL isTabletEnabled;
+ BOOL isMouseDeassociated;
}
- (void) switchSurface:(DisplaySurface *)surface;
- (void) grabMouse;
@@ -264,8 +264,21 @@ static int cocoa_keycode_to_qemu(int keycode)
- (void) toggleFullScreen:(id)sender;
- (void) handleEvent:(NSEvent *)event;
- (void) setAbsoluteEnabled:(BOOL)tIsAbsoluteEnabled;
+/* The state surrounding mouse grabbing is potentially confusing.
+ * isAbsoluteEnabled tracks qemu_input_is_absolute() [ie "is the emulated
+ * pointing device an absolute-position one?"], but is only updated on
+ * next refresh.
+ * isMouseGrabbed tracks whether GUI events are directed to the guest;
+ * it controls whether special keys like Cmd get sent to the guest,
+ * and whether we capture the mouse when in non-absolute mode.
+ * isMouseDeassociated tracks whether we've told MacOSX to disassociate
+ * the mouse and mouse cursor position by calling
+ * CGAssociateMouseAndMouseCursorPosition(FALSE)
+ * (which basically happens if we grab in non-absolute mode).
+ */
- (BOOL) isMouseGrabbed;
- (BOOL) isAbsoluteEnabled;
+- (BOOL) isMouseDeassociated;
- (float) cdx;
- (float) cdy;
- (QEMUScreen) gscreen;
@@ -613,14 +626,12 @@ QemuCocoaView *cocoaView;
case NSMouseMoved:
if (isAbsoluteEnabled) {
if (![self screenContainsPoint:p] || ![[self window] isKeyWindow]) {
- if (isTabletEnabled) { // if we leave the window, deactivate the tablet
- [NSCursor unhide];
- isTabletEnabled = FALSE;
+ if (isMouseGrabbed) {
+ [self ungrabMouse];
}
} else {
- if (!isTabletEnabled) { // if we enter the window, activate the tablet
- [NSCursor hide];
- isTabletEnabled = TRUE;
+ if (!isMouseGrabbed) {
+ [self grabMouse];
}
}
}
@@ -659,16 +670,9 @@ QemuCocoaView *cocoaView;
mouse_event = true;
break;
case NSLeftMouseUp:
- if (isTabletEnabled) {
- mouse_event = true;
- } else if (!isMouseGrabbed) {
- if ([self screenContainsPoint:p]) {
- [self grabMouse];
- } else {
- [NSApp sendEvent:event];
- }
- } else {
- mouse_event = true;
+ mouse_event = true;
+ if (!isMouseGrabbed && [self screenContainsPoint:p]) {
+ [self grabMouse];
}
break;
case NSRightMouseUp:
@@ -678,13 +682,11 @@ QemuCocoaView *cocoaView;
mouse_event = true;
break;
case NSScrollWheel:
- if (isTabletEnabled || isMouseGrabbed) {
+ if (isMouseGrabbed) {
buttons |= ([event deltaY] < 0) ?
MOUSE_EVENT_WHEELUP : MOUSE_EVENT_WHEELDN;
- mouse_event = true;
- } else {
- [NSApp sendEvent:event];
}
+ mouse_event = true;
break;
default:
[NSApp sendEvent:event];
@@ -702,12 +704,20 @@ QemuCocoaView *cocoaView;
qemu_input_update_buttons(dcl->con, bmap, last_buttons, buttons);
last_buttons = buttons;
}
- if (isTabletEnabled) {
- qemu_input_queue_abs(dcl->con, INPUT_AXIS_X, p.x, screen.width);
- qemu_input_queue_abs(dcl->con, INPUT_AXIS_Y, p.y, screen.height);
- } else if (isMouseGrabbed) {
- qemu_input_queue_rel(dcl->con, INPUT_AXIS_X, (int)[event deltaX]);
- qemu_input_queue_rel(dcl->con, INPUT_AXIS_Y, (int)[event deltaY]);
+ 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, screen.width);
+ qemu_input_queue_abs(dcl->con, INPUT_AXIS_Y, screen.height - p.y, 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 {
[NSApp sendEvent:event];
}
@@ -726,7 +736,10 @@ QemuCocoaView *cocoaView;
[normalWindow setTitle:@"QEMU - (Press ctrl + alt to release Mouse)"];
}
[NSCursor hide];
- CGAssociateMouseAndMouseCursorPosition(FALSE);
+ if (!isAbsoluteEnabled) {
+ isMouseDeassociated = TRUE;
+ CGAssociateMouseAndMouseCursorPosition(FALSE);
+ }
isMouseGrabbed = TRUE; // while isMouseGrabbed = TRUE, QemuCocoaApp sends all events to [cocoaView handleEvent:]
}
@@ -741,13 +754,17 @@ QemuCocoaView *cocoaView;
[normalWindow setTitle:@"QEMU"];
}
[NSCursor unhide];
- CGAssociateMouseAndMouseCursorPosition(TRUE);
+ if (isMouseDeassociated) {
+ CGAssociateMouseAndMouseCursorPosition(TRUE);
+ isMouseDeassociated = FALSE;
+ }
isMouseGrabbed = FALSE;
}
- (void) setAbsoluteEnabled:(BOOL)tIsAbsoluteEnabled {isAbsoluteEnabled = tIsAbsoluteEnabled;}
- (BOOL) isMouseGrabbed {return isMouseGrabbed;}
- (BOOL) isAbsoluteEnabled {return isAbsoluteEnabled;}
+- (BOOL) isMouseDeassociated {return isMouseDeassociated;}
- (float) cdx {return cdx;}
- (float) cdy {return cdy;}
- (QEMUScreen) gscreen {return screen;}