1
0
Fork 0

Avoid crash on Cmd-Q exit of the app on macOS

On this code path, AppKit uses exit, rather than letting main run as
normal. We handle most things via C++ destructors, which do run, but
Qt is happier if we clean it up explicitly.
This commit is contained in:
James Turner 2019-04-17 17:37:22 +01:00
parent e2ed179f4c
commit 79562bcf31
3 changed files with 72 additions and 1 deletions

View file

@ -41,4 +41,10 @@ SGPath platformDefaultDataPath();
*/
void transformToForegroundApp();
#endif // of FG_GUI_COCOA_HELPERS_H
/**
* 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

View file

@ -17,6 +17,8 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include <config.h>
#include "CocoaHelpers.h"
#include "CocoaHelpers_private.h"
@ -34,11 +36,18 @@
// simgear
#include <simgear/misc/sg_path.hxx>
#include <simgear/debug/logstream.hxx>
#include <simgear/structure/commands.hxx>
// flightgear
#include <GUI/MessageBox.hxx>
#include <Main/options.hxx>
#include <Main/locale.hxx>
#include <Main/globals.hxx>
#if defined(HAVE_QT)
# include <GUI/QtLauncher.hxx>
#endif
NSString* stdStringToCocoa(const std::string& s)
{
@ -165,3 +174,51 @@ void transformToForegroundApp()
[[NSApplication sharedApplication] activateIgnoringOtherApps: YES];
}
@interface FlightGearNSAppDelegate : NSObject <NSApplicationDelegate>
@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
}

View file

@ -61,6 +61,10 @@
#include <QCoreApplication>
#endif
#if defined(SG_MAC)
# include <GUI/CocoaHelpers.h>
#endif
// Static linking of OSG needs special macros
#ifdef OSG_LIBRARY_STATIC
#include <osgDB/Registry>
@ -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);
}