Fix OS X mouse position issues

Fix problems using absolute mouse positions in the view when the mouse
were outside the view area.
This commit is contained in:
David Capello 2015-01-25 19:08:41 -03:00
parent 9af8567a6b
commit 429c722f73
2 changed files with 85 additions and 74 deletions

View File

@ -131,9 +131,6 @@ void osx_mouse_handler(int ax, int ay, int x, int y, int z, int buttons)
_mouse_y = ay; _mouse_y = ay;
_mouse_z += z; _mouse_z += z;
_mouse_x = CLAMP(mouse_minx, _mouse_x, mouse_maxx);
_mouse_y = CLAMP(mouse_miny, _mouse_y, mouse_maxy);
_handle_mouse_input(); _handle_mouse_input();
} }

View File

@ -153,25 +153,14 @@ static RETSIGTYPE osx_signal_handler(int num)
static BOOL handle_mouse_enter( static void handle_mouse_enter()
NSRect frame, NSRect view, NSPoint point,
int* mx, int* my, int* buttons)
{ {
if (_mouse_installed && !_mouse_on && if (_mouse_installed && !_mouse_on && osx_window) {
(osx_window) && (NSPointInRect(point, view))) {
*mx = point.x;
*my = frame.size.height - point.y;
*buttons = 0;
_mouse_on = TRUE; _mouse_on = TRUE;
osx_hide_native_mouse(); osx_hide_native_mouse();
if (osx_mouse_enter_callback) if (osx_mouse_enter_callback)
osx_mouse_enter_callback(); osx_mouse_enter_callback();
return YES;
} }
else
return NO;
} }
@ -200,9 +189,8 @@ void osx_event_handler()
{ {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSEvent *event; NSEvent *event;
NSDate *distant_past = [NSDate distantPast];
NSPoint point; NSPoint point;
NSRect frame, view; NSView* view;
int dx = 0, dy = 0, dz = 0; int dx = 0, dy = 0, dz = 0;
int mx = _mouse_x; int mx = _mouse_x;
int my = _mouse_y; int my = _mouse_y;
@ -211,10 +199,12 @@ void osx_event_handler()
BOOL gotmouseevent = NO; BOOL gotmouseevent = NO;
while ((event = [NSApp nextEventMatchingMask: NSAnyEventMask while ((event = [NSApp nextEventMatchingMask: NSAnyEventMask
untilDate: distant_past untilDate: [NSDate distantPast]
inMode: NSDefaultRunLoopMode inMode: NSDefaultRunLoopMode
dequeue: YES]) != nil) dequeue: YES]))
{ {
BOOL send_event = YES;
_unix_lock_mutex(osx_skip_events_processing_mutex); _unix_lock_mutex(osx_skip_events_processing_mutex);
int skip_events_processing = osx_skip_events_processing; int skip_events_processing = osx_skip_events_processing;
_unix_unlock_mutex(osx_skip_events_processing_mutex); _unix_unlock_mutex(osx_skip_events_processing_mutex);
@ -224,16 +214,15 @@ void osx_event_handler()
continue; continue;
} }
view = NSMakeRect(0, 0, gfx_driver->w, gfx_driver->h); view = [osx_window contentView];
point = [event locationInWindow]; point = [event locationInWindow];
if (osx_window) if (osx_window) {
{ if ([event window] == nil)
frame = [[osx_window contentView] frame]; point = [osx_window convertScreenToBase:point];
}
else point = [view convertPoint:point fromView:nil];
{
frame = [[NSScreen mainScreen] frame];
} }
event_type = [event type]; event_type = [event type];
switch (event_type) { switch (event_type) {
@ -241,10 +230,11 @@ void osx_event_handler()
if (_keyboard_installed) if (_keyboard_installed)
osx_keyboard_handler(TRUE, event); osx_keyboard_handler(TRUE, event);
#if 0 // Avoid beeps TODO uncomment this when the OS X menus are ready #if 0 // Avoid beeps TODO comment this when the OS X menus are ready
if ([event modifierFlags] & NSCommandKeyMask && ) if ([event modifierFlags] & NSCommandKeyMask)
[NSApp sendEvent: event]; [NSApp sendEvent: event];
#endif #endif
send_event = NO;
break; break;
case NSKeyUp: case NSKeyUp:
@ -255,6 +245,7 @@ void osx_event_handler()
if ([event modifierFlags] & NSCommandKeyMask) if ([event modifierFlags] & NSCommandKeyMask)
[NSApp sendEvent: event]; [NSApp sendEvent: event];
#endif #endif
send_event = NO;
break; break;
case NSFlagsChanged: case NSFlagsChanged:
@ -267,87 +258,109 @@ void osx_event_handler()
case NSRightMouseDown: case NSRightMouseDown:
/* App is regaining focus */ /* App is regaining focus */
if (![NSApp isActive]) { if (![NSApp isActive]) {
handle_mouse_enter(frame, view, point, &mx, &my, &buttons); handle_mouse_enter();
if (osx_window) if (osx_window)
[osx_window invalidateCursorRectsForView: [osx_window contentView]]; [osx_window invalidateCursorRectsForView:view];
if (_keyboard_installed) if (_keyboard_installed)
osx_keyboard_focused(TRUE, 0); osx_keyboard_focused(TRUE, 0);
_switch_in(); _switch_in();
gotmouseevent = YES;
[NSApp sendEvent: event];
break;
} }
buttons |= ((event_type == NSLeftMouseDown) ? 0x1 : 0); if (_mouse_on) {
buttons |= ((event_type == NSRightMouseDown) ? 0x2 : 0); buttons |= ((event_type == NSLeftMouseDown) ? 0x1 : 0);
buttons |= ((event_type == NSOtherMouseDown) ? 0x4 : 0); buttons |= ((event_type == NSRightMouseDown) ? 0x2 : 0);
buttons |= ((event_type == NSOtherMouseDown) ? 0x4 : 0);
mx = point.x;
my = point.y;
[NSApp sendEvent: event]; gotmouseevent = YES;
gotmouseevent = YES; }
break; break;
case NSLeftMouseUp: case NSLeftMouseUp:
case NSOtherMouseUp: case NSOtherMouseUp:
case NSRightMouseUp: case NSRightMouseUp:
if ([NSApp isActive]) if ([NSApp isActive])
handle_mouse_enter(frame, view, point, &mx, &my, &buttons); handle_mouse_enter();
buttons &= ~((event_type == NSLeftMouseUp) ? 0x1 : 0); if (_mouse_on) {
buttons &= ~((event_type == NSRightMouseUp) ? 0x2 : 0); buttons &= ~((event_type == NSLeftMouseUp) ? 0x1 : 0);
buttons &= ~((event_type == NSOtherMouseUp) ? 0x4 : 0); buttons &= ~((event_type == NSRightMouseUp) ? 0x2 : 0);
buttons &= ~((event_type == NSOtherMouseUp) ? 0x4 : 0);
[NSApp sendEvent: event]; mx = point.x;
gotmouseevent = YES; my = point.y;
gotmouseevent = YES;
}
break; break;
case NSLeftMouseDragged: case NSLeftMouseDragged:
case NSRightMouseDragged: case NSRightMouseDragged:
case NSOtherMouseDragged: case NSOtherMouseDragged:
case NSMouseMoved: case NSMouseMoved:
if ([NSApp isActive]) if ([NSApp isActive] && [view mouse:point inRect:[view frame]])
handle_mouse_enter(frame, view, point, &mx, &my, &buttons); handle_mouse_enter();
dx += [event deltaX]; if (_mouse_on) {
dy += [event deltaY]; dx += [event deltaX];
dy += [event deltaY];
mx = point.x;
my = point.y;
mx = point.x; gotmouseevent = YES;
my = frame.size.height - point.y; }
[NSApp sendEvent: event];
gotmouseevent = YES;
break; break;
case NSScrollWheel: case NSScrollWheel:
dz += [event deltaY]; if (_mouse_on)
dz += [event deltaY];
mx = point.x;
my = point.y;
gotmouseevent = YES; gotmouseevent = YES;
break; break;
case NSMouseEntered: case NSMouseEntered:
if (([event trackingNumber] == osx_mouse_tracking_rect) && ([NSApp isActive])) { if ([event window] == osx_window &&
if (handle_mouse_enter(frame, view, point, &mx, &my, &buttons)) [event trackingNumber] == osx_mouse_tracking_rect) {
handle_mouse_enter();
if (_mouse_on) {
mx = point.x;
my = point.y;
gotmouseevent = YES; gotmouseevent = YES;
}
} }
[NSApp sendEvent: event];
break; break;
case NSMouseExited: case NSMouseExited:
if ([event trackingNumber] == osx_mouse_tracking_rect) { if (handle_mouse_leave()) {
if (handle_mouse_leave()) mx = point.x;
gotmouseevent = YES; my = point.y;
gotmouseevent = YES;
} }
[NSApp sendEvent: event];
break; break;
case NSAppKitDefined: case NSAppKitDefined:
switch ([event subtype]) { switch ([event subtype]) {
case NSApplicationActivatedEventType: case NSApplicationActivatedEventType:
if (osx_window) { if (osx_window) {
[osx_window invalidateCursorRectsForView: [osx_window contentView]]; [osx_window invalidateCursorRectsForView:view];
if (_keyboard_installed) if (_keyboard_installed)
osx_keyboard_focused(TRUE, 0); osx_keyboard_focused(TRUE, 0);
handle_mouse_enter(frame, view, point, &mx, &my, &buttons); handle_mouse_enter();
if (_mouse_on) {
mx = point.x;
my = point.y;
gotmouseevent = YES;
}
} }
_switch_in(); _switch_in();
break; break;
@ -355,6 +368,7 @@ void osx_event_handler()
case NSApplicationDeactivatedEventType: case NSApplicationDeactivatedEventType:
if (osx_window && _keyboard_installed) if (osx_window && _keyboard_installed)
osx_keyboard_focused(FALSE, 0); osx_keyboard_focused(FALSE, 0);
handle_mouse_leave(); handle_mouse_leave();
_switch_out(); _switch_out();
break; break;
@ -370,20 +384,20 @@ void osx_event_handler()
osx_window_first_expose = FALSE; osx_window_first_expose = FALSE;
[osx_window setHasShadow: NO]; [osx_window setHasShadow: NO];
[osx_window setHasShadow: YES]; [osx_window setHasShadow: YES];
[osx_window invalidateCursorRectsForView: [osx_window contentView]]; [osx_window invalidateCursorRectsForView:view];
} }
break; break;
} }
[NSApp sendEvent: event];
break;
default:
[NSApp sendEvent: event];
break; break;
} }
if (send_event == YES)
[NSApp sendEvent: event];
if (gotmouseevent == YES)
osx_mouse_handler(mx, my, dx, dy, dz, buttons);
} }
if (gotmouseevent == YES)
osx_mouse_handler(mx, my, dx, dy, dz, buttons);
[pool release]; [pool release];
} }