Question

I'm trying to simulate some key presses on Mac OS. This code is supposed to delete one previous character if the 'h' key is pressed (e.g. if user types 'tigh' it will become 'ti') by modifying keyboard events. However it only works with some applications; others totally refuse my events. Is there any problem with this code ?

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    CFMachPortRef      eventTap;
    CGEventMask        eventMask;
    CFRunLoopSourceRef runLoopSource;

    eventMask = ((1 << kCGEventKeyDown) | (1 << kCGEventKeyUp));

    eventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, 0,
                                eventMask, KeyHandler, NULL);
    if (!eventTap) {
        fprintf(stderr, "failed to create event tap\n");
        exit(1);
    }

    runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
    CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);    
    CGEventTapEnable(eventTap, true);
    CFRunLoopRun();
}

CGEventRef KeyHandler(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon)
{
    UniCharCount actualStringLength;
    UniCharCount maxStringLength = 1;    
    UniChar chars[3];

    CGEventKeyboardGetUnicodeString(event, maxStringLength, &actualStringLength, chars);

    if (chars[0] == 'h') {
        chars[0] = '\b';
        CGEventKeyboardSetUnicodeString(event, 1, chars);
        return event;        
    }

    return event;
}
Was it helpful?

Solution

Some applications find what is being typed based on the key code from the event (CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode)), rather than the event's UnicodeString.

That is, you will need to update the event's kCGKeyboardEventKeycode value from the 4 supplied by "h" to 51 or (0x33) for Backspace.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top