显示窗口未激活(保持其下方的应用程序处于活动状态)

问题描述:

我需要在第三方应用程序上方显示一个窗口(不带标题栏),而我的窗口不会聚焦.

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

我尝试使用 NSPanel 并设置启用非激活功能,但这无济于事.

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

我尝试了 orderFront:self ,但这也无济于事.

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

我总是需要添加 [NSApp activateIgnoringOtherApps:YES]; ,因为否则该窗口将不会显示.

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

我这里有一个仅用于此功能的示例项目:
http://users.telenet.be/prullen/TopW2.zip

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

UIElement 设置为 true ,因此没有停靠.您可以通过同时按 ALT +空格来激活窗口.您会看到它下面的应用失去了焦点.有关如何解决此问题的任何想法?我见过其他应用程序可以做到这一点,所以我知道这是可能的.

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.

这是到目前为止的代码.请记住,该窗口是非激活的NSPanel.我仍然需要最后一个 NSApp activateIgnoringOtherApps 行,否则它不会显示.但这当然使窗口成为活动窗口.

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];

我还继承了NSPanel并添加了两个方法:

I've also subclassed NSPanel and added two methods:

- (BOOL)canBecomeKeyWindow
{
    return YES;
}

- (BOOL)canBecomeMainWindow
{
    return YES;
}

好的,取消选中setHidesOnDeactivate可以解决此问题,但是现在窗口永远不会隐藏.当用户按下其下方的应用程序或切换到另一个应用程序时,我需要将其隐藏.

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];

以下任一方法都可以解决问题:

Either one of these should do the trick:

  • 使用-[NSWindow orderFrontRegardless] 将普通级别的窗口显示在最前面,而无需激活相应的应用程序,或者
  • 使用-[NSWindow setLevel:] 将窗口级别提高到高于 NSNormalWindowLevel
  • 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