Is there an easy way to know when a NSWindow was closed using the close button (of the window title bar) .
Using NSWindowDelegate and the windowWillClose:(NSNotification *)notification method I get notification of each closing. But how can I know the closing request was send by the close button
Use [yourWindow standardWindowButton:NSWindowCloseButton] to find the close button, then change its target and action to a custom method.
Related
How can I get an event or notification after a NSWindow is closed? The nearest thing that I can find is the windowWillClose: method in NSWindowDelegate. But this method is called when the NSWindow is about to close, not after it is closed. Should I just use this method? Is there a better way to do this?
Yes, you should use either -windowWillClose: or the NSWindowWillCloseNotification. It's sent before the window is closed because the window object might be deallocated after it's closed and there would be no good way to refer to the window at that point. It shouldn't matter from your code's point of view, though.
I want to create a borderless window floating above the main window. The main window should be the key window (I want it to handle the keyboard and mouse events). Also, the floating window should close as the user clicks outside of it. Basically, I'm creating a very custom context menu, just like NSMenu. It should behave likewise.
So I created my window this way:
NSWindow *menuWindow = [NSWindow windowWithContentViewController:menuViewController];
menuWindow.styleMask = NSBorderlessWindowMask;
menuWindow.level = NSFloatingWindowLevel;
[menuWindow makeKeyAndOrderFront:self];
That works perfectly, but how do I handle clicks outside to close it? The window doesn't invoke delegate's windowDidResignKey, because it's not a key window. If it does overload canBecomeKeyWindow (so that it returns YES), then the floating window grabs the user input, which is not what I want.
So, is there any way to automatically close a borderless window? Can NSPanel help? I tried using it, but with no success (the becomesKeyOnlyIfNeeded selector doesn't do what I need).
To detect clicks outside the window but within your app, you could install an event monitor using +[NSEvent addLocalMonitorForEventsMatchingMask:handler:]. If you also want to close the window when the user clicks in a different app, you could observe the NSApplicationDidResignActiveNotification notification.
NSWindow has a property hidesOnDeactivate that should do this for you.
From the Apple Docs:
The value of this property is true if the window is removed from the
screen when its application is deactivated; false if it remains
onscreen. The default value for NSWindow is false; the default value
for NSPanel is true.
In my MAC app, in one use case, I prompt an window to the user and give him 2 options (say buttons Save and Cancel). I want to force the user to select either of the 2 buttons to close the window.
But currently I find that if the user hits "Command + w" key when window has the focus, the window gets closed. In the .xib resource file, I uncheck the "close" option but that only disables the close option in the window UI.
How do I make sure that my window ignores the "Command+w" key and stays as is without closing.
Have also tried removing the notification by adding below code in awakeFromNib method but did not help.
[[NSNotificationCenter defaultCenter] removeObserver:NSWindowWillCloseNotification ];
Have also tried to implement "windowShouldClose" delegate method and return NO, but this method is never called. The documentation too says that this method is not reliable.
You should use an NSAlert for this sort of prompt, probably run as a sheet on the window. That would avoid the problem of closing it.
In any case, the window's delegate can implement -windowShouldClose: to control if a window is allowed to close. You can make an object (often the window controller) be its delegate by declaring that it adopts the NSWindowDelegate protocol and connecting the window's delegate outlet to that object.
I recently had to solve a similar problem. I'm not sure that this is the 'right' way to do it. But it worked for my purposes, and might work for you.
By default, I think, the 'Close Window' (CMD+W) menu item is bound to the action 'performClose' on first-responder. If you remove this binding and instead bind to a custom IBAction on your application delegate or main window controller, it allows you to conditionally call the close method of the current key-window if it is not matching the instance that you want to keep alive.
#property (strong, nonatomic) MyWindowController *unstoppable;
-(IBAction)killActiveWindow:(id)sender
{
NSWindow *keyWindow = [[NSApplication sharedApplication]keyWindow];
if ([keyWindow isNotEqualTo: unstoppable.window]){
NSLog(#" CMD+W Closing Window %#",keyWindow.title);
[keyWindow close];
}
}
The question
What happens when one click on the red button to close the window attached to an NSDocument?
What methods are called on which object?
Can I hook up somewhere in the process?
Why I ask this question:
When I click on the red button here of the window attached to the NSDocument, the panel
does not show up. I want to debug this, and that's why I need to know the process of actions raised by this click.
More info
I put a breaking point in - (void)windowWillClose:. When it stops here, the window seems to be already closed and if I ask p (bool) [self isDocumentEdited], I get true.
I have a dialog window that can be cancelled through a custom Cancel button or using the system red window button. I need to perform some simple logic when the dialog is cancelled. How do I detect that the user has pressed the red button?
I know I can detect the window being closed using the -windowWillClose: delegate callback. But this callback is also called when I close the window programmatically after the dialog succeeds. I also know I could simply set up a BOOL flag, but is there a better solution? It would be best if I could detect the red button activation.
Define close button:
NSButton *closeButton = [self standardWindowButton:NSWindowCloseButton];
Connect close button to custom selector:
[closeButton setTarget:self.delegate];
[closeButton setAction:#selector(closeThisWindow)];
Run specific code and close window manually.
-(void)closeThisWindow {
//
// The NSWindowCloseButton has been clicked.
// Code to be run before the window closes.
//
[self close];
}