diff --git a/config_help.txt b/config_help.txt index 4be797cc6b..f61601ec7a 100644 --- a/config_help.txt +++ b/config_help.txt @@ -274,7 +274,8 @@ Gui, printing, widget options: (Windows only) -combined-angle-lib .. Merge LibEGL and LibGLESv2 into LibANGLE (Windows only) - -qpa .......... Select default QPA backend (e.g., xcb, cocoa, windows) + -qpa .......... Select default QPA backend(s) (e.g., xcb, cocoa, windows) + A prioritized list separated by semi-colons. -xcb-xlib............. Enable Xcb-Xlib support [auto] Platform backends: diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 183ecc3117..fdc27b760c 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1140,33 +1140,47 @@ QString QGuiApplication::platformName() *QGuiApplicationPrivate::platform_name : QString(); } -static void init_platform(const QString &pluginArgument, const QString &platformPluginPath, const QString &platformThemeName, int &argc, char **argv) +Q_LOGGING_CATEGORY(lcQpaPluginLoading, "qt.qpa.plugin"); + +static void init_platform(const QString &pluginNamesWithArguments, const QString &platformPluginPath, const QString &platformThemeName, int &argc, char **argv) { - // Split into platform name and arguments - QStringList arguments = pluginArgument.split(QLatin1Char(':')); - const QString name = arguments.takeFirst().toLower(); - QString argumentsKey = name; - argumentsKey[0] = argumentsKey.at(0).toUpper(); - arguments.append(QLibraryInfo::platformPluginArguments(argumentsKey)); + QStringList plugins = pluginNamesWithArguments.split(QLatin1Char(';')); + QStringList platformArguments; + QStringList availablePlugins = QPlatformIntegrationFactory::keys(platformPluginPath); + for (auto pluginArgument : plugins) { + // Split into platform name and arguments + QStringList arguments = pluginArgument.split(QLatin1Char(':')); + const QString name = arguments.takeFirst().toLower(); + QString argumentsKey = name; + argumentsKey[0] = argumentsKey.at(0).toUpper(); + arguments.append(QLibraryInfo::platformPluginArguments(argumentsKey)); - // Create the platform integration. - QGuiApplicationPrivate::platform_integration = QPlatformIntegrationFactory::create(name, arguments, argc, argv, platformPluginPath); - if (Q_UNLIKELY(!QGuiApplicationPrivate::platform_integration)) { - QStringList keys = QPlatformIntegrationFactory::keys(platformPluginPath); - - QString fatalMessage; - if (keys.contains(name)) { - fatalMessage = QStringLiteral("This application failed to start because it could not load the Qt platform plugin \"%2\"\nin \"%3\", even though it was found. ").arg(name, QDir::toNativeSeparators(platformPluginPath)); - fatalMessage += QStringLiteral("This is usually due to missing dependencies, which you can verify by setting the env variable QT_DEBUG_PLUGINS to 1.\n\n"); + // Create the platform integration. + QGuiApplicationPrivate::platform_integration = QPlatformIntegrationFactory::create(name, arguments, argc, argv, platformPluginPath); + if (Q_UNLIKELY(!QGuiApplicationPrivate::platform_integration)) { + if (availablePlugins.contains(name)) { + qCInfo(lcQpaPluginLoading).nospace().noquote() + << "Could not load the Qt platform plugin \"" << name << "\" in \"" + << QDir::toNativeSeparators(platformPluginPath) << "\" even though it was found."; + } else { + qCWarning(lcQpaPluginLoading).nospace().noquote() + << "Could not find the Qt platform plugin \"" << name << "\" in \"" + << QDir::toNativeSeparators(platformPluginPath) << "\""; + } } else { - fatalMessage = QStringLiteral("This application failed to start because it could not find the Qt platform plugin \"%2\"\nin \"%3\".\n\n").arg(name, QDir::toNativeSeparators(platformPluginPath)); + QGuiApplicationPrivate::platform_name = new QString(name); + platformArguments = arguments; + break; } + } + + if (Q_UNLIKELY(!QGuiApplicationPrivate::platform_integration)) { + QString fatalMessage = QStringLiteral("This application failed to start because no Qt platform plugin could be initialized. " + "Reinstalling the application may fix this problem.\n"); + + if (!availablePlugins.isEmpty()) + fatalMessage += QStringLiteral("\nAvailable platform plugins are: %1.\n").arg(availablePlugins.join(QLatin1String(", "))); - if (!keys.isEmpty()) { - fatalMessage += QStringLiteral("Available platform plugins are: %1.\n\n").arg( - keys.join(QLatin1String(", "))); - } - fatalMessage += QStringLiteral("Reinstalling the application may fix this problem."); #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) // Windows: Display message box unless it is a console application // or debug build showing an assert box. @@ -1174,11 +1188,10 @@ static void init_platform(const QString &pluginArgument, const QString &platform MessageBox(0, (LPCTSTR)fatalMessage.utf16(), (LPCTSTR)(QCoreApplication::applicationName().utf16()), MB_OK | MB_ICONERROR); #endif // Q_OS_WIN && !Q_OS_WINRT qFatal("%s", qPrintable(fatalMessage)); + return; } - QGuiApplicationPrivate::platform_name = new QString(name); - // Many platforms have created QScreens at this point. Finish initializing // QHighDpiScaling to be prepared for early calls to qt_defaultDpi(). if (QGuiApplication::primaryScreen()) { @@ -1225,9 +1238,9 @@ static void init_platform(const QString &pluginArgument, const QString &platform #ifndef QT_NO_PROPERTIES // Set arguments as dynamic properties on the native interface as // boolean 'foo' or strings: 'foo=bar' - if (!arguments.isEmpty()) { + if (!platformArguments.isEmpty()) { if (QObject *nativeInterface = QGuiApplicationPrivate::platform_integration->nativeInterface()) { - for (const QString &argument : qAsConst(arguments)) { + for (const QString &argument : qAsConst(platformArguments)) { const int equalsPos = argument.indexOf(QLatin1Char('=')); const QByteArray name = equalsPos != -1 ? argument.left(equalsPos).toUtf8() : argument.toUtf8();