As you found in the documentation for the NSEvent
class' addGlobalMonitorForEventsMatchingMask:handler:
, this limitation is by design.
However, you can work around it by using the IOKit framework (specifically the IOHID portions) to receive low level device events/interrupts. I just had to do this recently for tracking some specific keypresses during mouse-drags.
The basic gist is to create an IOHID manager with IOHIDManagerCreate()
, then add the type(s) of devices to the manager that it should "monitor" with IOHIDManagerSetDeviceMatchingMultiple()
, register a callback with the manager via IOHIDManagerRegisterInputValueCallback()
, schedule the proper run-loop for the manager with IOHIDManagerScheduleWithRunLoop()
, and finally open the manager with IOHIDManagerOpen()
.
To get these low level events during mouse-drags, perform this setup in a separate thread. When scheduling the run-loop for the manager, use CFRunLoopGetCurrent()
to get the run loop for the current thread, and call CFRunLoopRun()
after IOHIDManagerOpen()
.
This guide from Apple can help you get started, along with this Q&A here on Stack Overflow.