objective-cmacoskeyboard-shortcutscgeventtap

(Mac) Simulating keyboard shortcuts - Arrow keys don't work


I'm trying to use Quartz Event Services to programmatically trigger keyboard shortcuts:

CGEventSourceRef src = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);

CGEventRef leftDown = CGEventCreateKeyboardEvent(src, 0x7b, true); // creating left arrow down event
CGEventRef leftUp = CGEventCreateKeyboardEvent(src, 0x7b, false); // creating left arrow up event

CGEventSetFlags(leftDown, kCGEventFlagMaskCommand); // setting command key modifier flag
CGEventSetFlags(leftUp, kCGEventFlagMaskCommand); // ""

CGEventTapLocation loc = kCGHIDEventTap;
CGEventPost(loc, leftDown);
CGEventPost(loc, leftUp);

CFRelease(leftDown);
CFRelease(leftUp);
CFRelease(src);

This code works for triggering system functions, if you use something other than an arrow key. But if you do use an arrow key, the code will just make your cursor move instead.

Triggering, for example, command-space with this code (0x31, kCGEventFlagMaskCommand) successfully brings up spotlight, but if you map spotlight to command-left_arrow, and then trigger command-left_arrow with this code, it will just make the cursor jump to the start of the line.


Something interesting to note is that Apple Script behaves the exact same way when I try to trigger system shortcuts incorporating arrow keys with it.

Is there a workaround for this?

Thank you for your help, I appreciate it.


Solution

  • For some reasons the arrow keys only work with a "private" CGEventSourceStateID in the way that you expect it. Change the line

    CGEventSourceRef src = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
    

    to

    CGEventSourceRef src = CGEventSourceCreate(kCGEventSourceStatePrivate);
    

    and it will work as expected. (Tested on macOS 10.13.4)