Dismiss Custom Window for NSStatusItem
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 h开发者_开发问答oping 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
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
精彩评论