Objective c PopupMenuPositionGitem:atLocation:inView:切换到其他应用程序时挂起

Objective c PopupMenuPositionGitem:atLocation:inView:切换到其他应用程序时挂起,objective-c,macos,cocoa,menu,Objective C,Macos,Cocoa,Menu,我正在开发一个无文档的应用程序(LSUIElementtrue)。当用户单击相应的NSStatusItem或使用键盘快捷键时,应用程序会弹出一个菜单 我的问题是,每当用户切换到另一个应用程序(使用⌘-选项卡)而不首先关闭菜单。我已经尝试了PopupMenuPositionGitem:atLocation:inView:,popUpContextMenu:withEvent:forView:,以及NSStatusItem(popUpStatusItemMenu:)上的相应方法 如果用户使用ESC键

我正在开发一个无文档的应用程序(
LSUIElement
true)。当用户单击相应的
NSStatusItem
或使用键盘快捷键时,应用程序会弹出一个菜单

我的问题是,每当用户切换到另一个应用程序(使用⌘-选项卡)而不首先关闭菜单。我已经尝试了
PopupMenuPositionGitem:atLocation:inView:
popUpContextMenu:withEvent:forView:
,以及
NSStatusItem
popUpStatusItemMenu:
)上的相应方法

如果用户使用ESC键关闭菜单,一切正常,但如果用户切换到其他应用程序,上述方法将不会返回(它们似乎同步运行,并在关闭菜单时返回)。应用程序不会崩溃,有几个技巧可以重新获得控制权(调用expoé,或单击弹出菜单的任何
NSStatusItem

如果应用程序具有停靠图标(即将
LSUIElement
设置为false),则问题消失

这是使用键盘快捷键时弹出菜单的代码:

[mainMenu popUpMenuPositioningItem:[mainMenu itemAtIndex:0]
                        atLocation:[NSEvent mouseLocation]
                            inView:nil];
这是单击
NSStatusItem
时菜单中弹出的代码:

- (void)mouseDown:(NSEvent *)event
{
    [statusItem popUpStatusItemMenu:[statusItem menu]];
}
mouseDown:
方法位于附加到
NSStatusItem
的自定义
NSView

你知道怎么解决这个问题吗

谢谢你的帮助

更新
问题还与正在激活的应用程序有关(我在显示菜单之前使用
[NSApp activateIgnoringOtherApps:YES];
,或者在某些情况下无法使用键盘导航菜单)。

问题似乎是由于在同一事件周期中激活应用程序和弹出菜单造成的。我找到了一个解决方法,详细描述见

总之,您需要首先激活应用程序(使用
[NSApp activateIgnoringOtherApps:YES];
),然后弹出菜单,确保这在新的事件周期中发生:您可以使用NSTimer触发菜单来实现这一点

- (void) someMethod {
    // Some code
    [NSApp activateIgnoringOtherApps:YES];
    [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(showMenu) userInfo:nil repeats:NO];
    //Some other code
}

- (void) showMenu {
    // This will show the menu at the current mouse position
    [aMenu popUpMenuPositioningItem:[mainMenu itemAtIndex:0] atLocation:[NSEvent mouseLocation] inView:nil];
}