Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSMenu with views in a modal NSWindow

I have an issue with selectors not being performed for custom views inside an NSMenuItem when they are displayed from a button within a modal NSWindow.

This appears to be a reproducible issue and I've simplified the issue as much as I can.

Modal window is displayed via.

   [NSApp runModalForWindow:_modalWindow];

The modal window only has a button, and the button is attached to the following selector.

- (IBAction)modalButtonClicked:(id)sender
{
    NSMenu* aMenu = [[NSMenu alloc] initWithTitle:@"Menu"];

    NSMenuItem* aItemA = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
    NSMenuItem* aItemB = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
    NSMenuItem* aItemC = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];

    [aItemA setView:[NSButton buttonWithTitle:@"Item A" target:self action:@selector(menuButtonClicked:)]];
    [aItemB setView:[NSButton buttonWithTitle:@"Item B" target:self action:@selector(menuButtonClicked:)]];
    [aItemC setView:[NSButton buttonWithTitle:@"Item C" target:self action:@selector(menuButtonClicked:)]];

    [aMenu addItem:aItemA];
    [aMenu addItem:aItemB];
    [aMenu addItem:aItemC];

    [NSMenu popUpContextMenu:aMenu withEvent:[NSApp currentEvent] forView:sender];
}

and the menu click event with a breakpoint:

- (void)menuButtonClicked:(id)sender
{
    NSLog(@"%@", sender);
}

Clicking on the button will display a menu with 3 buttons, however nothing happens when you click any of those buttons. @(menuButtonClicked:) is never called. This is only an issue with modal windows but there's no obvious reason why.

like image 413
AndyTang Avatar asked Sep 25 '19 16:09

AndyTang


1 Answers

The documention https://developer.apple.com/documentation/appkit/nsmenuitem/1514843-target?language=objc states:

To ensure that a menu item’s target can receive commands while a modal dialog is open, the target object should return YES in worksWhenModal.

And indeed if one adds:

- (BOOL)worksWhenModal {
    return YES;
}

then it works and your method menuButtonClicked gives out something like:

2019-10-03 22:47:27.892005+0200 MenuTest[12876:454071] <NSButton: 0x600003505760>
like image 137
Stephan Schlecht Avatar answered Nov 07 '22 03:11

Stephan Schlecht