plasma5-workspace/0002-Add-platform-detection-to-KWorkspace-library-to-adju.patch
Luca Beltrame fb44578e9c Accepting request 590845 from home:Vogtinator:qxcbonwayland
- Add patches to not set QT_QPA_PLATFORM in a wayland session:
  * 0001-Call-KLocalizedString-setApplicationDomain-after-Q-A.patch
  * 0002-Add-platform-detection-to-KWorkspace-library-to-adju.patch
  * 0003-No-longer-export-QT_QPA_PLATFORM-env-variable-to-the.patch
  * 0001-Set-XDG_SESSION_TYPE-wayland-in-startplasmacomposito.patch
- Set GDK_BACKEND=x11 to work around GTK3 bugs:
  * 0001-Set-GTK_BACKEND-x11-in-a-wayland-session.patch
- Add a suffix to the wayland session's name:
  * 0001-Add-suffix-to-the-wayland-session-s-name.patch
- Apply upstream patches before downstream patches

OBS-URL: https://build.opensuse.org/request/show/590845
OBS-URL: https://build.opensuse.org/package/show/KDE:Frameworks5/plasma5-workspace?expand=0&rev=388
2018-03-24 21:06:03 +00:00

524 lines
18 KiB
Diff

From 909eff21cca3cdb08ed683b126d83e20aa266608 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Fl=C3=B6ser?= <mgraesslin@kde.org>
Date: Sun, 25 Feb 2018 09:15:07 +0100
Subject: [PATCH 2/3] Add platform detection to KWorkspace library to adjust
QT_QPA_PLATFORM
Summary:
This is a preparation step to unset QT_QPA_PLATFORM from the wayland
startup session script. Setting QT_QPA_PLATFORM breaks 3rd-party Qt
software which does not bundle QtWayland. Most prominent example is
the Qt installer itself (see
https://bugreports.qt.io/browse/QTBUG-60222).
On the other hand our Plasma workspace applications need to be forced to
Wayland on a Wayland system. So we have a conflict between we want to
set QT_QPA_PLATFORM and we don't want to set QT_QPA_PLATFORM.
This change adds new API to KWorkspace to address this problem. The new
method adjusts the QT_QPA_PLATFORM based on the XDG_SESSION_TYPE
enviornment variable. It is completely opt-in. Meaning applications need
to explicitly add the call prior to creating the QGuiApplication and if
the user specifies either QT_QPA_PLATFORM env variable or any of the
-platform command line argument variants, the platform detection is
skipped.
The change also adjusts all plasma-workspace applications which should
use Wayland on Wayland to use the new API. The startup script on the
other hand still sets QT_QPA_PLATFORM. We also have applications outside
of plasma-workspace which needs this detection. Examples are:
* powerdevil
* systemsettings
* kinfocenter
Once this change is merged those applications can be adjusted by linking
against PW::KWorkspace and afterwards QT_QPA_PLATFORM can be unset from
startplasmacompositor.
Test Plan: See added autotest
Reviewers: #plasma
Subscribers: plasma-devel
Tags: #plasma
Differential Revision: https://phabricator.kde.org/D10816
---
krunner/CMakeLists.txt | 3 +-
krunner/main.cpp | 2 +
ksmserver/logout-greeter/main.cpp | 1 +
ksmserver/switchuser-greeter/main.cpp | 1 +
ksplash/ksplashqml/CMakeLists.txt | 1 +
ksplash/ksplashqml/main.cpp | 3 +
kuiserver/CMakeLists.txt | 1 +
kuiserver/main.cpp | 3 +
libkworkspace/CMakeLists.txt | 4 +
libkworkspace/autotests/CMakeLists.txt | 5 +
libkworkspace/autotests/testPlatformDetection.cpp | 128 ++++++++++++++++++++++
libkworkspace/kworkspace.cpp | 24 ++++
libkworkspace/kworkspace.h | 15 +++
shell/CMakeLists.txt | 1 +
shell/main.cpp | 2 +
startkde/kcminit/CMakeLists.txt | 4 +-
startkde/kcminit/main.cpp | 2 +
systemmonitor/CMakeLists.txt | 1 +
systemmonitor/main.cpp | 3 +
19 files changed, 201 insertions(+), 3 deletions(-)
create mode 100644 libkworkspace/autotests/CMakeLists.txt
create mode 100644 libkworkspace/autotests/testPlatformDetection.cpp
diff --git a/krunner/CMakeLists.txt b/krunner/CMakeLists.txt
index c73216e4..46aa92f8 100644
--- a/krunner/CMakeLists.txt
+++ b/krunner/CMakeLists.txt
@@ -23,6 +23,7 @@ target_link_libraries(krunner
KF5::Crash
KF5::WaylandClient
KF5::QuickAddons
+ PW::KWorkspace
)
target_compile_definitions(krunner PRIVATE -DPROJECT_VERSION="${PROJECT_VERSION}")
@@ -38,4 +39,4 @@ ecm_configure_package_config_file(KRunnerAppDBusInterfaceConfig.cmake.in
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/KRunnerAppDBusInterfaceConfig.cmake
DESTINATION ${CMAKECONFIG_INSTALL_DIR})
-add_subdirectory(update)
\ No newline at end of file
+add_subdirectory(update)
diff --git a/krunner/main.cpp b/krunner/main.cpp
index 24fe5a9f..06bf47c0 100644
--- a/krunner/main.cpp
+++ b/krunner/main.cpp
@@ -33,6 +33,7 @@
#include <kdeclarative/qmlobject.h>
#include <KQuickAddons/QtQuickSettings>
+#include <kworkspace.h>
#include "view.h"
@@ -43,6 +44,7 @@ int main(int argc, char **argv)
qunsetenv("QT_DEVICE_PIXEL_RATIO");
QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling);
+ KWorkSpace::detectPlatform(argc, argv);
QQuickWindow::setDefaultAlphaBuffer(true);
QApplication app(argc, argv);
KLocalizedString::setApplicationDomain("krunner");
diff --git a/ksmserver/logout-greeter/main.cpp b/ksmserver/logout-greeter/main.cpp
index a94442be..369bc08f 100644
--- a/ksmserver/logout-greeter/main.cpp
+++ b/ksmserver/logout-greeter/main.cpp
@@ -166,6 +166,7 @@ int main(int argc, char *argv[])
// Qt does not currently (5.9.4) support fullscreen on xdg_shell v6.
qputenv("QT_WAYLAND_SHELL_INTEGRATION", "wl-shell");
+ KWorkSpace::detectPlatform(argc, argv);
QQuickWindow::setDefaultAlphaBuffer(true);
QApplication app(argc, argv);
diff --git a/ksmserver/switchuser-greeter/main.cpp b/ksmserver/switchuser-greeter/main.cpp
index cbacb9fc..22200a43 100644
--- a/ksmserver/switchuser-greeter/main.cpp
+++ b/ksmserver/switchuser-greeter/main.cpp
@@ -138,6 +138,7 @@ int main(int argc, char *argv[])
// Qt does not currently (5.9.4) support fullscreen on xdg_shell v6.
qputenv("QT_WAYLAND_SHELL_INTEGRATION", "wl-shell");
+ KWorkSpace::detectPlatform(argc, argv);
QQuickWindow::setDefaultAlphaBuffer(true);
QGuiApplication app(argc, argv);
diff --git a/ksplash/ksplashqml/CMakeLists.txt b/ksplash/ksplashqml/CMakeLists.txt
index 105cd022..b4ad34ef 100644
--- a/ksplash/ksplashqml/CMakeLists.txt
+++ b/ksplash/ksplashqml/CMakeLists.txt
@@ -16,6 +16,7 @@ target_link_libraries(ksplashqml
KF5::QuickAddons
KF5::WaylandClient
KF5::WindowSystem
+ PW::KWorkspace
)
install(TARGETS ksplashqml ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
diff --git a/ksplash/ksplashqml/main.cpp b/ksplash/ksplashqml/main.cpp
index 25faacde..a97c3d60 100644
--- a/ksplash/ksplashqml/main.cpp
+++ b/ksplash/ksplashqml/main.cpp
@@ -23,6 +23,8 @@
#include <QTextStream>
+#include <kworkspace.h>
+
#include <iostream>
#include <unistd.h>
@@ -88,6 +90,7 @@ int main(int argc, char **argv)
//enable to send log output to /tmp/ksplash
//which is useful for debugging
// qInstallMsgHandler(myMessageHandler);
+ KWorkSpace::detectPlatform(argc, argv);
QQuickWindow::setDefaultAlphaBuffer(true);
SplashApp app(argc, argv);
diff --git a/kuiserver/CMakeLists.txt b/kuiserver/CMakeLists.txt
index 7e79076e..4787b828 100644
--- a/kuiserver/CMakeLists.txt
+++ b/kuiserver/CMakeLists.txt
@@ -60,6 +60,7 @@ endif ()
target_link_libraries(kdeinit_kuiserver5
+ PW::KWorkspace
Qt5::DBus
KF5::ConfigWidgets
KF5::DBusAddons
diff --git a/kuiserver/main.cpp b/kuiserver/main.cpp
index 2d8a5b6f..07df24a6 100644
--- a/kuiserver/main.cpp
+++ b/kuiserver/main.cpp
@@ -27,12 +27,15 @@
#include <kdbusservice.h>
+#include <kworkspace.h>
+
#include <QCommandLineParser>
Q_LOGGING_CATEGORY(KUISERVER, "kuiserver", QtInfoMsg)
extern "C" Q_DECL_EXPORT int kdemain(int argc, char **argv)
{
+ KWorkSpace::detectPlatform(argc, argv);
QApplication app(argc, argv);
app.setApplicationName(QStringLiteral("kuiserver"));
app.setApplicationVersion(QStringLiteral("2.0"));
diff --git a/libkworkspace/CMakeLists.txt b/libkworkspace/CMakeLists.txt
index b31ffc69..0f779040 100644
--- a/libkworkspace/CMakeLists.txt
+++ b/libkworkspace/CMakeLists.txt
@@ -73,3 +73,7 @@ install(EXPORT libkworkspaceLibraryTargets
NAMESPACE PW::
DESTINATION ${CMAKECONFIG_INSTALL_DIR}
FILE LibKWorkspaceLibraryTargets.cmake )
+
+if(BUILD_TESTING)
+ add_subdirectory(autotests)
+endif()
diff --git a/libkworkspace/autotests/CMakeLists.txt b/libkworkspace/autotests/CMakeLists.txt
new file mode 100644
index 00000000..4409dc6d
--- /dev/null
+++ b/libkworkspace/autotests/CMakeLists.txt
@@ -0,0 +1,5 @@
+include(ECMMarkAsTest)
+add_executable(testPlatformDetection testPlatformDetection.cpp)
+target_link_libraries(testPlatformDetection Qt5::Test PW::KWorkspace)
+add_test(NAME kworkspace-testPlatformDetection COMMAND testPlatformDetection)
+ecm_mark_as_test(testPlatformDetection)
diff --git a/libkworkspace/autotests/testPlatformDetection.cpp b/libkworkspace/autotests/testPlatformDetection.cpp
new file mode 100644
index 00000000..8e06afb1
--- /dev/null
+++ b/libkworkspace/autotests/testPlatformDetection.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2018 Martin Flöser <mgraesslin@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3, or any
+ * later version accepted by the membership of KDE e.V. (or its
+ * successor approved by the membership of KDE e.V.), which shall
+ * act as a proxy defined in Section 6 of version 3 of the license.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <QtTest/QtTest>
+
+#include "../kworkspace.h"
+
+#include <vector>
+
+class TestPlatformDetection : public QObject
+{
+ Q_OBJECT
+private Q_SLOTS:
+ void init();
+ void testPlatformSelection_data();
+ void testPlatformSelection();
+ void testArguments_data();
+ void testArguments();
+ void testQtQpaPlatformIsSet_data();
+ void testQtQpaPlatformIsSet();
+};
+
+void TestPlatformDetection::init()
+{
+ qunsetenv("QT_QPA_PLATFORM");
+ qunsetenv("XDG_SESSION_TYPE");
+}
+
+void TestPlatformDetection::testPlatformSelection_data()
+{
+ QTest::addColumn<QByteArray>("xdgSessionType");
+ QTest::addColumn<QByteArray>("expectedQtQpaPlatform");
+
+ QTest::newRow("wayland") << QByteArrayLiteral("wayland") << QByteArrayLiteral("wayland");
+ QTest::newRow("x11") << QByteArrayLiteral("x11") << QByteArrayLiteral("xcb");
+ QTest::newRow("unknown") << QByteArrayLiteral("mir") << QByteArray();
+}
+
+void TestPlatformDetection::testPlatformSelection()
+{
+ QVERIFY(!qEnvironmentVariableIsSet("QT_QPA_PLATFORM"));
+ QFETCH(QByteArray, xdgSessionType);
+ qputenv("XDG_SESSION_TYPE", xdgSessionType);
+
+ std::vector<QByteArray> cppArgv{
+ QByteArrayLiteral("testPlatformDetction")
+ };
+ std::vector<char*> argv;
+ for (QByteArray &arg : cppArgv) {
+ argv.push_back(arg.data());
+ }
+ KWorkSpace::detectPlatform(1, argv.data());
+ QTEST(qgetenv("QT_QPA_PLATFORM"), "expectedQtQpaPlatform");
+}
+
+void TestPlatformDetection::testArguments_data()
+{
+ QTest::addColumn<QByteArray>("arg");
+
+ QTest::newRow("-platform") << QByteArrayLiteral("-platform");
+ QTest::newRow("--platform") << QByteArrayLiteral("--platform");
+ QTest::newRow("-platform=wayland") << QByteArrayLiteral("-platform=wayland");
+ QTest::newRow("--platform=wayland") << QByteArrayLiteral("--platform=wayland");
+}
+
+void TestPlatformDetection::testArguments()
+{
+ QVERIFY(!qEnvironmentVariableIsSet("QT_QPA_PLATFORM"));
+ qputenv("XDG_SESSION_TYPE", "wayland");
+
+ QFETCH(QByteArray, arg);
+ std::vector<QByteArray> cppArgv{
+ QByteArrayLiteral("testPlatformDetction"),
+ arg,
+ QByteArrayLiteral("wayland")
+ };
+ std::vector<char*> argv;
+ for (QByteArray &arg : cppArgv) {
+ argv.push_back(arg.data());
+ }
+ KWorkSpace::detectPlatform(3, argv.data());
+ QVERIFY(!qEnvironmentVariableIsSet("QT_QPA_PLATFORM"));
+}
+
+void TestPlatformDetection::testQtQpaPlatformIsSet_data()
+{
+ QTest::addColumn<QByteArray>("qtQpaPlatform");
+ QTest::addColumn<QByteArray>("xdgSessionType");
+
+ QTest::newRow("xcb - x11") << QByteArrayLiteral("xcb") << QByteArrayLiteral("x11");
+ QTest::newRow("xcb - wayland") << QByteArrayLiteral("xcb") << QByteArrayLiteral("wayland");
+ QTest::newRow("wayland - x11") << QByteArrayLiteral("wayland") << QByteArrayLiteral("x11");
+ QTest::newRow("wayland - wayland") << QByteArrayLiteral("wayland") << QByteArrayLiteral("wayland");
+ QTest::newRow("windows - x11") << QByteArrayLiteral("windows") << QByteArrayLiteral("x11");
+}
+
+void TestPlatformDetection::testQtQpaPlatformIsSet()
+{
+ // test verifies that if QT_QPA_PLATFORM is set the env variable does not get adjusted
+ QFETCH(QByteArray, qtQpaPlatform);
+ QFETCH(QByteArray, xdgSessionType);
+ qputenv("QT_QPA_PLATFORM", qtQpaPlatform);
+ qputenv("XDG_SESSION_TYPE", xdgSessionType);
+
+ KWorkSpace::detectPlatform(0, nullptr);
+ QCOMPARE(qgetenv("QT_QPA_PLATFORM"), qtQpaPlatform);
+}
+
+QTEST_GUILESS_MAIN(TestPlatformDetection)
+
+#include "testPlatformDetection.moc"
diff --git a/libkworkspace/kworkspace.cpp b/libkworkspace/kworkspace.cpp
index 444270d8..5b0b2505 100644
--- a/libkworkspace/kworkspace.cpp
+++ b/libkworkspace/kworkspace.cpp
@@ -260,6 +260,30 @@ void propagateSessionManager()
#endif
}
+void detectPlatform(int argc, char **argv)
+{
+ if (qEnvironmentVariableIsSet("QT_QPA_PLATFORM")) {
+ return;
+ }
+ for (int i = 0; i < argc; i++) {
+ if (qstrcmp(argv[i], "-platform") == 0 ||
+ qstrcmp(argv[i], "--platform") == 0 ||
+ QByteArray(argv[i]).startsWith("-platform=") ||
+ QByteArray(argv[i]).startsWith("--platform=")) {
+ return;
+ }
+ }
+ const QByteArray sessionType = qgetenv("XDG_SESSION_TYPE");
+ if (sessionType.isEmpty()) {
+ return;
+ }
+ if (qstrcmp(sessionType, "wayland") == 0) {
+ qputenv("QT_QPA_PLATFORM", "wayland");
+ } else if (qstrcmp(sessionType, "x11") == 0) {
+ qputenv("QT_QPA_PLATFORM", "xcb");
+ }
+}
+
} // end namespace
diff --git a/libkworkspace/kworkspace.h b/libkworkspace/kworkspace.h
index 6cfc94fe..44025674 100644
--- a/libkworkspace/kworkspace.h
+++ b/libkworkspace/kworkspace.h
@@ -150,6 +150,21 @@ namespace KWorkSpace
*/
KWORKSPACE_EXPORT void propagateSessionManager();
+ /**
+ * Performs platform detection and adjusts QT_QPA_PLATFORM environment
+ * variable to either xcb or wayland depending on the detected platform.
+ *
+ * The detection is based on the XDG_SESSION_TYPE environment variable.
+ * The detection is skipped in case QT_QPA_PLATFORM is already set or
+ * if one of the command line arguments contains the "-platform" variable.
+ *
+ * In order to make use of this function, it has to be invoked before the
+ * QGuiApplication instance is constructed. Invoking after constructing the
+ * QGuiApplication has no effect.
+ * @since 5.13
+ **/
+ KWORKSPACE_EXPORT void detectPlatform(int argc, char **argv);
+
}
#endif
diff --git a/shell/CMakeLists.txt b/shell/CMakeLists.txt
index 04ad01ae..b5f53f84 100644
--- a/shell/CMakeLists.txt
+++ b/shell/CMakeLists.txt
@@ -93,6 +93,7 @@ target_link_libraries(plasmashell
KF5::XmlGui
KF5::Package
KF5::WaylandClient
+ PW::KWorkspace
)
target_include_directories(plasmashell PRIVATE "${CMAKE_BINARY_DIR}")
target_compile_definitions(plasmashell PRIVATE -DPROJECT_VERSION="${PROJECT_VERSION}")
diff --git a/shell/main.cpp b/shell/main.cpp
index 22ef0388..09cca77a 100644
--- a/shell/main.cpp
+++ b/shell/main.cpp
@@ -31,6 +31,7 @@
#include <kdbusservice.h>
#include <klocalizedstring.h>
#include <kcrash.h>
+#include <kworkspace.h>
#include "shellcorona.h"
#include "standaloneappcorona.h"
@@ -56,6 +57,7 @@ int main(int argc, char *argv[])
QQuickWindow::setDefaultAlphaBuffer(true);
+ KWorkSpace::detectPlatform(argc, argv);
QApplication app(argc, argv);
KLocalizedString::setApplicationDomain("plasmashell");
diff --git a/startkde/kcminit/CMakeLists.txt b/startkde/kcminit/CMakeLists.txt
index 783c1966..00f024e9 100644
--- a/startkde/kcminit/CMakeLists.txt
+++ b/startkde/kcminit/CMakeLists.txt
@@ -14,7 +14,7 @@ qt5_add_dbus_interface(kcminit_KDEINIT_SRCS ${klauncher_xml} klauncher_iface)
kf5_add_kdeinit_executable( kcminit ${kcminit_KDEINIT_SRCS})
-target_link_libraries(kdeinit_kcminit Qt5::Core Qt5::Gui Qt5::DBus KF5::CoreAddons KF5::Service KF5::I18n)
+target_link_libraries(kdeinit_kcminit Qt5::Core Qt5::Gui Qt5::DBus KF5::CoreAddons KF5::Service KF5::I18n PW::KWorkspace)
if (XCB_XCB_FOUND)
target_link_libraries(kdeinit_kcminit XCB::XCB)
endif()
@@ -32,7 +32,7 @@ set(kcminit_startup_KDEINIT_SRCS main.cpp)
qt5_add_dbus_interface(kcminit_startup_KDEINIT_SRCS ${klauncher_xml} klauncher_iface)
kf5_add_kdeinit_executable( kcminit_startup ${kcminit_startup_KDEINIT_SRCS})
-target_link_libraries(kdeinit_kcminit_startup Qt5::Core Qt5::Gui Qt5::DBus KF5::CoreAddons KF5::Service KF5::I18n)
+target_link_libraries(kdeinit_kcminit_startup Qt5::Core Qt5::Gui Qt5::DBus KF5::CoreAddons KF5::Service KF5::I18n PW::KWorkspace)
if (XCB_XCB_FOUND)
target_link_libraries(kdeinit_kcminit_startup XCB::XCB)
endif()
diff --git a/startkde/kcminit/main.cpp b/startkde/kcminit/main.cpp
index 7181281c..6ac26bda 100644
--- a/startkde/kcminit/main.cpp
+++ b/startkde/kcminit/main.cpp
@@ -42,6 +42,7 @@
#include <kconfiggroup.h>
#include <klocalizedstring.h>
#include <kservicetypetrader.h>
+#include <kworkspace.h>
static int ready[ 2 ];
static bool startup = false;
@@ -221,6 +222,7 @@ extern "C" Q_DECL_EXPORT int kdemain(int argc, char *argv[])
startup = ( strcmp( argv[ 0 ], "kcminit_startup" ) == 0 ); // started from startkde?
+ KWorkSpace::detectPlatform(argc, argv);
QGuiApplication::setDesktopSettingsAware(false);
QGuiApplication app(argc, argv); //gui is needed for several modules
KLocalizedString::setApplicationDomain("kcminit");
diff --git a/systemmonitor/CMakeLists.txt b/systemmonitor/CMakeLists.txt
index e952d9ed..f925cb63 100644
--- a/systemmonitor/CMakeLists.txt
+++ b/systemmonitor/CMakeLists.txt
@@ -25,6 +25,7 @@ target_link_libraries(systemmonitor
KF5::XmlGui
KF5::GlobalAccel
KF5::WindowSystem
+ PW::KWorkspace
)
install(TARGETS systemmonitor DESTINATION ${KDE_INSTALL_BINDIR})
diff --git a/systemmonitor/main.cpp b/systemmonitor/main.cpp
index ccf6cae7..7311580b 100644
--- a/systemmonitor/main.cpp
+++ b/systemmonitor/main.cpp
@@ -21,10 +21,13 @@
#include <QDBusConnection>
#include <KLocalizedString>
+#include <kworkspace.h>
+
#include "ksystemactivitydialog.h"
int main(int argc, char** argv)
{
+ KWorkSpace::detectPlatform(argc, argv);
QApplication app(argc, argv);
KLocalizedString::setApplicationDomain("systemmonitor");
--
2.16.2