CGEventTapCreate and CFMachPortCreateRunLoopSource fails EXC_BAD_ACCESS

1.6k Views Asked by At

I am trying to tap into the HID events of OSX. I found a snippet for testing it. However my code always seem to fail with EXC_BAD_ACCESS at the CFMachPortCreateRunLoopSource line. It seems that downEventTap is null. Reading the documentation tells me that this needs to be run on the main thread, I am pretty sure I am on the main thread, and wrapping things up in dispatch_async(dispatch_get_main_queue(), ^{ still gives me null. I am calling listen from application didFinishLaunching and added

@interface AppDelegate (){
  CFRunLoopSourceRef downSourceRef;
}

This is how I think creating an Event tap is to be done:

CGEventRef onKeyDown(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
  NSLog(@"DOWN (%lli)", CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode));
  // When it matches, I return CGEventCreate(NULL) to stop the event
  return event;
}
-(void)listen{

  CFMachPortRef downEventTap = CGEventTapCreate(kCGHIDEventTap,kCGHeadInsertEventTap,kCGEventTapOptionDefault,CGEventMaskBit(kCGEventKeyDown),&onKeyDown,(__bridge void *)(self));
  downSourceRef = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, downEventTap, 0); //<-- Crash exc_bad_access: downEventTap = 0x0,downSourceRef= 0x0
  CFRelease(downEventTap);
  CFRunLoopAddSource(CFRunLoopGetCurrent(), downSourceRef, kCFRunLoopDefaultMode);
  CFRelease(downSourceRef);
}
1

There are 1 best solutions below

1
On BEST ANSWER

You most likely do not have the permissions required to tap the event which causes CGEventTapCreate to return NULL, which causes CFMachPortCreateRunLoopSource to segfault when trying to dereference said NULL.