Capturing keystrokes globally (macOS)


#1

I’m trying to capture keystrokes globally on mac.
I’ve been following Theo Watson’s old NoisyTyper project as a base but getting this error:

No matching function for call to 'CGEventTapCreate'

Here’s the code I’m trying to run:

CFMachPortRef eventTap;
CFRunLoopSourceRef runLoopSource;

CGEventRef recordKeysCallback(CGEventTapProxy proxy,
                          CGEventType type,
                          CGEventRef event,
                          void* nothing){

  if (type == kCGEventKeyDown){
    int key = CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode);
    ofLog() << ofToString(key);
  }

  return event;	
}

void ofApp::setup(){
  eventTap = CGEventTapCreate(kCGHIDEventTap,
                            kCGHeadInsertEventTap,
                            0,
                            kCGEventMaskForAllEvents,
                            recordKeysCallback,   // <-- this is the function called
                            NULL);

  // wrap event listener to loopable form
  runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault,
                                              eventTap,
                                              0);
  // add wrapped listener to loop
  CFRunLoopAddSource(CFRunLoopGetCurrent(),
                   runLoopSource,
                   kCFRunLoopCommonModes);

  ProcessSerialNumber psn = { 0, kCurrentProcess };
  OSErr err = SetFrontProcess( & psn );

  // enable event tab
  CGEventTapEnable(eventTap, true);

  // run event tab
  CFRunLoopRun();
}

Any pointers would be greatly appreciated!


#2

I’m also getting this error when capturing keystrokes. Did you solve it?


#3

Hey, I just stumbled the same problem and was able to fix the error by replacing eventTap’s CGEventTapOption 0 with kCGEventTapOptionDefault.

so basically this:

eventTap = CGEventTapCreate(kCGHIDEventTap,
					kCGHeadInsertEventTap,
					kCGEventTapOptionDefault, kCGEventMaskForAllEvents,  recordKeysCallback, NULL);   // <-- this is the function called

Found it going through these docs: https://developer.apple.com/documentation/coregraphics/1454426-cgeventtapcreate?language=objc

Also it seems that now the app needs to be added to your system preferences -> security -> privacy -> accessibility to access keystrokes. And needs to be removed and added everytime you compile it :-S

hope it helps