From db34ddda5335ab3bc90bfd202ba1fe53c8c6bd35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Tue, 21 Apr 2015 11:21:28 +0200 Subject: [PATCH] [wayland] Add positional arguments to be programs to starts This allows to start applications once kwin_wayland is started. E.g. kwin_wayland --libinput --xwayland --framebuffer /usr/bin/startkde Thus it would start startkde once both Wayland Server and Xwayland are up and running and ready for connection. This resolves the problem that prior to startup it is not known which will be the X11 display variable. By passing the environment to the process by KWin this problem is resolved. --- main_wayland.cpp | 22 ++++++++++++++++++++++ main_wayland.h | 4 ++++ 2 files changed, 26 insertions(+) diff --git a/main_wayland.cpp b/main_wayland.cpp index 1b7fef39bc..d6f41a1b1f 100644 --- a/main_wayland.cpp +++ b/main_wayland.cpp @@ -39,6 +39,7 @@ along with this program. If not, see . #include #include #include +#include #include #include #include @@ -214,6 +215,23 @@ void ApplicationWayland::continueStartupWithX() ::exit(1); } + // start the applications passed to us as command line arguments + if (!m_applicationsToStart.isEmpty()) { + QProcessEnvironment environment = QProcessEnvironment::systemEnvironment(); + environment.remove(QStringLiteral("WAYLAND_SOCKET")); + environment.remove(QStringLiteral("QT_QPA_PLATFORM")); + environment.insert(QStringLiteral("DISPLAY"), QString::fromUtf8(qgetenv("DISPLAY"))); + // TODO: maybe create a socket per process? + environment.insert(QStringLiteral("WAYLAND_DISPLAY"), waylandServer()->display()->socketName()); + for (const QString &application: m_applicationsToStart) { + // note: this will kill the started process when we exit + // this is going to happen anyway as we are the wayland and X server the app connects to + QProcess *p = new QProcess(this); + p->setProcessEnvironment(environment); + p->start(application); + } + } + // HACK: create a QWindow in a thread to force QtWayland to create the client buffer integration // this performs an eglInitialize which would block as it does a roundtrip to the Wayland server // in the main thread. By moving into a thread we get the initialize without hitting the problem @@ -425,6 +443,9 @@ KWIN_EXPORT int kdemain(int argc, char * argv[]) i18n("Enable libinput support for input events processing. Note: never use in a nested session.")); parser.addOption(libinputOption); #endif + parser.addPositionalArgument(QStringLiteral("applications"), + i18n("Applications to start once Wayland and Xwayland server are started"), + QStringLiteral("[/path/to/application...]")); parser.process(a); a.processCommandLine(&parser); @@ -468,6 +489,7 @@ KWIN_EXPORT int kdemain(int argc, char * argv[]) } a.setStartXwayland(parser.isSet(xwaylandOption)); + a.setApplicationsToStart(parser.positionalArguments()); a.start(); return a.exec(); diff --git a/main_wayland.h b/main_wayland.h index 647a2da5a4..e97c049930 100644 --- a/main_wayland.h +++ b/main_wayland.h @@ -49,6 +49,9 @@ public: void setFramebuffer(const QString &fbdev) { m_framebuffer = fbdev; } + void setApplicationsToStart(const QStringList &applications) { + m_applicationsToStart = applications; + } protected: void performStartup() override; @@ -66,6 +69,7 @@ private: QByteArray m_x11Display; QByteArray m_waylandDisplay; QString m_framebuffer; + QStringList m_applicationsToStart; }; }