From 1bd967badbc38edf40dc24152ba4ca494f760685 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 11 Apr 2018 13:59:37 +0200 Subject: Avoid parsing the commandline arguments twice We parse the arguments independently from QApplication and initialize the settings before we create QApplication. Therefore we can parse any setting before creating QApplication which is required for high DPI support. We use the QApplication argument parsing to filter out Qt specific commandline arguments like style. Change-Id: I83ead87476d99351de6fe4f86c96c39a721af47b Reviewed-by: Eike Ziller --- src/app/main.cpp | 141 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 83 insertions(+), 58 deletions(-) (limited to 'src/app') diff --git a/src/app/main.cpp b/src/app/main.cpp index f095e373bc..3660a111e5 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -58,7 +58,9 @@ #include #include -#include +#include +#include +#include #ifdef ENABLE_QT_BREAKPAD #include @@ -146,9 +148,22 @@ static void printHelp(const QString &a0) displayHelpText(help); } +QString applicationDirPath(char *arg = 0) +{ + static QString dir; + + if (arg) + dir = QFileInfo(QString::fromLocal8Bit(arg)).dir().absolutePath(); + + if (QCoreApplication::instance()) + return QApplication::applicationDirPath(); + + return dir; +} + static QString resourcePath() { - return QDir::cleanPath(QCoreApplication::applicationDirPath() + '/' + RELATIVE_DATA_PATH); + return QDir::cleanPath(applicationDirPath() + '/' + RELATIVE_DATA_PATH); } static inline QString msgCoreLoadFailure(const QString &why) @@ -238,7 +253,7 @@ static void setupInstallSettings(QString &installSettingspath) if (installSettings.contains(kInstallSettingsKey)) { QString installSettingsPath = installSettings.value(kInstallSettingsKey).toString(); if (QDir::isRelativePath(installSettingsPath)) - installSettingsPath = QCoreApplication::applicationDirPath() + '/' + installSettingsPath; + installSettingsPath = applicationDirPath() + '/' + installSettingsPath; QSettings::setPath(QSettings::IniFormat, QSettings::SystemScope, installSettingsPath); } } @@ -293,23 +308,12 @@ static inline QSettings *userSettings() return createUserSettings(); } -static void setHighDpiEnvironmentVariable(int argc, char **argv) +static void setHighDpiEnvironmentVariable() { if (Utils::HostOsInfo().isMacHost()) return; - std::vector arguments(argv, argv + argc); - auto it = arguments.begin(); - QString settingsPath; - while (it != arguments.end()) { - const QString &arg = QString::fromStdString(*it); - it = ++it; - if (arg == SETTINGS_OPTION && it != arguments.end()) - settingsPath = QDir::fromNativeSeparators(QString::fromStdString(*it)); - } - if (!settingsPath.isEmpty()) - QSettings::setPath(QSettings::IniFormat, QSettings::UserScope, settingsPath); std::unique_ptr settings(createUserSettings()); const bool defaultValue = Utils::HostOsInfo().isWindowsHost(); @@ -347,8 +351,6 @@ int main(int argc, char **argv) Utils::TemporaryDirectory::setMasterTemporaryDirectory(QDir::tempPath() + "/" + Core::Constants::IDE_CASED_ID + "-XXXXXX"); - setHighDpiEnvironmentVariable(argc, argv); - QLoggingCategory::setFilterRules(QLatin1String("qtc.*.debug=false\nqtc.*.info=false")); #ifdef Q_OS_MAC @@ -360,55 +362,42 @@ int main(int argc, char **argv) setrlimit(RLIMIT_NOFILE, &rl); #endif - SharedTools::QtSingleApplication::setAttribute(Qt::AA_ShareOpenGLContexts); - SharedTools::QtSingleApplication app((QLatin1String(Core::Constants::IDE_DISPLAY_NAME)), argc, argv); - - loadFonts(); - - if (Utils::HostOsInfo().isWindowsHost() - && !qFuzzyCompare(qApp->devicePixelRatio(), 1.0) - && QApplication::style()->objectName().startsWith( - QLatin1String("windows"), Qt::CaseInsensitive)) { - QApplication::setStyle(QLatin1String("fusion")); - } - const int threadCount = QThreadPool::globalInstance()->maxThreadCount(); - QThreadPool::globalInstance()->setMaxThreadCount(qMax(4, 2 * threadCount)); - - const QString libexecPath = QCoreApplication::applicationDirPath() - + '/' + RELATIVE_LIBEXEC_PATH; -#ifdef ENABLE_QT_BREAKPAD - QtSystemExceptionHandler systemExceptionHandler(libexecPath); -#else - // Display a backtrace once a serious signal is delivered (Linux only). - CrashHandlerSetup setupCrashHandler(Core::Constants::IDE_DISPLAY_NAME, - CrashHandlerSetup::EnableRestart, libexecPath); -#endif - - app.setAttribute(Qt::AA_UseHighDpiPixmaps); - // Manually determine -settingspath and -installsettingspath command line options // We can't use the regular way of the plugin manager, because that needs to parse plugin meta data // but the settings path can influence which plugins are enabled QString settingsPath; QString installSettingsPath; QStringList customPluginPaths; - QStringList pluginArguments; - - QStringListIterator it(app.arguments()); - while (it.hasNext()) { - const QString &arg = it.next(); - if (arg == SETTINGS_OPTION && it.hasNext()) - settingsPath = QDir::fromNativeSeparators(it.next()); - else if (arg == INSTALL_SETTINGS_OPTION && it.hasNext()) - installSettingsPath = QDir::fromNativeSeparators(it.next()); - else if (arg == PLUGINPATH_OPTION && it.hasNext()) - customPluginPaths += QDir::fromNativeSeparators(it.next()); - else - pluginArguments.append(arg); + std::vector appArguments; + bool hasTestOption = false; + + auto it = argv; + const auto end = argv + argc; + while (it != end) { + const auto arg = QString::fromLocal8Bit(*it); + const bool hasNext = it + 1 != end; + + if (arg == SETTINGS_OPTION && hasNext) { + ++it; + settingsPath = QDir::fromNativeSeparators(QString::fromLocal8Bit(*it)); + } else if (arg == INSTALL_SETTINGS_OPTION && hasNext) { + ++it; + installSettingsPath = QDir::fromNativeSeparators(QString::fromLocal8Bit(*it)); + } else if (arg == PLUGINPATH_OPTION && hasNext) { + ++it; + customPluginPaths += QDir::fromNativeSeparators(QString::fromLocal8Bit(*it)); + } else { + if (arg == TEST_OPTION) + hasTestOption = true; + appArguments.push_back(*it); + } + ++it; } + applicationDirPath(argv[0]); + QScopedPointer temporaryCleanSettingsDir; - if (settingsPath.isEmpty() && pluginArguments.contains(TEST_OPTION)) { + if (settingsPath.isEmpty() && hasTestOption) { temporaryCleanSettingsDir.reset(new Utils::TemporaryDirectory("qtc-test-settings")); if (!temporaryCleanSettingsDir->isValid()) return 1; @@ -421,11 +410,47 @@ int main(int argc, char **argv) QSettings::setDefaultFormat(QSettings::IniFormat); setupInstallSettings(installSettingsPath); // plugin manager takes control of this settings object - QSettings *settings = userSettings(); + setHighDpiEnvironmentVariable(); + + SharedTools::QtSingleApplication::setAttribute(Qt::AA_ShareOpenGLContexts); + + int numberofArguments = static_cast(appArguments.size()); + + SharedTools::QtSingleApplication app((QLatin1String(Core::Constants::IDE_DISPLAY_NAME)), + numberofArguments, + appArguments.data()); + const QStringList pluginArguments = app.arguments(); + + /*Initialize global settings and resetup install settings with QApplication::applicationDirPath */ + setupInstallSettings(installSettingsPath); + QSettings *settings = userSettings(); QSettings *globalSettings = new QSettings(QSettings::IniFormat, QSettings::SystemScope, QLatin1String(Core::Constants::IDE_SETTINGSVARIANT_STR), QLatin1String(Core::Constants::IDE_CASED_ID)); + loadFonts(); + + if (Utils::HostOsInfo().isWindowsHost() + && !qFuzzyCompare(qApp->devicePixelRatio(), 1.0) + && QApplication::style()->objectName().startsWith( + QLatin1String("windows"), Qt::CaseInsensitive)) { + QApplication::setStyle(QLatin1String("fusion")); + } + const int threadCount = QThreadPool::globalInstance()->maxThreadCount(); + QThreadPool::globalInstance()->setMaxThreadCount(qMax(4, 2 * threadCount)); + + const QString libexecPath = QCoreApplication::applicationDirPath() + + '/' + RELATIVE_LIBEXEC_PATH; +#ifdef ENABLE_QT_BREAKPAD + QtSystemExceptionHandler systemExceptionHandler(libexecPath); +#else + // Display a backtrace once a serious signal is delivered (Linux only). + CrashHandlerSetup setupCrashHandler(Core::Constants::IDE_DISPLAY_NAME, + CrashHandlerSetup::EnableRestart, libexecPath); +#endif + + app.setAttribute(Qt::AA_UseHighDpiPixmaps); + PluginManager pluginManager; PluginManager::setPluginIID(QLatin1String("org.qt-project.Qt.QtCreatorPlugin")); PluginManager::setGlobalSettings(globalSettings); -- cgit v1.2.3