diff --git a/FL/mac.H b/FL/mac.H index eba5c9497..e33dc4c16 100644 --- a/FL/mac.H +++ b/FL/mac.H @@ -281,6 +281,14 @@ extern void fl_mac_set_about( Fl_Callback *cb, void *user_data, int shortcut = 0 */ extern int fl_mac_os_version; +/** Determines whether cmd-Q or the "Quit xxx" item of application menu terminates the app or only the event loop. + By default, fl_mac_quit_early = 1, and cmd-Q or "Quit xxx" terminate the app when all windows are closed + without Fl::run() returning. If fl_mac_quit_early is set to 0, cmd-Q or "Quit xxx" terminate only the event loop + when all windows are closed, and Fl::run() returns. + \note This OS-specific variable will not be part of the API of FLTK 1.4. + */ +extern int fl_mac_quit_early; + /** The system menu bar. */ extern class Fl_Sys_Menu_Bar *fl_sys_menu_bar; diff --git a/documentation/src/osissues.dox b/documentation/src/osissues.dox index 829c3d5e7..baa00f112 100644 --- a/documentation/src/osissues.dox +++ b/documentation/src/osissues.dox @@ -732,9 +732,20 @@ Apple "Quit" Event \par When the user presses Cmd-Q or requests a termination of the -application, OS X will send a "Quit" Apple Event. FLTK handles -this event by sending an \c FL_CLOSE event to all open -windows. If all windows close, the application will terminate. +application, FLTK reacts sending an \c FL_CLOSE event to all open +windows. If any window remains open, the termination request aborts, +and the app continues. If all windows close, FLTK default behaviour +is to terminate the application immediately, without letting Fl::run() +return. Consequently, potential cleanup code placed after the Fl::run() +call does not run, and potential global destructors that would run +after main() would return do not run. All code that should run so +the app cleanly terminates must therefore be placed in +window callbacks (which run when windows are closed) or in atexit() +functions. +Alternatively, FLTK can be directed to just terminate the event loop +and therefore let potential cleanup code placed after return from Fl::run() +and from main() execute. This is obtained setting global variable +\ref fl_mac_quit_early to 0. Apple "Open" Event diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm index c8be6c0c6..2e3244980 100644 --- a/src/Fl_cocoa.mm +++ b/src/Fl_cocoa.mm @@ -81,6 +81,7 @@ static unsigned make_current_counts = 0; // if > 0, then Fl_Window::make_current static NSBitmapImageRep* rect_to_NSBitmapImageRep(Fl_Window *win, int x, int y, int w, int h); int fl_mac_os_version = Fl_X::calc_mac_os_version(); // the version number of the running Mac OS X (e.g., 100604 for 10.6.4) +int fl_mac_quit_early = 1; // set it to 0 so cmd-Q does not terminate app but merely terminates the event loop // public variables CGContextRef fl_gc = 0; @@ -1533,7 +1534,7 @@ static FLWindowDelegate *flwindowdelegate_instance = nil; - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender { fl_lock_function(); - NSApplicationTerminateReply reply = NSTerminateNow; + NSApplicationTerminateReply reply = (fl_mac_quit_early ? NSTerminateNow : NSTerminateCancel); while ( Fl_X::first ) { Fl_Window *win = Fl::first_window(); if (win->parent()) win = win->top_window();