Introduce a setting to specify an input method
At the moment we are getting the input method from the command line which is not very handy (but very secure). This patch changes it so it can be specified from a configuration setting. CCBUG: 427972
This commit is contained in:
parent
59b1dee55a
commit
05ebe676d2
3 changed files with 77 additions and 33 deletions
|
@ -314,6 +314,9 @@
|
|||
<min>0</min>
|
||||
</entry>
|
||||
</group>
|
||||
<group name="Wayland">
|
||||
<entry name="InputMethod" type="Path" />
|
||||
</group>
|
||||
<group name="Xwayland">
|
||||
<entry name="XwaylandCrashPolicy" type="Enum">
|
||||
<choices name="KWin::XwaylandCrashPolicy">
|
||||
|
|
101
main_wayland.cpp
101
main_wayland.cpp
|
@ -25,6 +25,7 @@
|
|||
|
||||
// KDE
|
||||
#include <KCrash>
|
||||
#include <KDesktopFile>
|
||||
#include <KLocalizedString>
|
||||
#include <KPluginLoader>
|
||||
#include <KPluginMetaData>
|
||||
|
@ -112,6 +113,7 @@ void gainRealTime(RealTimeFlags flags = RealTimeFlags::DontReset)
|
|||
ApplicationWayland::ApplicationWayland(int &argc, char **argv)
|
||||
: ApplicationWaylandAbstract(OperationModeWaylandOnly, argc, argv)
|
||||
{
|
||||
connect(waylandServer(), &WaylandServer::terminatingInternalClientConnection, this, &ApplicationWayland::stopInputMethod);
|
||||
}
|
||||
|
||||
ApplicationWayland::~ApplicationWayland()
|
||||
|
@ -216,42 +218,75 @@ void ApplicationWayland::continueStartupWithScene()
|
|||
m_xwayland->start();
|
||||
}
|
||||
|
||||
|
||||
void ApplicationWayland::stopInputMethod()
|
||||
{
|
||||
if (!m_inputMethodProcess) {
|
||||
return;
|
||||
}
|
||||
m_inputMethodProcess->kill();
|
||||
m_inputMethodProcess->waitForFinished();
|
||||
if (waylandServer()) {
|
||||
waylandServer()->destroyInputMethodConnection();
|
||||
}
|
||||
m_inputMethodProcess->deleteLater();
|
||||
m_inputMethodProcess = nullptr;
|
||||
}
|
||||
|
||||
void ApplicationWayland::startInputMethod(const QString &executable)
|
||||
{
|
||||
stopInputMethod();
|
||||
if (executable.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QStringList arguments = KShell::splitArgs(executable);
|
||||
if (arguments.isEmpty()) {
|
||||
qWarning("Failed to launch the input method server: %s is an invalid command", qPrintable(m_inputMethodServerToStart));
|
||||
return;
|
||||
}
|
||||
|
||||
const QString program = arguments.takeFirst();
|
||||
int socket = dup(waylandServer()->createInputMethodConnection());
|
||||
if (socket >= 0) {
|
||||
qWarning("Failed to create the input method connection");
|
||||
return;
|
||||
}
|
||||
|
||||
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");
|
||||
m_inputMethodProcess = new Process(this);
|
||||
m_inputMethodProcess->setProcessChannelMode(QProcess::ForwardedErrorChannel);
|
||||
m_inputMethodProcess->setProcessEnvironment(environment);
|
||||
m_inputMethodProcess->setProgram(program);
|
||||
m_inputMethodProcess->setArguments(arguments);
|
||||
m_inputMethodProcess->start();
|
||||
}
|
||||
|
||||
void ApplicationWayland::refreshSettings(const KConfigGroup &group, const QByteArrayList &names)
|
||||
{
|
||||
if (group.name() != "Wayland" || !names.contains("InputMethod")) {
|
||||
return;
|
||||
}
|
||||
|
||||
startInputMethod(group.readEntry("InputMethod", QString()));
|
||||
}
|
||||
|
||||
void ApplicationWayland::startSession()
|
||||
{
|
||||
if (!m_inputMethodServerToStart.isEmpty()) {
|
||||
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->setProcessEnvironment(environment);
|
||||
p->setProgram(program);
|
||||
p->setArguments(arguments);
|
||||
p->start();
|
||||
connect(waylandServer(), &WaylandServer::terminatingInternalClientConnection, p, [p] {
|
||||
p->kill();
|
||||
p->waitForFinished();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
qWarning("Failed to launch the input method server: %s is an invalid command",
|
||||
qPrintable(m_inputMethodServerToStart));
|
||||
}
|
||||
startInputMethod(m_inputMethodServerToStart);
|
||||
} else {
|
||||
KSharedConfig::Ptr kwinSettings = kwinApp()->config();
|
||||
m_settingsWatcher = KConfigWatcher::create(kwinSettings);
|
||||
connect(m_settingsWatcher.data(), &KConfigWatcher::configChanged, this, &ApplicationWayland::refreshSettings);
|
||||
|
||||
KConfigGroup group = kwinSettings->group("Wayland");
|
||||
KDesktopFile file(group.readEntry("InputMethod", QString()));
|
||||
startInputMethod(file.desktopGroup().readEntry("Exec", QString()));
|
||||
}
|
||||
|
||||
// start session
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#ifndef KWIN_MAIN_WAYLAND_H
|
||||
#define KWIN_MAIN_WAYLAND_H
|
||||
#include "main.h"
|
||||
#include <KConfigWatcher>
|
||||
#include <QProcessEnvironment>
|
||||
|
||||
namespace KWin
|
||||
|
@ -54,14 +55,19 @@ private:
|
|||
void continueStartupWithScene();
|
||||
void finalizeStartup();
|
||||
void startSession() override;
|
||||
void startInputMethod(const QString &executable);
|
||||
void refreshSettings(const KConfigGroup &group, const QByteArrayList &names);
|
||||
void stopInputMethod();
|
||||
|
||||
bool m_startXWayland = false;
|
||||
QStringList m_applicationsToStart;
|
||||
QString m_inputMethodServerToStart;
|
||||
QProcessEnvironment m_environment;
|
||||
QString m_sessionArgument;
|
||||
QProcess *m_inputMethodProcess = nullptr;
|
||||
|
||||
Xwl::Xwayland *m_xwayland = nullptr;
|
||||
KConfigWatcher::Ptr m_settingsWatcher;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue