diff --git a/src/GUI/CocoaHelpers.h b/src/GUI/CocoaHelpers.h index 9c999778e..8a23407a6 100644 --- a/src/GUI/CocoaHelpers.h +++ b/src/GUI/CocoaHelpers.h @@ -41,4 +41,10 @@ SGPath platformDefaultDataPath(); */ void transformToForegroundApp(); -#endif // of FG_GUI_COCOA_HELPERS_H \ No newline at end of file +/** + * AppKit shuts us down via exit(), the code in main to cleanup is not run + * in that scenario. Do some cleanup manually to avoid crashes on exit. + */ +void cocoaRegisterTerminateHandler(); + +#endif // of FG_GUI_COCOA_HELPERS_H diff --git a/src/GUI/CocoaHelpers.mm b/src/GUI/CocoaHelpers.mm index 6c91e4906..5ced7bd6c 100644 --- a/src/GUI/CocoaHelpers.mm +++ b/src/GUI/CocoaHelpers.mm @@ -17,6 +17,8 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // +#include + #include "CocoaHelpers.h" #include "CocoaHelpers_private.h" @@ -34,11 +36,18 @@ // simgear #include +#include +#include // flightgear #include #include
#include
+#include
+ +#if defined(HAVE_QT) +# include +#endif NSString* stdStringToCocoa(const std::string& s) { @@ -165,3 +174,51 @@ void transformToForegroundApp() [[NSApplication sharedApplication] activateIgnoringOtherApps: YES]; } + +@interface FlightGearNSAppDelegate : NSObject +@end + +@implementation FlightGearNSAppDelegate + + +// it would be lovely to do the following, but the return code doesn't +// seem to work as documented - maybe it's ignored due to newer process +// management +#if 0 +- (NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication *)sender +{ + SGCommandMgr* mgr = SGCommandMgr::instance(); + SGPropertyNode_ptr propArgs(new SGPropertyNode); + propArgs->setStringValue("dialog-name", "exit"); + mgr->execute("dialog-show", propArgs, globals->get_props()); + + return NSTerminateCancel; +} +#endif + +- (void) applicationWillTerminate:(NSNotification *)notification +{ + SG_LOG(SG_GENERAL, SG_INFO, "macOS quit occuring"); +#if defined(HAVE_QT) + flightgear::shutdownQtApp(); +#endif +} + +@end + +void cocoaRegisterTerminateHandler() +{ + FlightGearNSAppDelegate* delegate = [[FlightGearNSAppDelegate alloc] init]; + + auto *app = [NSApplication sharedApplication]; + [[NSNotificationCenter defaultCenter] + addObserver:delegate + selector:@selector(applicationWillTerminate:) + name:NSApplicationWillTerminateNotification object:app]; +#if 9 + [[NSNotificationCenter defaultCenter] + addObserver:delegate + selector:@selector(applicationShouldTerminate:) + name:NSApplicationWillTerminateNotification object:app]; +#endif +} diff --git a/src/Viewer/fg_os_osgviewer.cxx b/src/Viewer/fg_os_osgviewer.cxx index 1ae4feba4..dbe2db560 100644 --- a/src/Viewer/fg_os_osgviewer.cxx +++ b/src/Viewer/fg_os_osgviewer.cxx @@ -61,6 +61,10 @@ #include #endif +#if defined(SG_MAC) +# include +#endif + // Static linking of OSG needs special macros #ifdef OSG_LIBRARY_STATIC #include @@ -366,6 +370,10 @@ void fgOSInit(int* argc, char** argv) SG_LOG(SG_GL, SG_INFO, "Using stock OSG implementation of GraphicsWindow"); } #endif +#if defined(SG_MAC) + cocoaRegisterTerminateHandler(); +#endif + globals->get_renderer()->init(); WindowSystemAdapter::setWSA(new WindowSystemAdapter); }