Accessing touch events in a global monitor throws an error

747 Views Asked by At

I'm writing a MacOs app where I'm trying to get the position of a touch in the trackpad. For example the left bottom corner would be 0,0 and the top right would be 100,100.

I want to get that information for touches that happen out of my application, so I'm using a global monitor.

I've found some information and read official documentation (with an impressive lack of examples), but I still can get this to work. I'm getting an error any time I try to access the method allTouches() from the event. Here's the code:

import Cocoa

class ViewController: NSViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        NSEvent.addGlobalMonitorForEvents(matching: NSEvent.EventTypeMask.leftMouseDown) {event in
            let touch = event.allTouches()
        }
    }
}

I'm getting the following error:

2018-11-17 12:49:08.693873+0000 App[76030:1935325] [default] Unable to load Info.plist exceptions (eGPUOverrides)
2018-11-17 12:49:09.910842+0000 App[76030:1935325] *** Assertion failure in -[NSEvent touchesMatchingPhase:inView:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/AppKit/AppKit-1671/AppKit.subproj/NSEvent.m:4752
2018-11-17 12:49:09.910996+0000 App[76030:1935325] [General] An uncaught exception was raised
2018-11-17 12:49:09.911019+0000 App[76030:1935325] [General] Invalid message sent to event "NSEvent: type=LMouseDown loc=(760.789,273.406) time=414257.3 flags=0 win=0x0 winNum=42380 ctxt=0x0 evNum=30352 click=1 buttonNumber=0 pressure=1 deviceID:0x200000001000000 subtype=NSEventSubtypeTouch"
2018-11-17 12:49:09.913059+0000 App[76030:1935325] [General] (
    0   CoreFoundation                      0x00007fff32b6943d __exceptionPreprocess + 256
    1   libobjc.A.dylib                     0x00007fff5ea76720 objc_exception_throw + 48
    2   CoreFoundation                      0x00007fff32b8408e +[NSException raise:format:arguments:] + 98
    3   Foundation                          0x00007fff34f2055d -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 194
    4   AppKit                              0x00007fff303e3cd2 -[NSEvent touchesMatchingPhase:inView:] + 494
    5   App                             0x00000001000018a2 _T07App14ViewControllerC11viewDidLoadyyFySo7NSEventCcfU_ + 34
    6   App                             0x0000000100001c4e _T0So7NSEventCIxx_ABIyBy_TR + 62
    7   AppKit                              0x00007fff3063f2b5 GlobalObserverHandler + 117
    8   HIToolbox                           0x00007fff31d468d9 _ZL23DispatchEventToHandlersP14EventTargetRecP14OpaqueEventRefP14HandlerCallRec + 1502
    9   HIToolbox                           0x00007fff31d45c16 _ZL30SendEventToEventTargetInternalP14OpaqueEventRefP20OpaqueEventTargetRefP14HandlerCallRec + 371
    10  HIToolbox                           0x00007fff31d45a9c SendEventToEventTargetWithOptions + 45
    11  HIToolbox                           0x00007fff31d62c54 _ZL29ToolboxEventDispatcherHandlerP25OpaqueEventHandlerCallRefP14OpaqueEventRefPv + 1336
    12  HIToolbox                           0x00007fff31d46d0c _ZL23DispatchEventToHandlersP14EventTargetRecP14OpaqueEventRefP14HandlerCallRec + 2577
    13  HIToolbox                           0x00007fff31d45c16 _ZL30SendEventToEventTargetInternalP14OpaqueEventRefP20OpaqueEventTargetRefP14HandlerCallRec + 371
    14  HIToolbox                           0x00007fff31d631cd SendEventToEventTarget + 39
    15  AppKit                              0x00007fff30005b36 _DPSNextEvent + 1472
    16  AppKit                              0x00007fff300046fa -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1362
    17  AppKit                              0x00007fff2fffe75d -[NSApplication run] + 699
    18  AppKit                              0x00007fff2ffede97 NSApplicationMain + 780
    19  App                             0x00000001000039ed main + 13
    20  libdyld.dylib                       0x00007fff5fb44085 start + 1
)

What am I doing wrong and how do I fix it?

1

There are 1 best solutions below

2
On

allTouches is not valid for mouse down events, only from within NSEventTypeGesture events, as noted by the comment in the header file:

/* Only valid for NSEventTypeGesture events. Equivalent to [event
touchesMatchingPhase:NSTouchPhaseAny inView:nil] */
- (NSSet <NSTouch *> *)allTouches NS_AVAILABLE_MAC(10_12);

For the NSEvent.EventTypeMask.leftMouseDown you are asking to be notified of the following are the primary properties you will likely want to access:

/* these messages are valid for all mouse down/up/drag events */
@property (readonly) NSInteger clickCount;
@property (readonly) NSInteger buttonNumber;    // for NSOtherMouse events, but will return valid constants for NSLeftMouse and NSRightMouse
…
/* -pressure is valid for all mouse down/up/drag events, and is also valid for NSEventTypeTabletPoint events on 10.4 or later and NSEventTypePressure on 10.10.3 or later */
@property (readonly) float pressure;
/* -locationInWindow is valid for all mouse-related events */
@property (readonly) NSPoint locationInWindow;

If you are actually trying to get gestures then use the NSEventTypeGesture mask. Then you can use allTouches and touchesForView. Note you may need to distinguish between gesture scroll related events and other gestures, depending on your situation and goals.