[wayland] Pass command line arguments to launched processes
Summary: Since QProcess::setProgram() doesn't split the command, we need to do it ourselves. Test Plan: `dbus-run-session kwin_wayland "kate foo.txt"` works again. Reviewers: #kwin, cblack, davidedmundson, apol Reviewed By: #kwin, cblack, davidedmundson, apol Subscribers: apol, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D29253
This commit is contained in:
parent
d3303bc407
commit
2fa5526f12
1 changed files with 64 additions and 39 deletions
103
main_wayland.cpp
103
main_wayland.cpp
|
@ -33,11 +33,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include <KWayland/Server/display.h>
|
||||
#include <KWayland/Server/seat_interface.h>
|
||||
// KDE
|
||||
#include <KCrash>
|
||||
#include <KLocalizedString>
|
||||
#include <KPluginLoader>
|
||||
#include <KPluginMetaData>
|
||||
#include <KCrash>
|
||||
#include <KQuickAddons/QtQuickSettings>
|
||||
#include <KShell>
|
||||
|
||||
// Qt
|
||||
#include <qplatformdefs.h>
|
||||
|
@ -216,61 +217,85 @@ void ApplicationWayland::continueStartupWithScene()
|
|||
void ApplicationWayland::startSession()
|
||||
{
|
||||
if (!m_inputMethodServerToStart.isEmpty()) {
|
||||
int socket = dup(waylandServer()->createInputMethodConnection());
|
||||
if (socket >= 0) {
|
||||
QProcessEnvironment environment = processStartupEnvironment();
|
||||
environment.insert(QStringLiteral("WAYLAND_SOCKET"), QByteArray::number(socket));
|
||||
environment.insert(QStringLiteral("QT_QPA_PLATFORM"), QStringLiteral("wayland"));
|
||||
environment.remove("DISPLAY");
|
||||
environment.remove("WAYLAND_DISPLAY");
|
||||
QProcess *p = new Process(this);
|
||||
p->setProcessChannelMode(QProcess::ForwardedErrorChannel);
|
||||
connect(p, qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this,
|
||||
[p] {
|
||||
if (waylandServer()) {
|
||||
waylandServer()->destroyInputMethodConnection();
|
||||
QStringList arguments = KShell::splitArgs(m_inputMethodServerToStart);
|
||||
if (!arguments.isEmpty()) {
|
||||
QString program = arguments.takeFirst();
|
||||
int socket = dup(waylandServer()->createInputMethodConnection());
|
||||
if (socket >= 0) {
|
||||
QProcessEnvironment environment = processStartupEnvironment();
|
||||
environment.insert(QStringLiteral("WAYLAND_SOCKET"), QByteArray::number(socket));
|
||||
environment.insert(QStringLiteral("QT_QPA_PLATFORM"), QStringLiteral("wayland"));
|
||||
environment.remove("DISPLAY");
|
||||
environment.remove("WAYLAND_DISPLAY");
|
||||
QProcess *p = new Process(this);
|
||||
p->setProcessChannelMode(QProcess::ForwardedErrorChannel);
|
||||
connect(p, qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this,
|
||||
[p] {
|
||||
if (waylandServer()) {
|
||||
waylandServer()->destroyInputMethodConnection();
|
||||
}
|
||||
p->deleteLater();
|
||||
}
|
||||
p->deleteLater();
|
||||
}
|
||||
);
|
||||
p->setProcessEnvironment(environment);
|
||||
p->setProgram(m_inputMethodServerToStart);
|
||||
p->start();
|
||||
p->waitForStarted(); //do we really need to wait?
|
||||
);
|
||||
p->setProcessEnvironment(environment);
|
||||
p->setProgram(program);
|
||||
p->setArguments(arguments);
|
||||
p->start();
|
||||
p->waitForStarted(); //do we really need to wait?
|
||||
}
|
||||
} else {
|
||||
qWarning("Failed to launch the input method server: %s is an invalid command",
|
||||
qPrintable(m_inputMethodServerToStart));
|
||||
}
|
||||
}
|
||||
|
||||
// start session
|
||||
if (!m_sessionArgument.isEmpty()) {
|
||||
QProcess *p = new Process(this);
|
||||
p->setProcessChannelMode(QProcess::ForwardedErrorChannel);
|
||||
p->setProcessEnvironment(processStartupEnvironment());
|
||||
connect(p, qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this, [p] (int code, QProcess::ExitStatus status) {
|
||||
p->deleteLater();
|
||||
if (status == QProcess::CrashExit) {
|
||||
qWarning() << "Session process has crashed";
|
||||
QCoreApplication::exit(-1);
|
||||
return;
|
||||
}
|
||||
QStringList arguments = KShell::splitArgs(m_sessionArgument);
|
||||
if (!arguments.isEmpty()) {
|
||||
QString program = arguments.takeFirst();
|
||||
QProcess *p = new Process(this);
|
||||
p->setProcessChannelMode(QProcess::ForwardedErrorChannel);
|
||||
p->setProcessEnvironment(processStartupEnvironment());
|
||||
connect(p, qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this, [p] (int code, QProcess::ExitStatus status) {
|
||||
p->deleteLater();
|
||||
if (status == QProcess::CrashExit) {
|
||||
qWarning() << "Session process has crashed";
|
||||
QCoreApplication::exit(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (code) {
|
||||
qWarning() << "Session process exited with code" << code;
|
||||
}
|
||||
if (code) {
|
||||
qWarning() << "Session process exited with code" << code;
|
||||
}
|
||||
|
||||
QCoreApplication::exit(code);
|
||||
});
|
||||
p->setProgram(m_sessionArgument);
|
||||
p->start();
|
||||
QCoreApplication::exit(code);
|
||||
});
|
||||
p->setProgram(program);
|
||||
p->setArguments(arguments);
|
||||
p->start();
|
||||
} else {
|
||||
qWarning("Failed to launch the session process: %s is an invalid command",
|
||||
qPrintable(m_sessionArgument));
|
||||
}
|
||||
}
|
||||
// start the applications passed to us as command line arguments
|
||||
if (!m_applicationsToStart.isEmpty()) {
|
||||
for (const QString &application: m_applicationsToStart) {
|
||||
QStringList arguments = KShell::splitArgs(application);
|
||||
if (arguments.isEmpty()) {
|
||||
qWarning("Failed to launch application: %s is an invalid command",
|
||||
qPrintable(application));
|
||||
continue;
|
||||
}
|
||||
QString program = arguments.takeFirst();
|
||||
// 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 Process(this);
|
||||
p->setProcessChannelMode(QProcess::ForwardedErrorChannel);
|
||||
p->setProcessEnvironment(processStartupEnvironment());
|
||||
p->setProgram(application);
|
||||
p->setProgram(program);
|
||||
p->setArguments(arguments);
|
||||
p->startDetached();
|
||||
p->deleteLater();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue