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>
|
<min>0</min>
|
||||||
</entry>
|
</entry>
|
||||||
</group>
|
</group>
|
||||||
|
<group name="Wayland">
|
||||||
|
<entry name="InputMethod" type="Path" />
|
||||||
|
</group>
|
||||||
<group name="Xwayland">
|
<group name="Xwayland">
|
||||||
<entry name="XwaylandCrashPolicy" type="Enum">
|
<entry name="XwaylandCrashPolicy" type="Enum">
|
||||||
<choices name="KWin::XwaylandCrashPolicy">
|
<choices name="KWin::XwaylandCrashPolicy">
|
||||||
|
|
101
main_wayland.cpp
101
main_wayland.cpp
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
// KDE
|
// KDE
|
||||||
#include <KCrash>
|
#include <KCrash>
|
||||||
|
#include <KDesktopFile>
|
||||||
#include <KLocalizedString>
|
#include <KLocalizedString>
|
||||||
#include <KPluginLoader>
|
#include <KPluginLoader>
|
||||||
#include <KPluginMetaData>
|
#include <KPluginMetaData>
|
||||||
|
@ -112,6 +113,7 @@ void gainRealTime(RealTimeFlags flags = RealTimeFlags::DontReset)
|
||||||
ApplicationWayland::ApplicationWayland(int &argc, char **argv)
|
ApplicationWayland::ApplicationWayland(int &argc, char **argv)
|
||||||
: ApplicationWaylandAbstract(OperationModeWaylandOnly, argc, argv)
|
: ApplicationWaylandAbstract(OperationModeWaylandOnly, argc, argv)
|
||||||
{
|
{
|
||||||
|
connect(waylandServer(), &WaylandServer::terminatingInternalClientConnection, this, &ApplicationWayland::stopInputMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplicationWayland::~ApplicationWayland()
|
ApplicationWayland::~ApplicationWayland()
|
||||||
|
@ -216,42 +218,75 @@ void ApplicationWayland::continueStartupWithScene()
|
||||||
m_xwayland->start();
|
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()
|
void ApplicationWayland::startSession()
|
||||||
{
|
{
|
||||||
if (!m_inputMethodServerToStart.isEmpty()) {
|
if (!m_inputMethodServerToStart.isEmpty()) {
|
||||||
QStringList arguments = KShell::splitArgs(m_inputMethodServerToStart);
|
startInputMethod(m_inputMethodServerToStart);
|
||||||
if (!arguments.isEmpty()) {
|
} else {
|
||||||
QString program = arguments.takeFirst();
|
KSharedConfig::Ptr kwinSettings = kwinApp()->config();
|
||||||
int socket = dup(waylandServer()->createInputMethodConnection());
|
m_settingsWatcher = KConfigWatcher::create(kwinSettings);
|
||||||
if (socket >= 0) {
|
connect(m_settingsWatcher.data(), &KConfigWatcher::configChanged, this, &ApplicationWayland::refreshSettings);
|
||||||
QProcessEnvironment environment = processStartupEnvironment();
|
|
||||||
environment.insert(QStringLiteral("WAYLAND_SOCKET"), QByteArray::number(socket));
|
KConfigGroup group = kwinSettings->group("Wayland");
|
||||||
environment.insert(QStringLiteral("QT_QPA_PLATFORM"), QStringLiteral("wayland"));
|
KDesktopFile file(group.readEntry("InputMethod", QString()));
|
||||||
environment.remove("DISPLAY");
|
startInputMethod(file.desktopGroup().readEntry("Exec", QString()));
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// start session
|
// start session
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#ifndef KWIN_MAIN_WAYLAND_H
|
#ifndef KWIN_MAIN_WAYLAND_H
|
||||||
#define KWIN_MAIN_WAYLAND_H
|
#define KWIN_MAIN_WAYLAND_H
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include <KConfigWatcher>
|
||||||
#include <QProcessEnvironment>
|
#include <QProcessEnvironment>
|
||||||
|
|
||||||
namespace KWin
|
namespace KWin
|
||||||
|
@ -54,14 +55,19 @@ private:
|
||||||
void continueStartupWithScene();
|
void continueStartupWithScene();
|
||||||
void finalizeStartup();
|
void finalizeStartup();
|
||||||
void startSession() override;
|
void startSession() override;
|
||||||
|
void startInputMethod(const QString &executable);
|
||||||
|
void refreshSettings(const KConfigGroup &group, const QByteArrayList &names);
|
||||||
|
void stopInputMethod();
|
||||||
|
|
||||||
bool m_startXWayland = false;
|
bool m_startXWayland = false;
|
||||||
QStringList m_applicationsToStart;
|
QStringList m_applicationsToStart;
|
||||||
QString m_inputMethodServerToStart;
|
QString m_inputMethodServerToStart;
|
||||||
QProcessEnvironment m_environment;
|
QProcessEnvironment m_environment;
|
||||||
QString m_sessionArgument;
|
QString m_sessionArgument;
|
||||||
|
QProcess *m_inputMethodProcess = nullptr;
|
||||||
|
|
||||||
Xwl::Xwayland *m_xwayland = nullptr;
|
Xwl::Xwayland *m_xwayland = nullptr;
|
||||||
|
KConfigWatcher::Ptr m_settingsWatcher;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue