Search code examples
cocoakeyboard-shortcutsnsmenuitem

NSMenuItem KeyEquivalent " "(space) bug


I want to set key equivalent " "(space) without any modifiers for NSMenuItem (in App Main Menu).

As follows from documentation:

For example, in an application that plays media, the Play command may be mapped to just “ ” (space), without the command key. You can do this with the following code:

[menuItem setKeyEquivalent:@" "];

[menuItem setKeyEquivalentModifierMask:0];

Key Equivalent sets successfully, but it don't work. When I press "Space" key without modifiers nothing happens, but it's works when i press "Space" with "Fn" modifier key.

I need to use "Space" without modifiers. Any help please!


Solution

  • I had the same problem. I haven't investigated very hard, but as far as I can tell, the spacebar doesn't "look" like a keyboard shortcut to Cocoa so it gets routed to -insertText:. My solution was to subclass the NSWindow, catch it as it goes up the responder chain (presumably you could subclass NSApp instead), and send it off to the menu system explicitly:

    - (void)insertText:(id)insertString
    {
        if ([insertString isEqual:@" "]) {
            NSEvent *fakeEvent = [NSEvent keyEventWithType:NSKeyDown
                                                  location:[self mouseLocationOutsideOfEventStream]
                                             modifierFlags:0
                                                 timestamp:[[NSProcessInfo processInfo] systemUptime]
                                              windowNumber:self.windowNumber
                                                   context:[NSGraphicsContext currentContext]
                                                characters:@" "
                               charactersIgnoringModifiers:@" "
                                                 isARepeat:NO
                                                   keyCode:49];
            [[NSApp mainMenu] performKeyEquivalent:fakeEvent];
        } else {
            [super insertText:insertString];
        }
    }