I'm trying to add an event trap to enable/disable event from my magic trackpad. I thought this would be straight forward, i.e. register an event trap and when required, discard the event by returning NULL
. The idea is to use the pad for some specific, time consuming data entry, the applications to enter the data into are third party ones so I can't just add code to do want I want there. So i figured I'd monitor the system events and then send the desired input via a bunch of CGEventCreateKeyboardEvent
s.
The problem is returning null does not seem to discard the events, a bit more investigation suggests that this is not restricted to those coming from the trackpad but also my default usb mouse.
My code is below. With what is below i'd expect not to be able to move the mouse, if I change (A) to use kCGEventScrollWheel
or kCGEventLeftMouseDragged
then event is consumed, i.e. scrolling or left btn drag don't occur. Does this mean that not all events can be discarded? Hopefully I'm just missing something obvious here
#define case_print(a) case a: printf("%s - %d\n",#a,a); break;
CGEventRef eventOccurred(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void* refcon) {
int subType = CGEventGetIntegerValueField(event, kCGMouseEventSubtype);
if (type == NSEventTypeGesture || subType == NX_SUBTYPE_MOUSE_TOUCH) {
printf("touchpad\n");
switch(type) {
case_print(kCGEventNull)
case_print(kCGEventLeftMouseDown)
case_print(kCGEventLeftMouseUp)
case_print(kCGEventRightMouseDown)
case_print(kCGEventRightMouseUp)
case_print(kCGEventMouseMoved)
case_print(kCGEventLeftMouseDragged)
case_print(kCGEventRightMouseDragged)
case_print(kCGEventScrollWheel)
case_print(kCGEventOtherMouseDown)
case_print(kCGEventOtherMouseUp)
case_print(kCGEventOtherMouseDragged)
case_print(kCGEventTapDisabledByTimeout)
case_print(kCGEventTapDisabledByUserInput)
case_print(NSEventTypeGesture)
case_print(NSEventTypeMagnify)
case_print(NSEventTypeSwipe)
case_print(NSEventTypeRotate)
case_print(NSEventTypeBeginGesture)
case_print(NSEventTypeEndGesture)
default:
printf("default: %d\n",type);
break;
}
event = NULL;
} else {
if (type == kCGEventMouseMoved) { // (A)
printf("discarding mouse event");
event = NULL;
}
}
return event;
}
CFMachPortRef createEventTap() {
CGEventMask eventMask = NSAnyEventMask;
if (!AXAPIEnabled() && !AXIsProcessTrusted()) {
printf("axapi not enabled");
}
return CGEventTapCreate(kCGHIDEventTap,
kCGHeadInsertEventTap,
kCGEventTapOptionDefault,
eventMask,
eventOccurred,
NULL);
}
int main (int argc, const char * argv[]) {
CFMachPortRef tap = createEventTap();
if (tap) {
CFRunLoopSourceRef rl = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, tap, 0);
CFRunLoopAddSource(CFRunLoopGetMain(), rl, kCFRunLoopCommonModes);
CGEventTapEnable(tap, true);
CFRunLoopRun();
printf("Tap created.\n");
sleep(-1);
} else {
printf("failed!\n");
}
return 0;
}
Note, "axapi not enabled" is not output although i don't think the accessibility option affects anything but the keyboard events.
BTW, I've seen a few similar posts on how to get the events from the touch pad, just nothing applicable to discarding them (other than returning null should work).