NSMenu programmatically select item
Asked Answered
L

3

11

I'm writing a plugin for application - custom keyboard shortcut. I can traverse through its views. I need to open popup menu, select item in it, then open its submenu and select some item in submenu.

For now I'm only able to open top popup menu by sending performClick: to related NSPopUpButton element.

How can I programmatically select item in menu and open its submenu?

I've tried:

  • call selectItem: on the NSPopUpButton (and related NSMenu). No luck and I see a notion in the doc: "Note that while a menu is tracking user input, programmatic changes to the menu such as adding, removing, or changing items on the menu is not reflected"
  • send keyboard events (using this answer). No luck - may be because I'm holding some keys at the moment of sending those events
  • to find any info on how to do it via Accessibility API, but I just can't find anything on how to use it on current Application (or even on any other application, but with Objective-C)
Lugger answered 5/2, 2014 at 16:58 Comment(3)
have you looked also into performClick:?Inculcate
@Inculcate what do you mean? I'm opening popup menu using performClick: on NSPopUpButtonLugger
opening menu with current selection on nspopupbutton should be done with performClick: which should call performClickWithFrame:inView: on its cell. Correct way in this case should be to first select menuitem on popupbutton and then call perform click. This is because there might custom action (on menuitem) other than on/off which you might accidentally trigger with performActionForItemAtIndexFrancesco
B
9

Use the NSMenu method - (void)performActionForItemAtIndex:(NSInteger)index

NSUInteger idx = [[[menuItem menu] itemArray] indexOfObject:menuItem];
[[menuItem menu] performActionForItemAtIndex:idx];
Boyce answered 20/1, 2015 at 12:8 Comment(0)
F
4

For opening submenu: performActionForItemAtIndex:

For selecting and opening menu: selectItemAtIndex: + performClick:

Do not call performActionForItemAtIndex: on item that does not have submenu cause you might trigger action that might have been set by someone else.

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    NSMenu *menu = self.popup.menu;
    NSMenuItem *item = [menu itemAtIndex:2];
    [item setAction:@selector(terminate:)];
    [item setTarget:NSApp];
}

- (IBAction)action:(id)sender {
    //[self.popup.menu performActionForItemAtIndex:2]; -> if not submenu this will quit your app
    [self.popup selectItemAtIndex:2]; //-> first select menu item
    [self.popup performClick:nil]; //-> open menu - will not quit app
}
Francesco answered 23/1, 2019 at 23:28 Comment(0)
P
1

In addition to @LCC 's answer, you can also call indexOfItem on NSMenu

NSInteger index = [item.menu indexOfItem:item];
[item.menu performActionForItemAtIndex:index];
Poore answered 5/9, 2016 at 19:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.