NSBorderlessWindow not responding to CMD-W/CMD-M
I have an NSBorderlessWindow subclass of NSWindow with a transparent and non-opaque background (so it's non-rectangular in appearance). I've added my own buttons to function as the close and minimize buttons when I click them, but for some reason the window will not respond to CMD-W or CMD-M like 开发者_如何学Pythona normal one does. I have my NSWindow subclass set to return YES to canBecomeKeyWindow and canBecomeMainWindow.
My NIB still has all the standard menu items in it that are there when you create a new project - including the "Minimize" item in the Window menu with the default shortcut CMD-M defined. It's hooked up to send performMiniaturize: to the first responder. However it is not enabled when the app is run, so it seems like it must be asking the window if it can minimize and the window says no or something. (I'm still very new to OSX/Cocoa.)
What am I missing?
Also, and maybe this is related, my borderless window has a shadow enabled - but unlike a normal titled window, when I make my window the active/front window by clicking on it, the shadow doesn't change. Normally an OSX focused window has a slightly larger/darker shadow to make it stand out more but mine never changes the shadow. It's like I'm missing something to make the OS treat this window as a real/normal/main window or something and as a result I lose the shadow change and functioning CMD-W/CMD-M.
What you're missing is that when you make a borderless window, you're eliminating the FrameView that standard windows come with, which actually implement the -keyDown: method that receives those keystrokes and miniaturizes or closes the window.
NSWindow itself is actually a fairly lightweight class, and most of what we think of as standard window behavior is done by the frame view.
Could it be that you deleted the File > Close menu item?
By default this has the Cmd-W keyboard shortcut, and is connected to the performClose
target in the first responder.
We fixed this by dragging in the standard File menu from the Library panel in Interface Builder.
I first tried implementing keyDown:
per NSResponder's suggestion, but that didn't do the trick.
I've solved this by simply creating my own IBActions for Close and Minimize. Note that you want to call close
and miniaturize:
on your NSBorderlessWindow, not performClose:
or performMiniaturize:
.
To add to the accepted answer, here is some code which implements performClose:
and performMiniaturize:
in a window subclass. Doing it this way means you don't have to modify the main menu at all.
@interface Window : NSWindow
@end
@implementation Window
- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item
{
if ([item action] == @selector(performClose:))
return YES;
else if ([item action] == @selector(performMiniaturize:))
return YES;
return [super validateUserInterfaceItem:item];
}
- (IBAction)performClose:(id)sender
{
[self close];
}
- (IBAction)performMiniaturize:(id)sender
{
[self miniaturize:sender];
}
@end
精彩评论