objective-cmacoscocoaappkitinput-method-kit

Intercept Command+key with IMKit (or similar)


I was looking to intercept Command key combinations and thought that IMKit would be a good choice. By extending IMKInputController I can intercept most keys but it seems to ignore modified ones.

I've tried overriding

-(BOOL)inputText:(NSString*)string client:(id)sender;

and (alternatively)

-(BOOL)inputText:(NSString*)string 
             key:(NSInteger)keyCode 
       modifiers:(NSUInteger)flags 
          client:(id)sender;

but no luck; the methods just plain aren't called when the modifiers are applied. To be more specific the command and alt key don't get caught by the methods above. Simple modifiers like shift and ctrl work (and the modifier flags variable is set in the second method). Fire up Apple's sample application NumberInput to see for yourself.

Any suggestions? Am I on totally the wrong track?


Solution

  • Short answer:

    Use handleEvent:client: and listen to the NSFlagsChanged event.


    IMKInputController implements the IMKServerInput Protocol, which provides three alternatives to handle an event.

    1. Key binding - using inputText:client: and didCommandBySelector:client:
    2. Text data only - using inputText:key:modifiers:client:
    3. Handle all events - using handleEvent:client:

    Seems like you've only tried the top two. You can achieve the goal with the third option.

    Try the following:

    1. override recognizedEvents: (from IMKStateSetting Protocol)

      - (NSUInteger)recognizedEvents:(id)sender
      {
          return NSKeyDownMask | NSFlagsChangedMask;
      }
      
    2. and use handleEvent:client:

      -(BOOL)handleEvent:(NSEvent*)event client:(id)sender
      {
          NSLog(@"handling event: %@", event);
          return false;
      }
      

    You can see the printout on every keydown and keyup of the modifiers in Console, including command and alt.