Show Window without activating (keep application below it active)

こ雲淡風輕ζ 提交于 2021-02-07 13:10:05

问题


I need to show a window (without title bar) above third party applications without my window taking focus.

I have tried using an NSPanel and setting enabling non-activating, but that didn't help.

I tried orderFront:self, but that didn't help either.

I always needed to add [NSApp activateIgnoringOtherApps:YES]; because the window wouldn't show otherwise.

I have here a sample project for just this functionality:
http://users.telenet.be/prullen/TopW2.zip

UIElement is set to true in the application's plist file, so there is no dock. You can activate the window by pressing ALT + SPACE at the same time. You will see that the app below it looses focus. Any thoughts on how to fix this? I've seen other apps do it so I know it's possible.

Edit: here's the code so far. Remember the window is a non-activating NSPanel. I still need that last NSApp activateIgnoringOtherApps line or otherwise it doesn't display. But of course that makes the window the active one.

 _windowController = [[MyWindowController alloc] initWithWindowNibName:@"MyWindowController"];

    [[_windowController window] setLevel:NSNormalWindowLevel+1];
    [[_windowController window] orderFrontRegardless];

    [_windowController showWindow:self];

   [NSApp activateIgnoringOtherApps:YES];

I've also subclassed NSPanel and added two methods:

- (BOOL)canBecomeKeyWindow
{
    return YES;
}

- (BOOL)canBecomeMainWindow
{
    return YES;
}

Edit: OK, unchecking setHidesOnDeactivate fixes this, but now the window will never hide. I need it to hide when the user presses the app below it or switches to another app.

Edit 2: OK, this seems to fix the above issue:

- (void)awakeFromNib
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(hideWindow) name:NSWindowDidResignKeyNotification object:nil];
}
- (void)hideWindow {
    [self setHidesOnDeactivate:YES];
}

Not sure if there's a better way.

And for those that want to know how to display the window:

    [[_windowController window] setLevel:NSPopUpMenuWindowLevel];
    [[_windowController window] orderFrontRegardless];
    [[_windowController window] makeKeyWindow];

    [_windowController showWindow:self];

回答1:


Either one of these should do the trick:

  • Use -[NSWindow orderFrontRegardless] to get a normal level window to the front without activating the corresponding app, or
  • Use -[NSWindow setLevel:] to increase the window level to something higher than NSNormalWindowLevel



回答2:


Not to take away from @puzzle's useful answer, but it sounds like your problem has something to do with using an NSPanel instead of an NSWindow.

The "How Panels Work" docs say:

  • Onscreen panels, except for alert dialogs, are removed from the screen when the application isn’t active and are restored when the application again becomes active. This reduces screen clutter.
  • Specifically, the NSWindow implementation of the hidesOnDeactivate method returns NO, but the NSPanel implementation of the same method returns YES.

So perhaps you could override hidesOnDeactivate to return NO, or change to NSWindow



来源:https://stackoverflow.com/questions/15077471/show-window-without-activating-keep-application-below-it-active

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