1

What would be the most appropriate place to intercept CmdAnyKey key events in an NSDocument based application?

Intention is to switch to some component in the active window - kind of like Firefox allows you to switch the tabs - without having a matching shortcut on a menu command to perform that task.

I.e. ideally the framework should do it's normal processing including handling menu commands and just after all other responders fail to respond to that particular shortcut it should be routed to the custom method.

I've searched NSDocument, NSAppDelegate, NSWindowController but couldn't locate any appropriate mechanism to hook into in order to receive these commands on window level.

So lacking any existing customization mechanism does override keyDown: in a custom NSWindowController look like the most appropriate way to achieve the desired effect?

ATV
  • 4,116
  • 3
  • 23
  • 42
  • Have you tried to see if Cntl-Tab (Note: Cntl-Tab, not Cmd-Tab) works automatically? It switches tabs in Safari. Perhaps it's a system-wide shortcut? Also, shouldn't the normal `NSResponder` that would handle such a thing be what you use? – user1118321 Apr 27 '14 at 16:12
  • `NSWindowController` implements `NSResponder`. And Firefox is an example of an app intercepting commands w/o having menu items that would handle that particular hotkey. The question is more general. – ATV Apr 27 '14 at 17:49

1 Answers1

2

Yes, subclassing NSWindow is the way to do this if you need to get the keyboard event after everything up the responder chain refused to handle it.

Here's how I did it in one of my projects:

- (void)keyDown:(NSEvent*)event
{
    SEL keyDownBool = @selector(keyDownBool:);

    if ([[self delegate] respondsToSelector:keyDownBool]
    && [[self delegate] performSelector:keyDownBool withObject:event])
    {
        return;
    }

    [super keyDown:event];
}

My custom keyDownBool: delegate method returned YES if it handled particular key event. Otherwise this method passes key event down to super.

Now I'm using + (id)addLocalMonitorForEventsMatchingMask:(NSEventMask)mask handler:(NSEvent* (^)(NSEvent*))block instead of subclassing. The difference is that it handles (and optionally discards) events before they are dispatched.

pointum
  • 2,987
  • 24
  • 31