显示一个模态NSWindow,而不激活其他应用程序窗口

8
我有一个NSStatusItem在菜单栏中正确显示。其中一个项目(当被点击时)会展示一个模态NSWindow,该窗口旨在执行一次性任务,然后消失。(例如,用户输入少量文本,点击“保存”,模态NSWindow就会消失。)
问题出现在应用程序在后台运行时。模态窗口会正确地显示在前台正在运行的任何应用程序上方,但是当用户点击“保存”按钮时,其余应用程序窗口也会变为活动状态。这是不希望的,因为用户随后必须点击回到他们正在使用的应用程序。(破坏了NSStatusItem的便利性。)我使用以下方式显示模态窗口:
[myWindow setFrame:finalRect display:YES animate:NO];
[myWindow setLevel:NSPopUpMenuWindowLevel];
[NSApp runModalForWindow:myWindow];

有没有办法防止我的弹出窗口中的点击/事件导致应用程序其余部分变为活动状态?或者有没有一种方法让NSApp知道这个特定面板不应该自动激活应用程序的其余部分?谢谢!
4个回答

19

不要创建一个 NSWindow,而是创建一个带有样式 NSNonactivatingPanelMaskNSPanel。然后可以像平常一样使用 makeKeyAndOrderFront:orderOut: 显示/隐藏面板。


3

你需要使用NSApp的beginModalSessionForWindow、runModalSession和endModalSession这些方法。

例如,可以参考这里的示例代码: 如何创建完全自定义的NSAlert


1
几年前,Ken Thomases 在 cocoa-dev 列表上提出的一个解决方案在这里也适用:
[[NSApplication sharedApplication] hide:self];
[[NSApplication sharedApplication] performSelector:@selector(unhideWithoutActivation) 
                                        withObject:nil 
                                        afterDelay:0.05];

理论上,这告诉应用程序隐藏自己并在窗口堆栈底部取消隐藏。
您还可以拦截鼠标单击事件并使用[NSApp preventWindowOrdering]

不,单击该窗口中的任何位置仍会将相关应用程序窗口置于最前面。 - Craig Otis

0
你可以尝试类似这样的代码:
...
if ([NSApp isHidden])
    [myWindow makeKeyAndOrderFront:self];
else
    [NSApp runModalForWindow:myWindow];
... 

并且当完成时:

...
if ([NSApp isHidden])
    [myWindow orderOut:self];
else
    [NSApp stopModal];
... 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接