10 #ifndef NS_RETURNS_INNER_POINTER
11 #define NS_RETURNS_INNER_POINTER
13 #include <AppKit/AppKit.h>
14 #include <AvailabilityMacros.h>
16 #ifndef MAC_OS_X_VERSION_10_10_3
26 @property (readonly) NSInteger
stage;
59 __block NSSize displayPixelSize;
60 dispatch_sync(dispatch_get_main_queue(), ^{
61 NSDictionary *description = [[NSScreen mainScreen] deviceDescription];
62 displayPixelSize = [description[NSDeviceSize] sizeValue];
65 *width = (int)displayPixelSize.width;
66 *height = (
int)displayPixelSize.height;
74 return event.pressure +
MAX(0., event.stage - 1.);
118 NSRect rectInWindow = NSMakeRect(pointInWindow.x, pointInWindow.y, 0, 0);
119 NSPoint pointInScreen =
window ? [window convertRectToScreen:rectInWindow].origin : pointInWindow;
122 NSInteger windowNumberForPoint = [NSWindow windowNumberAtPoint:pointInScreen belowWindowWithWindowNumber:0];
123 for (NSWindow *w in [NSApp windows])
124 if ([w windowNumber] == windowNumberForPoint
126 && NSPointInRect(pointInScreen, [w convertRectToScreen:[[w contentView] frame]]))
132 pointInScreen.y = [[NSScreen mainScreen] frame].size.height - pointInScreen.y;
144 __block NSRect bounds;
147 bounds = [view convertRectFromBacking:((VuoGraphicsView *)view).viewport];
154 NSPoint windowOrigin = [w frameRectForContentRect:w.frame].origin;
155 NSPoint screenOrigin = w.screen.frame.origin;
156 bounds.origin.x += windowOrigin.x - screenOrigin.x;
157 bounds.origin.y += windowOrigin.y - screenOrigin.y;
160 VuoPoint2d pointInVuo;
161 double viewMaxX = NSWidth(bounds) - 1;
162 double viewMaxY = NSHeight(bounds) - 1;
163 pointInVuo.x = ((pointInView.x - NSMinX(bounds) - viewMaxX /2.) * 2.) / viewMaxX;
164 pointInVuo.y = ((pointInView.y - NSMinY(bounds) - viewMaxY/2.) * 2.) / viewMaxX;
165 pointInVuo.y /= (NSWidth(bounds)/viewMaxX) * (viewMaxY/NSHeight(bounds));
174 NSRect fullScreenFrame = [[window screen] frame];
180 pointInScreen.x =
VuoReal_snap(pointInScreen.x * fullScreenFrame.size.width / (fullScreenFrame.size.width+1), 0, 1);
181 pointInScreen.y =
VuoReal_snap(pointInScreen.y * fullScreenFrame.size.height / (fullScreenFrame.size.height+1), 0, 1);
183 NSView *view = [window contentView];
184 NSPoint pointInView = NSMakePoint(pointInScreen.x - fullScreenFrame.origin.x,
185 pointInScreen.y - fullScreenFrame.origin.y);
186 *isInScreen = NSPointInRect(pointInScreen, fullScreenFrame);
209 __block NSView *view;
210 __block NSPoint pointInView;
211 __block NSRect frame;
213 view =
window.contentView;
214 pointInView = [view convertPoint:pointInWindow fromView:nil];
217 *shouldFire = NSPointInRect(pointInView, frame);
226 NSView *view = [window contentView];
227 NSRect bounds = [view bounds];
228 VuoPoint2d deltaInVuo;
229 deltaInVuo.x = (delta.x * 2.) / bounds.size.width;
230 deltaInVuo.y = -(delta.y * 2.) / bounds.size.width;
247 return !NSEqualPoints([[NSCursor currentCursor] hotSpot], [[NSCursor currentSystemCursor] hotSpot]);
259 if (fabs(delta.x) < 0.00001 && fabs(delta.y) < 0.00001)
262 bool shouldFire =
false;
263 NSWindow *targetWindow = (NSWindow *)windowRef;
266 if (targetWindow == [event
window])
289 bool shouldFire =
false;
290 VuoPoint2d convertedPoint;
291 NSPoint pointInWindowOrScreen = [event locationInWindow];
292 NSWindow *targetWindow = (NSWindow *)windowRef;
295 __block
bool isKeyWindow;
297 isKeyWindow = targetWindow.isKeyWindow;
304 pointInWindowOrScreen = fullscreenPoint;
307 else if (targetWindow == [event
window])
309 else if (! [event
window] && isKeyWindow)
313 NSRect rectInWindowOrScreen = NSMakeRect(pointInWindowOrScreen.x, pointInWindowOrScreen.y, 0, 0);
314 __block NSPoint pointInWindow;
316 pointInWindow = [targetWindow convertRectFromScreen:rectInWindowOrScreen].origin;
325 if (!fireRegardlessOfPosition)
331 if (shouldFire || fireRegardlessOfPosition)
332 fire(convertedPoint);
348 bool shouldFire =
false;
349 VuoPoint2d convertedDelta;
350 NSPoint deltaInScreen = NSMakePoint([event deltaX], [event deltaY]);
351 if (fabs(deltaInScreen.x) < 0.0001
352 && fabs(deltaInScreen.y) < 0.0001)
355 NSWindow *targetWindow = (NSWindow *)windowRef;
363 NSPoint pointInWindowOrScreen = [NSEvent mouseLocation];
367 else if (targetWindow == [event
window] || (! [event
window] && [targetWindow isKeyWindow]))
382 fire(convertedDelta);
394 void (*singleClicked)(VuoPoint2d),
void (*doubleClicked)(VuoPoint2d),
void (*tripleClicked)(VuoPoint2d))
399 NSInteger clickCount = [event clickCount];
400 NSPoint fullscreenPoint = [NSEvent mouseLocation];
401 NSTimeInterval clickIntervalInSeconds = [NSEvent doubleClickInterval];
402 dispatch_time_t clickInterval = dispatch_time(DISPATCH_TIME_NOW, clickIntervalInSeconds * NSEC_PER_SEC);
405 void (*fired)(VuoPoint2d) = NULL;
407 fired = singleClicked;
408 else if (clickCount == 2)
409 fired = doubleClicked;
410 else if (clickCount >= 3)
411 fired = tripleClicked;
416 dispatch_after(clickInterval, context->
clickQueue, ^{
417 if (context->pendingClickCount == clickCount)
419 VuoMouse_fireMousePositionIfNeeded(event, fullscreenPoint, windowRef, modifierKey, false, ^(VuoPoint2d point){ fired(point); });
420 context->pendingClickCount = 0;
434 id monitor = [NSEvent addLocalMonitorForEventsMatchingMask:NSScrollWheelMask handler:^(NSEvent *event) {
435 VuoMouse_fireScrollDeltaIfNeeded(event, window, modifierKey, ^(VuoPoint2d point){ scrolled(point); });
450 id monitor = [NSEvent addLocalMonitorForEventsMatchingMask:NSScrollWheelMask handler:^(NSEvent *event) {
451 VuoMouse_fireScrollDeltaIfNeeded(event, window, modifierKey, scrolled);
464 if (
window && (modifierKey == VuoModifierKey_Any || modifierKey == VuoModifierKey_None))
486 id monitor = [NSEvent addLocalMonitorForEventsMatchingMask:NSMouseMovedMask|NSLeftMouseDraggedMask|NSRightMouseDraggedMask|NSOtherMouseDraggedMask handler:^(NSEvent *event) {
487 VuoMouse_fireMousePositionIfNeeded(event, [NSEvent mouseLocation], window, modifierKey, true, ^(VuoPoint2d point){ movedTo(point); });
507 id monitor = [NSEvent addLocalMonitorForEventsMatchingMask:NSMouseMovedMask|NSLeftMouseDraggedMask|NSRightMouseDraggedMask|NSOtherMouseDraggedMask handler:^(NSEvent *event) {
508 VuoMouse_fireMousePositionIfNeeded(event, [NSEvent mouseLocation], window, modifierKey, true, movedTo);
525 id monitor = [NSEvent addLocalMonitorForEventsMatchingMask:NSMouseMovedMask|NSLeftMouseDraggedMask|NSRightMouseDraggedMask|NSOtherMouseDraggedMask handler:^(NSEvent *event) {
526 VuoMouse_fireMouseDeltaIfNeeded(event, window, modifierKey, movedBy);
544 NSEventMask eventMask = 0;
547 case VuoMouseButton_Left:
548 eventMask = NSLeftMouseDraggedMask;
550 case VuoMouseButton_Middle:
551 eventMask = NSOtherMouseDraggedMask;
553 case VuoMouseButton_Right:
554 eventMask = NSRightMouseDraggedMask;
557 context->
monitor2 = [NSEvent addLocalMonitorForEventsMatchingMask:NSLeftMouseDraggedMask handler:^(NSEvent *event) {
558 VuoMouse_fireMousePositionIfNeeded(event, [NSEvent mouseLocation], window, VuoModifierKey_Control, fireRegardlessOfPosition, dragMovedTo);
563 case VuoMouseButton_Any:
564 eventMask = NSLeftMouseDraggedMask | NSOtherMouseDraggedMask | NSRightMouseDraggedMask;
568 context->
monitor = [NSEvent addLocalMonitorForEventsMatchingMask:eventMask handler:^(NSEvent *event) {
569 VuoMouse_fireMousePositionIfNeeded(event, [NSEvent mouseLocation], window, modifierKey, fireRegardlessOfPosition, dragMovedTo);
596 NSEventMask eventMask = 0;
599 case VuoMouseButton_Left:
600 eventMask = NSLeftMouseDownMask;
602 case VuoMouseButton_Middle:
603 eventMask = NSOtherMouseDownMask;
605 case VuoMouseButton_Right:
606 eventMask = NSRightMouseDownMask;
609 context->
monitor2 = [NSEvent addLocalMonitorForEventsMatchingMask:NSLeftMouseDownMask handler:^(NSEvent *event) {
610 VuoMouse_fireMousePositionIfNeeded(event, [NSEvent mouseLocation], window, VuoModifierKey_Control, false, pressed);
615 case VuoMouseButton_Any:
616 eventMask = NSLeftMouseDownMask | NSOtherMouseDownMask | NSRightMouseDownMask;
622 context->
monitor = [NSEvent addLocalMonitorForEventsMatchingMask:eventMask handler:^(NSEvent *event) {
623 if (event.type == NSEventTypePressure)
625 if (context->priorPressureStage == 1 && event.stage == 2 && forcePressed)
626 VuoMouse_fireMousePositionIfNeeded(event, [NSEvent mouseLocation], window, modifierKey, false, forcePressed);
627 context->priorPressureStage = event.stage;
630 VuoMouse_fireMousePositionIfNeeded(event, [NSEvent mouseLocation], window, modifierKey, false, pressed);
646 ^(VuoPoint2d point){ pressed(point); },
647 ^(VuoPoint2d point){ forcePressed(point); },
648 button,
window, modifierKey);
661 context->
monitor = [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskPressure handler:^(NSEvent *event) {
662 if (VuoModifierKey_doMacEventFlagsMatch(CGEventGetFlags([event CGEvent]), modifierKey)
663 && (button == VuoMouseButton_Any
664 || (button == VuoMouseButton_Left && NSEvent.pressedMouseButtons & 1)
665 || (button == VuoMouseButton_Right && NSEvent.pressedMouseButtons & 2)
666 || (button == VuoMouseButton_Middle && NSEvent.pressedMouseButtons & 4)))
667 pressureChanged(VuoMouse_getPressure(event));
682 NSEventMask eventMask = 0;
685 case VuoMouseButton_Left:
686 eventMask = NSLeftMouseUpMask;
688 case VuoMouseButton_Middle:
689 eventMask = NSOtherMouseUpMask;
691 case VuoMouseButton_Right:
692 eventMask = NSRightMouseUpMask;
695 context->
monitor2 = [NSEvent addLocalMonitorForEventsMatchingMask:NSLeftMouseUpMask handler:^(NSEvent *event) {
696 VuoMouse_fireMousePositionIfNeeded(event, [NSEvent mouseLocation], window, VuoModifierKey_Control, fireRegardlessOfPosition, released);
701 case VuoMouseButton_Any:
702 eventMask = NSLeftMouseUpMask | NSOtherMouseUpMask | NSRightMouseUpMask;
706 context->
monitor = [NSEvent addLocalMonitorForEventsMatchingMask:eventMask handler:^(NSEvent *event) {
707 VuoMouse_fireMousePositionIfNeeded(event, [NSEvent mouseLocation], window, modifierKey, fireRegardlessOfPosition, released);
731 context->
clickQueue = dispatch_queue_create(
"vuo.mouse.click", 0);
732 context->
clickGroup = dispatch_group_create();
735 NSEventMask eventMask = 0;
738 case VuoMouseButton_Left:
739 eventMask = NSLeftMouseUpMask;
741 case VuoMouseButton_Middle:
742 eventMask = NSOtherMouseUpMask;
744 case VuoMouseButton_Right:
745 eventMask = NSRightMouseUpMask;
748 context->
monitor2 = [NSEvent addLocalMonitorForEventsMatchingMask:NSLeftMouseUpMask handler:^(NSEvent *event) {
749 VuoMouse_fireMouseClickIfNeeded(context, event, window, VuoModifierKey_Control, singleClicked, doubleClicked, tripleClicked);
754 case VuoMouseButton_Any:
755 eventMask = NSLeftMouseUpMask | NSOtherMouseUpMask | NSRightMouseUpMask;
759 context->
monitor = [NSEvent addLocalMonitorForEventsMatchingMask:eventMask handler:^(NSEvent *event) {
760 VuoMouse_fireMouseClickIfNeeded(context, event, window, modifierKey, singleClicked, doubleClicked, tripleClicked);
784 context->
window = windowRef;
804 [NSEvent removeMonitor:context->monitor];
809 [NSEvent removeMonitor:context->monitor2];
817 dispatch_group_wait(context->
clickGroup, DISPATCH_TIME_FOREVER);
828 [view removeTouchesMovedTrigger:context->touchesMoved zoomed:context->zoomed swipedLeft:context->swipedLeft swipedRight:context->swipedRight];
867 |NSLeftMouseDraggedMask|NSRightMouseDraggedMask|NSOtherMouseDraggedMask
868 |NSLeftMouseDownMask|NSOtherMouseDownMask|NSRightMouseDownMask
869 |NSLeftMouseUpMask|NSOtherMouseUpMask|NSRightMouseUpMask
870 handler:^(NSEvent *event) {
872 NSPoint p = [event locationInWindow];
873 NSWindow *window = [event window];
876 NSRect rectInWindow = NSMakeRect(p.x, p.y, 0, 0);
877 VuoMouseStatus_position = [window convertRectToScreen:rectInWindow].origin;
880 VuoMouseStatus_position = p;
882 switch ([event type])
884 case NSLeftMouseDown: if (!VuoMouse_isResizing()) VuoMouseStatus_leftButton = true; break;
885 case NSLeftMouseUp: VuoMouseStatus_leftButton = false; break;
886 case NSOtherMouseDown: if (!VuoMouse_isResizing()) VuoMouseStatus_middleButton = true; break;
887 case NSOtherMouseUp: VuoMouseStatus_middleButton = false; break;
888 case NSRightMouseDown: if (!VuoMouse_isResizing()) VuoMouseStatus_rightButton = true; break;
889 case NSRightMouseUp: VuoMouseStatus_rightButton = false; break;
907 [NSEvent removeMonitor:VuoMouseStatus_monitor];
929 bool onlyUpdateWhenActive)
931 if (onlyUpdateWhenActive)
933 __block
bool isActive;
935 isActive = [NSApp isActive];
941 bool shouldTrackPresses;
951 NSRect rectInScreen = NSMakeRect(pointInScreen.x, pointInScreen.y, 0, 0);
952 __block NSPoint pointInWindow;
953 __block
bool isKeyWindow;
955 pointInWindow = [targetWindow convertRectFromScreen:rectInScreen].origin;
956 isKeyWindow = targetWindow.isKeyWindow;
959 shouldTrackPresses = shouldTrackPresses && isKeyWindow;
965 pointInScreen.y = CGDisplayPixelsHigh(CGMainDisplayID()) - pointInScreen.y;
968 shouldTrackPresses =
true;
971 if ( !shouldTrackPresses)
986 case VuoMouseButton_Left:
989 case VuoMouseButton_Right:
1000 case VuoMouseButton_Middle:
1003 case VuoMouseButton_Any: