[wayland] Improve passing env variables to applications started by KWin

If an env variable is set outside of KWin (e.g. QT_QPA_PLATFORM) we
want KWin to pass the original env variable to the started process and
not pass none instead because it's one of KWin's special changed
variables.

Thus we take the environment before we adjust it and pass that to the
started processes with our own DISPLAY and WAYLAND_DISPLAY added.
This commit is contained in:
Martin Gräßlin 2015-06-29 10:51:37 +02:00
parent 085c77810b
commit fa7b2fd055
2 changed files with 12 additions and 10 deletions

View file

@ -177,12 +177,11 @@ void ApplicationWayland::continueStartupWithX()
if (!m_inputMethodServerToStart.isEmpty()) { if (!m_inputMethodServerToStart.isEmpty()) {
int socket = dup(waylandServer()->createInputMethodConnection()); int socket = dup(waylandServer()->createInputMethodConnection());
if (socket >= 0) { if (socket >= 0) {
QProcessEnvironment environment = QProcessEnvironment::systemEnvironment(); QProcessEnvironment environment = m_environment;
environment.insert(QStringLiteral("WAYLAND_SOCKET"), QByteArray::number(socket)); environment.insert(QStringLiteral("WAYLAND_SOCKET"), QByteArray::number(socket));
environment.insert(QStringLiteral("QT_QPA_PLATFORM"), QStringLiteral("wayland")); environment.insert(QStringLiteral("QT_QPA_PLATFORM"), QStringLiteral("wayland"));
environment.remove("DISPLAY"); environment.remove("DISPLAY");
environment.remove("WAYLAND_DISPLAY"); environment.remove("WAYLAND_DISPLAY");
environment.remove(QStringLiteral("EGL_PLATFORM"));
QProcess *p = new QProcess(this); QProcess *p = new QProcess(this);
p->setProcessEnvironment(environment); p->setProcessEnvironment(environment);
p->start(m_inputMethodServerToStart); p->start(m_inputMethodServerToStart);
@ -192,14 +191,8 @@ void ApplicationWayland::continueStartupWithX()
// start the applications passed to us as command line arguments // start the applications passed to us as command line arguments
if (!m_applicationsToStart.isEmpty()) { if (!m_applicationsToStart.isEmpty()) {
QProcessEnvironment environment = QProcessEnvironment::systemEnvironment(); QProcessEnvironment environment = m_environment;
environment.remove(QStringLiteral("WAYLAND_SOCKET"));
environment.remove(QStringLiteral("QT_QPA_PLATFORM"));
environment.remove(QStringLiteral("QT_WAYLAND_DISABLE_WINDOWDECORATION"));
environment.remove(QStringLiteral("EGL_PLATFORM"));
environment.insert(QStringLiteral("DISPLAY"), QString::fromUtf8(qgetenv("DISPLAY"))); 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) { for (const QString &application: m_applicationsToStart) {
// note: this will kill the started process when we exit // 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 // this is going to happen anyway as we are the wayland and X server the app connects to
@ -315,7 +308,7 @@ void ApplicationWayland::startXwaylandServer()
m_xwaylandProcess = new QProcess(kwinApp()); m_xwaylandProcess = new QProcess(kwinApp());
m_xwaylandProcess->setProgram(QStringLiteral("Xwayland")); m_xwaylandProcess->setProgram(QStringLiteral("Xwayland"));
QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); QProcessEnvironment env = m_environment;
env.insert("WAYLAND_SOCKET", QByteArray::number(wlfd)); env.insert("WAYLAND_SOCKET", QByteArray::number(wlfd));
m_xwaylandProcess->setProcessEnvironment(env); m_xwaylandProcess->setProcessEnvironment(env);
m_xwaylandProcess->setArguments({QStringLiteral("-displayfd"), m_xwaylandProcess->setArguments({QStringLiteral("-displayfd"),
@ -427,6 +420,9 @@ KWIN_EXPORT int kdemain(int argc, char * argv[])
sigaddset(&userSiganls, SIGUSR2); sigaddset(&userSiganls, SIGUSR2);
pthread_sigmask(SIG_BLOCK, &userSiganls, nullptr); pthread_sigmask(SIG_BLOCK, &userSiganls, nullptr);
QProcessEnvironment environment = QProcessEnvironment::systemEnvironment();
environment.insert(QStringLiteral("WAYLAND_DISPLAY"), server->display()->socketName());
// enforce wayland plugin, unfortunately command line switch has precedence // enforce wayland plugin, unfortunately command line switch has precedence
setenv("QT_QPA_PLATFORM", "wayland", true); setenv("QT_QPA_PLATFORM", "wayland", true);
#if (QT_VERSION < QT_VERSION_CHECK(5, 4, 2)) #if (QT_VERSION < QT_VERSION_CHECK(5, 4, 2))
@ -440,6 +436,7 @@ KWIN_EXPORT int kdemain(int argc, char * argv[])
qputenv("QT_WAYLAND_DISABLE_WINDOWDECORATION", "1"); qputenv("QT_WAYLAND_DISABLE_WINDOWDECORATION", "1");
KWin::ApplicationWayland a(argc, argv); KWin::ApplicationWayland a(argc, argv);
a.setupTranslator(); a.setupTranslator();
a.setProcessStartupEnvironment(environment);
server->setParent(&a); server->setParent(&a);

View file

@ -21,6 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define KWIN_MAIN_WAYLAND_H #define KWIN_MAIN_WAYLAND_H
#include "main.h" #include "main.h"
#include <QtCore/private/qeventdispatcher_unix_p.h> #include <QtCore/private/qeventdispatcher_unix_p.h>
#include <QProcessEnvironment>
class QProcess; class QProcess;
@ -43,6 +44,9 @@ public:
void setInputMethodServerToStart(const QString &inputMethodServer) { void setInputMethodServerToStart(const QString &inputMethodServer) {
m_inputMethodServerToStart = inputMethodServer; m_inputMethodServerToStart = inputMethodServer;
} }
void setProcessStartupEnvironment(const QProcessEnvironment &environment) {
m_environment = environment;
}
bool notify(QObject *o, QEvent *e) override; bool notify(QObject *o, QEvent *e) override;
@ -61,6 +65,7 @@ private:
QStringList m_applicationsToStart; QStringList m_applicationsToStart;
QString m_inputMethodServerToStart; QString m_inputMethodServerToStart;
QProcess *m_xwaylandProcess = nullptr; QProcess *m_xwaylandProcess = nullptr;
QProcessEnvironment m_environment;
}; };
class EventDispatcher : public QEventDispatcherUNIX class EventDispatcher : public QEventDispatcherUNIX