diff --git a/src/GUI/QtFileDialog.cxx b/src/GUI/QtFileDialog.cxx index effae6650..480b2566a 100644 --- a/src/GUI/QtFileDialog.cxx +++ b/src/GUI/QtFileDialog.cxx @@ -40,9 +40,12 @@ void QtFileDialog::exec() int fakeargc = 1; static char fakeargv0[] = "fgfs"; static char * fakeargv[2] = {fakeargv0, 0}; - // This does nothing if it has already been run, so the fake argc/argv - // are only used if run without launcher - flightgear::initApp(fakeargc, fakeargv); + // This does nothing if it has already been run, so the fake argc/argv are + // only used if run without launcher. Don't attempt to initialize the + // QSettings, because this would require FGGlobals to be initialized (for + // globals->get_fg_home()), which would prevent using this function at + // early startup. + flightgear::initApp(fakeargc, fakeargv, false /* doInitQSettings */); // concatenate filter patterns, as Qt uses a single string std::string filter=""; diff --git a/src/GUI/QtLauncher.cxx b/src/GUI/QtLauncher.cxx index 8a1fdacf9..a255a7632 100644 --- a/src/GUI/QtLauncher.cxx +++ b/src/GUI/QtLauncher.cxx @@ -83,6 +83,7 @@ using namespace flightgear; using namespace simgear::pkg; +using std::string; const int MAX_RECENT_AIRCRAFT = 20; const int DEFAULT_MP_PORT = 5000; @@ -505,7 +506,9 @@ static void initQtResources() namespace flightgear { -void initApp(int& argc, char** argv) +// Only requires FGGlobals to be initialized if 'doInitQSettings' is true. +// Safe to call several times. +void initApp(int& argc, char** argv, bool doInitQSettings) { static bool qtInitDone = false; static int s_argc; @@ -525,22 +528,45 @@ void initApp(int& argc, char** argv) app->setApplicationName("FlightGear"); app->setOrganizationDomain("flightgear.org"); - QSettings::setDefaultFormat(QSettings::IniFormat); - QSettings::setPath(QSettings::IniFormat, QSettings::UserScope, - QString::fromStdString(globals->get_fg_home().utf8Str())); - // reset numeric / collation locales as described at: // http://doc.qt.io/qt-5/qcoreapplication.html#details ::setlocale(LC_NUMERIC, "C"); ::setlocale(LC_COLLATE, "C"); - - Qt::KeyboardModifiers mods = app->queryKeyboardModifiers(); - if (mods & (Qt::AltModifier | Qt::ShiftModifier)) { - qWarning() << "Alt/shift pressed during launch"; - QSettings settings; - settings.setValue("fg-root", "!ask"); - } } + + if (doInitQSettings) { + initQSettings(); + } +} + +// Requires FGGlobals to be initialized. Safe to call several times. +void initQSettings() +{ + static bool qSettingsInitDone = false; + + if (!qSettingsInitDone) { + qSettingsInitDone = true; + string fgHome = globals->get_fg_home().utf8Str(); + + QSettings::setDefaultFormat(QSettings::IniFormat); + QSettings::setPath(QSettings::IniFormat, QSettings::UserScope, + QString::fromStdString(fgHome)); + } +} + +bool checkKeyboardModifiersForSettingFGRoot() +{ + initQSettings(); + + Qt::KeyboardModifiers mods = qApp->queryKeyboardModifiers(); + if (mods & (Qt::AltModifier | Qt::ShiftModifier)) { + qWarning() << "Alt/shift pressed during launch"; + QSettings settings; + settings.setValue("fg-root", "!ask"); + return true; + } + + return false; } bool runLauncherDialog() diff --git a/src/GUI/QtLauncher.hxx b/src/GUI/QtLauncher.hxx index bc9d844df..a24d89a1a 100644 --- a/src/GUI/QtLauncher.hxx +++ b/src/GUI/QtLauncher.hxx @@ -23,7 +23,15 @@ namespace flightgear { - void initApp(int& argc, char** argv); + // Only requires FGGlobals to be initialized if 'doInitQSettings' is true. + // Safe to call several times. + void initApp(int& argc, char** argv, bool doInitQSettings = true); + // Requires FGGlobals to be initialized. Safe to call several times. + void initQSettings(); + + // Set 'fg-root' in QSettings to the special value "!ask" if either Alt or + // Shift is pressed. Return true in this case, false otherwise. + bool checkKeyboardModifiersForSettingFGRoot(); bool runLauncherDialog(); diff --git a/src/GUI/QtMessageBox.cxx b/src/GUI/QtMessageBox.cxx index 430bc34d0..d8aa4a609 100644 --- a/src/GUI/QtMessageBox.cxx +++ b/src/GUI/QtMessageBox.cxx @@ -34,9 +34,12 @@ QtMessageBox(const std::string& caption, int fakeargc = 1; static char fakeargv0[] = "fgfs"; static char * fakeargv[2] = {fakeargv0, 0}; - // This does nothing if it has already been run, so the fake argc/argv - // are only used if an error box is triggered in early startup - flightgear::initApp(fakeargc, fakeargv); + // This does nothing if it has already been run, so the fake argc/argv are + // only used if an error box is triggered in early startup. Don't attempt + // to initialize the QSettings, because this would require FGGlobals to be + // initialized (for globals->get_fg_home()), which would prevent using + // this function at early startup. + flightgear::initApp(fakeargc, fakeargv, false /* doInitQSettings */); QMessageBox msgBox; msgBox.setWindowTitle(QString::fromStdString(caption)); msgBox.setText(QString::fromStdString(msg)); diff --git a/src/Main/main.cxx b/src/Main/main.cxx index bed7e2954..2e7997e81 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -495,6 +495,8 @@ int fgMainInit( int argc, char **argv ) #if defined(HAVE_QT) if (showLauncher) { flightgear::initApp(argc, argv); + flightgear::checkKeyboardModifiersForSettingFGRoot(); + if (!flightgear::runLauncherDialog()) { return EXIT_SUCCESS; }