summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorJohan Klokkhammer Helsing <johan.helsing@qt.io>2018-02-14 15:51:38 +0100
committerJohan Helsing <johan.helsing@qt.io>2018-02-20 09:21:53 +0000
commit093d85393fbacf68028e3b5fd39329878757d603 (patch)
treea315db93791b402ee47c345a3374f09dcdfe52a8 /src/gui
parent3190edb07735bb47b7cf85c582d415ab6487a446 (diff)
Support multiple entries in the Qt platform plugin string
[ChangeLog][QtGui] QT_QPA_PLATFORM and the -platform argument now support a list of platform plugins in prioritized order. Platforms are separated by semicolons. The plugins are tried in the order they are specified as long as all preceding platforms fail gracefully by returning nullptr in the implementation of QPlatformIntegrationPlugin::create() This is useful on Linux distributions where the Wayland plugin may be installed, but is not supported by the current session. i.e. if X11 is running or if the compositor does not provide a compatible shell extension. Example usage: QT_QPA_PLATFORM="wayland;xcb" ./application or ./application -platform "wayland;xcb" Task-number: QTBUG-59762 Change-Id: Ia3f034ec522ed6729d71acf971d172da9e68a5a0 Reviewed-by: Gatis Paeglis <gatis.paeglis@qt.io>
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/kernel/qguiapplication.cpp67
1 files changed, 40 insertions, 27 deletions
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)
-{
- // 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));
+Q_LOGGING_CATEGORY(lcQpaPluginLoading, "qt.qpa.plugin");
+
+static void init_platform(const QString &pluginNamesWithArguments, const QString &platformPluginPath, const QString &platformThemeName, int &argc, char **argv)
+{
+ 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)) {
+ 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 {
+ QGuiApplicationPrivate::platform_name = new QString(name);
+ platformArguments = arguments;
+ break;
+ }
+ }
- // 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 = QStringLiteral("This application failed to start because no Qt platform plugin could be initialized. "
+ "Reinstalling the application may fix this problem.\n");
- 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");
- } 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));
- }
+ 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();