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".
目前,macOS支持窗口选项卡,我们可以将多个窗口合并到一个窗口的选项卡中。现在,如果我们右键单击选项卡,它会在上下文菜单中显示默认菜单项,例如“关闭选项卡”,“关闭其他选项卡”,“将选项卡移动到新窗口”。但是,Safari选项卡还有一个附加菜单项作为“Pin Tab”,而Xcode选项卡还有一个附加项目为“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.
我想在我的mac应用程序中实现类似的功能。如何在我的应用程序中向此上下文菜单添加其他菜单项。我查看了NSWindow,NSWindowController和NSDocument的文档,但没有提到有关此上下文菜单的任何内容。如果实现了类似功能的人可以分享一些关于如何处理这个问题的想法,那将会非常有用。
1 个解决方案
#1
1
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.
您可以观察NSMenuDidBeginTrackingNotification通知。它会在菜单出现之前触发。您可以直接将项目添加到菜单中,也可以指定一个委托并将其添加到menuNeedsUpdate:方法中。请注意不要多次添加项目,因为每次菜单打开前都会触发通知。
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.
请注意,我在自定义的NSWindow子类中尝试了此代码。您可能还想检查哪个NSMenu正在发送通知 - 根据您的应用程序,它可能是不同的上下文菜单,主菜单等。
#1
1
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.
您可以观察NSMenuDidBeginTrackingNotification通知。它会在菜单出现之前触发。您可以直接将项目添加到菜单中,也可以指定一个委托并将其添加到menuNeedsUpdate:方法中。请注意不要多次添加项目,因为每次菜单打开前都会触发通知。
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.
请注意,我在自定义的NSWindow子类中尝试了此代码。您可能还想检查哪个NSMenu正在发送通知 - 根据您的应用程序,它可能是不同的上下文菜单,主菜单等。