Frank
Frank

Reputation:

Closing child windows in Cocoa when the main window is closed

I'm a Cocoa newbie so it is likely that my approach is wrong but ..

I have an app which opens several child windows (after the main/parent window has been loaded) using NSWindowController and initNibWIthName:. This works fine.

But when I close the parent window (using the red x) these remain open and prevent the app from closing until they are closed as well. This makes sense as I am not shutting them anywhere.

But how do I do this? There must be an event that is called at this point but I can't find what it is anywhere.

Notifications such as applicationWillTerminate (and so on) are only called when the application actually is terminating not when the close button has been pressed.

I guess I'm looking for something similar to the Windows WM_CLOSE type messages.

Upvotes: 2

Views: 6241

Answers (3)

mmmmmm
mmmmmm

Reputation: 32661

windowWillClose:

Apple developer docs NSWindowDelegate

Upvotes: 3

Jeremy W. Sherman
Jeremy W. Sherman

Reputation: 36143

The closest equivalent you'll find is the NSWindowWillCloseNotification posted by the window prior to its closing. You can probably get the child windows to close themselves when the parent window closes using:

NSWindow *parentWindow;
NSArray *childWindows;

NSNotificationCenter *noteCenter = [NSNotificationCenter defaultCenter];
for (NSWindow *childWindow in childWindows) {
  [noteCenter
   addObserver:childWindow selector:@selector(close)
   name:NSWindowWillCloseNotification object:parentWindow];
}

If the child window will be deallocated before its parent, be sure to unregister it for notifications before that happens.

The delegate method mentioned by Mark is a convenience method for the delegate that saves them the trouble of registering for a notification they'll likely want anyway. You don't need to create a window controller just to receive that message; simply sending the window [window setDelegate:myObject] will cause myObject to receive the -windowWillClose: message if it responds to the method.

By the way, what Cocoa calls "child windows" differs from what you're thinking of. They're not addressed in the Window Programming Guide, but if you look at the documentation for the related methods on NSWindow, you'll see that they basically track the movements of their parent window, so that they move with it.

If you're coming to Cocoa from Win32 programming, you might find Apple's Porting to Mac OS X from Windows Win32 API helpful to highlight conceptual differences between Win32 and Cocoa.

Upvotes: 4

Peter Hosey
Peter Hosey

Reputation: 96323

Windows and applications are not the same thing in Mac OS X.

If you have a single-window interface, with a main window and no others except for About, Preferences, etc., then you should implement applicationShouldTerminateAfterLastWindowClosed: in your application delegate and return YES. This is the only way (aside from you doing it manually) that closing a window causes the application to quit.

If you have a multiple-window interface (as in a typical document-based application), then you should make all of those windows peers to one another. Windows such as Inspectors and tool palettes should be floating panels, not regular windows. And closing the last window should never, ever quit such an app.

Upvotes: 2

Related Questions