Showing a modal NSWindow, without activating the other application windows

六月ゝ 毕业季﹏ 提交于 2019-11-27 15:11:28

问题


I have an NSStatusItem that is properly displaying in the MenuBar. One of the items (when clicked) displays a modal NSWindow from my application, which is meant to perform a one-off task, then disappear. (Eg. the user enters a small bit of text, clicks "Save", and the modal NSWindow goes away.)

The issue occurs when the application is running in the background. The modal window properly appears above whatever application is running in the foreground, but when the user clicks the "Save" button, the rest of the application's windows also are made active. This is undesirable, as the user then has to click back to whatever app they were using. (Destroying the convenience of the NSStatusItem.) I'm displaying the modal window using:

[myWindow setFrame:finalRect display:YES animate:NO];
[myWindow setLevel:NSPopUpMenuWindowLevel];
[NSApp runModalForWindow:myWindow];

Is there any way to prevent clicks/events in my popup window from causing the rest of the application to become active? Or a way to let NSApp know that this particular panel shouldn't automatically activate the rest of the app? Thanks!


回答1:


Instead of creating an NSWindow, create an NSPanel with the style NSNonactivatingPanelMask. You can then do the usual makeKeyAndOrderFront: and orderOut: to show/hide panel as needed.




回答2:


NSApp's beginModalSessionForWindow, runModalSession, endModalSession are methods you need.

Have a look here for example how to use it: Creating a fully customized NSAlert




回答3:


A solution by Ken Thomases on the cocoa-dev list a couple years ago looks applicable here too:

[[NSApplication sharedApplication] hide:self];
[[NSApplication sharedApplication] performSelector:@selector(unhideWithoutActivation) 
                                        withObject:nil 
                                        afterDelay:0.05];

Which in theory tells the application to hide itself and unhide at the bottom of the window stack.

You could also intercept the mouse click event and use [NSApp preventWindowOrdering]




回答4:


You can try something like:

...
if ([NSApp isHidden])
    [myWindow makeKeyAndOrderFront:self];
else
    [NSApp runModalForWindow:myWindow];
... 

and when finish:

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


来源:https://stackoverflow.com/questions/4484521/showing-a-modal-nswindow-without-activating-the-other-application-windows

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!