关闭 NSStatusItem 的自定义窗口

发布于 2024-11-25 17:32:43 字数 2777 浏览 0 评论 0原文

单击 NSStatusItem 时会弹出一个自定义窗口。该代码基于 MAAtachedwindow。一切都工作得很好,但当用户单击其他状态栏项目或其他应用程序等其他内容时,我无法找到关闭窗口的方法。

这是我创建窗口的代码:

    statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:width] retain];

    //setup custom status menu view
    CGFloat height = [[NSStatusBar systemStatusBar] thickness];
    NSRect viewFrame = NSMakeRect(0.0f, 0.0f, width, height);
    statusMenuView = [[[_ISStatusMenuView alloc] initWithFrame:viewFrame] retain];
    statusMenuView.offset = aOffset;
    statusItem.view = statusMenuView;

    //setup the window to show when clicked
    NSRect contentRect = NSZeroRect;
    contentRect.size = aView.frame.size;
    statusMenuWindow = [[[NSWindow alloc] initWithContentRect:contentRect
                                   styleMask:NSBorderlessWindowMask
                                     backing:NSBackingStoreBuffered 
                                       defer:NO] retain];

    [statusMenuWindow setLevel:NSPopUpMenuWindowLevel];
    [statusMenuWindow setBackgroundColor:[NSColor clearColor]];
    [statusMenuWindow setMovableByWindowBackground:NO];
    [statusMenuWindow setExcludedFromWindowsMenu:YES];
    [statusMenuWindow setOpaque:NO];
    [statusMenuWindow setHasShadow:NO];
    [statusMenuWindow useOptimizedDrawing:YES];
    [[statusMenuWindow contentView] addSubview:aView];
    [statusMenuWindow setDelegate:self];

    statusMenuView.statusMenuWindow = statusMenuWindow;

以下是我显示窗口的方式:

- (void)centerView{
    NSRect menuFrame = self.window.frame;
    NSRect windowFrame = self.statusMenuWindow.frame;
    NSPoint menuPoint = NSMakePoint(NSMidX(menuFrame), NSMinY(menuFrame));
    menuPoint.x -= windowFrame.size.width*0.5f;
    menuPoint.y -= windowFrame.size.height+self.offset;
    [self.statusMenuWindow setFrameOrigin:menuPoint];
    [self.statusMenuWindow makeKeyAndOrderFront:self];
}

我希望 windowDidResignKey 委托方法能够解决问题,但此配置不会成功。委托正在工作,因为 windowDidMove 确实运行了。

- (void)windowDidResignKey:(NSNotification *)notification{
    NSLog(@"windowDidResignKey");
    [statusMenuView hideView];
}

- (void)windowDidResignMain:(NSNotification *)notification{
    NSLog(@"windowDidResignMain");
}

- (void)windowDidMove:(NSNotification *)notification{
    NSLog(@"windowDidMove");
}

回顾一下,当用户单击其他任何内容时,如何隐藏自定义窗口(标准状态栏菜​​单的工作方式)?

编辑 查看 Popup 示例后我唯一缺少的是我必须将 NSPanel 子类化并使其成为关键窗口。

@interface Panel : NSPanel
@end

@implementation Panel

- (BOOL)canBecomeKeyWindow{
    return YES;
}

@end

I've got a custom window popping up when an NSStatusItem is clicked. The code is based on MAAtachedwindow. Everything is working great but I can't figure out a way to dismiss the window when the user clicks on something else like another status bar item, or another app.

Here's my code for creating the window:

    statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:width] retain];

    //setup custom status menu view
    CGFloat height = [[NSStatusBar systemStatusBar] thickness];
    NSRect viewFrame = NSMakeRect(0.0f, 0.0f, width, height);
    statusMenuView = [[[_ISStatusMenuView alloc] initWithFrame:viewFrame] retain];
    statusMenuView.offset = aOffset;
    statusItem.view = statusMenuView;

    //setup the window to show when clicked
    NSRect contentRect = NSZeroRect;
    contentRect.size = aView.frame.size;
    statusMenuWindow = [[[NSWindow alloc] initWithContentRect:contentRect
                                   styleMask:NSBorderlessWindowMask
                                     backing:NSBackingStoreBuffered 
                                       defer:NO] retain];

    [statusMenuWindow setLevel:NSPopUpMenuWindowLevel];
    [statusMenuWindow setBackgroundColor:[NSColor clearColor]];
    [statusMenuWindow setMovableByWindowBackground:NO];
    [statusMenuWindow setExcludedFromWindowsMenu:YES];
    [statusMenuWindow setOpaque:NO];
    [statusMenuWindow setHasShadow:NO];
    [statusMenuWindow useOptimizedDrawing:YES];
    [[statusMenuWindow contentView] addSubview:aView];
    [statusMenuWindow setDelegate:self];

    statusMenuView.statusMenuWindow = statusMenuWindow;

And here is how I'm showing the window:

- (void)centerView{
    NSRect menuFrame = self.window.frame;
    NSRect windowFrame = self.statusMenuWindow.frame;
    NSPoint menuPoint = NSMakePoint(NSMidX(menuFrame), NSMinY(menuFrame));
    menuPoint.x -= windowFrame.size.width*0.5f;
    menuPoint.y -= windowFrame.size.height+self.offset;
    [self.statusMenuWindow setFrameOrigin:menuPoint];
    [self.statusMenuWindow makeKeyAndOrderFront:self];
}

I was hoping the windowDidResignKey delegate method would do the trick but it doesn't go off with this configuration. The delegate is working because windowDidMove does run.

- (void)windowDidResignKey:(NSNotification *)notification{
    NSLog(@"windowDidResignKey");
    [statusMenuView hideView];
}

- (void)windowDidResignMain:(NSNotification *)notification{
    NSLog(@"windowDidResignMain");
}

- (void)windowDidMove:(NSNotification *)notification{
    NSLog(@"windowDidMove");
}

So to recap, how can I hide my custom window when the user clicks on anything else, the way the standard status bar menus work?

Edit
After looking at the Popup example the only thing I was missing was I had to subclass NSPanel and make it so it could become the key window.

@interface Panel : NSPanel
@end

@implementation Panel

- (BOOL)canBecomeKeyWindow{
    return YES;
}

@end

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

横笛休吹塞上声 2024-12-02 17:32:43

你需要确保你的窗口可以成为关键窗口,并在它放弃关键时调用你的窗口的 orderOut: 方法。如果您还没有使用自定义 NSWindowController,您应该使用自定义 NSWindowController,在这种情况下,您只需调用其“close”方法即可关闭窗口。

我建议您不要发布一堆代码,而是看一下最近发布的这个优秀的将窗口附加到状态项的示例:
Shpakovski 弹出窗口示例

You need to make sure your window can become the key window, and call your window's orderOut: method when it resigns key. You should be using a custom NSWindowController, if you are not already, in which case you would just call its "close" method to dismiss your window.

Instead of posting a bunch of code, I would suggest you just look at this excellent, recently-posted example of attaching a window to a status item:
Shpakovski Popup Window Example

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文