cocoaeventsinput-method-kit

IMKit to catch NSKeyup event


As an experiment, I am trying to achieve the following:

I was thinking of handling the keydown and keyup event, but apparently handleEvent:client: in IMKServerInput Protocol seems to only catch key down and mouse events.

Without much experience with cocoa, I’ve tried some methods with no success:

I reached to a conclusion that IMKit is only capable of passively receiving events. Since it is not an application, there is no keyUp: method to override - AFAIK, IMKit does not inherit NSResponder class.

Unfortunately cocoa is way too broad and has much less (or overflowed with non-helping) documentations for a novice like me to dive in.

Can anyone help me to the right direction?


Solution

  • I tried all possible alternatives one by one, and eventually achieved it by creating a global EventTap with CGEventTap.

    The code basically looks like this:

    // Create an event tap.
    CGEventMask eventMask = ((1 << kCGEventKeyDown) | (1 << kCGEventKeyUp));
    CFMachPortRef eventTap = CGEventTapCreate(kCGSessionEventTap,
                                kCGHeadInsertEventTap,
                                0,
                                eventMask,
                                myCGEventCallback,
                                NULL);
    
    if (!eventTap) {
        NSLog(@"failed to create event tap\n");
        return NO;
    } else {
        // Create a run loop source.
        runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
        // Add to the current run loop.
        CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
        // Enable the event tap.
        CGEventTapEnable(eventTap, true);
        return YES;
    }
    

    where myCGEventCallback handles the global states.

    Meanwhile here are some of what I've found out: