简体   繁体   中英

Add additional menu items to the contextual menu on right click on NSWindow tabs

Currently macOS supports window tabbing and we can merge multiple windows into tabs on a single window. Right now if we do a right click on the tab, it shows default menu items in contextual menu such as "Close Tabs", "Close Other Tabs", "Move Tab to New Window". However Safari tabs has one additional menu item as "Pin Tab" and Xcode tabs has additional item as "New Tab".

在此处输入图片说明 在此处输入图片说明

I would like to achieve something similar to this in my mac application. How do I add additional menu items to this contextual menu in my application. I have looked into the documentation for NSWindow , NSWindowController and NSDocument but none of it mentions anything about this contextual menu. It would be really helpful if someone who has implemented something similar can share some ideas about how to approach this.

You can observe the NSMenuDidBeginTrackingNotification notification. It will fire before the menu appears. You can add you items to the menu directly, or assign a delegate and add them in the menuNeedsUpdate: method. Be careful not to add your items multiple times, as the notification will fire before the menu opens each time.

The target of the menu item is automatically set to the window represented by the tab. Here is a complete example:

@implementation TabbedWindow

BOOL didAddMenuItem;

- (void)awakeFromNib
{
    [self toggleTabBar:self];

    self.title = [[NSUUID UUID] UUIDString];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(menuDidStartTracking:) name:@"NSMenuDidBeginTrackingNotification" object:nil];
}

- (IBAction)newWindowForTab:(id)sender
{
    TabbedWindowController* twc = [[TabbedWindowController alloc] initWithWindowNibName:@"TabbedWindowController"];
    [self addTabbedWindow:twc.window ordered:NSWindowAbove];
    [twc.window makeKeyAndOrderFront:nil];
}

- (void)menuDidStartTracking:(NSNotification*)sender
{
    if(didAddMenuItem)
        return;

    NSMenu *tabMenu = (NSMenu *)sender.object;

    NSMenuItem *myMenuItem = [[NSMenuItem alloc] initWithTitle:@"My cool item" action:@selector(myCoolAction:) keyEquivalent:@""];

    NSMenuItem *anotherItem = [tabMenu itemAtIndex:0];
    myMenuItem.target = anotherItem.target;

    [tabMenu addItem:myMenuItem];

    didAddMenuItem = YES;
}

- (void)myCoolAction:(id)sender
{
    NSLog(@"You clicked on the tab for: %@", self.title);
}

Note that I tried this code in a custom NSWindow subclass. You may also want to check which NSMenu is sending the notification - depending on your app, it could be a different context menu, the main menu, etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM