Commit 98bcdbe7 authored by Boudewijn Rempt's avatar Boudewijn Rempt

[wayland] Add a command-line option to start an input method server

Input-method servers, like maliit, need to be known to KWin since KWin
needs to know about virtual keyboards. Virtual keyboards should be shown
as OSD layers, and they are one of the types of windows that actually
should be showable when the lock screen is active.

kwin_wayland --inputmethod /path/to/your/input-server

tries to start the input server. The input-server's window never gets
keyboard focus and is shown on top of all windows except for KWin's
internal clients.
parent 1d78430a
......@@ -174,6 +174,22 @@ void ApplicationWayland::continueStartupWithX()
::exit(1);
}
if (!m_inputMethodServerToStart.isEmpty()) {
int socket = dup(waylandServer()->createInputMethodConnection());
if (socket >= 0) {
QProcessEnvironment environment = QProcessEnvironment::systemEnvironment();
environment.insert(QStringLiteral("WAYLAND_SOCKET"), QByteArray::number(socket));
environment.insert(QStringLiteral("QT_QPA_PLATFORM"), QStringLiteral("wayland"));
environment.insert(QStringLiteral("QT_IM_MODULE"), QStringLiteral("maliit"));
environment.remove("DISPLAY");
environment.remove("WAYLAND_DISPLAY");
QProcess *p = new QProcess(this);
p->setProcessEnvironment(environment);
p->start(m_inputMethodServerToStart);
p->waitForStarted();
}
}
// start the applications passed to us as command line arguments
if (!m_applicationsToStart.isEmpty()) {
QProcessEnvironment environment = QProcessEnvironment::systemEnvironment();
......@@ -418,6 +434,7 @@ KWIN_EXPORT int kdemain(int argc, char * argv[])
#endif
qunsetenv("QT_DEVICE_PIXEL_RATIO");
qunsetenv("QT_IM_MODULE");
qputenv("WAYLAND_SOCKET", QByteArray::number(server->createQtConnection()));
qputenv("QT_WAYLAND_DISABLE_WINDOWDECORATION", "1");
KWin::ApplicationWayland a(argc, argv);
......@@ -479,6 +496,12 @@ KWIN_EXPORT int kdemain(int argc, char * argv[])
QCommandLineOption drmOption(QStringLiteral("drm"), i18n("Render through drm node."));
parser.addOption(drmOption);
#endif
QCommandLineOption inputMethodOption(QStringLiteral("inputmethod"),
i18n("Input method that KWin starts."),
QStringLiteral("path/to/imserver"));
parser.addOption(inputMethodOption);
parser.addPositionalArgument(QStringLiteral("applications"),
i18n("Applications to start once Wayland and Xwayland server are started"),
QStringLiteral("[/path/to/application...]"));
......@@ -576,6 +599,7 @@ KWIN_EXPORT int kdemain(int argc, char * argv[])
a.setStartXwayland(parser.isSet(xwaylandOption));
a.setApplicationsToStart(parser.positionalArguments());
a.setInputMethodServerToStart(parser.value(inputMethodOption));
a.start();
return a.exec();
......
......@@ -40,6 +40,9 @@ public:
void setApplicationsToStart(const QStringList &applications) {
m_applicationsToStart = applications;
}
void setInputMethodServerToStart(const QString &inputMethodServer) {
m_inputMethodServerToStart = inputMethodServer;
}
bool notify(QObject *o, QEvent *e) override;
......@@ -56,6 +59,7 @@ private:
bool m_startXWayland = false;
int m_xcbConnectionFd = -1;
QStringList m_applicationsToStart;
QString m_inputMethodServerToStart;
QProcess *m_xwaylandProcess = nullptr;
};
......
......@@ -62,6 +62,9 @@ ShellClient::ShellClient(ShellSurfaceInterface *surface)
setGeometry(QRect(QPoint(0, 0), m_clientSize));
setDesktop(VirtualDesktopManager::self()->current());
}
if (waylandServer()->inputMethodConnection() == m_shellSurface->client()) {
m_windowType = NET::OnScreenDisplay;
}
connect(surface->surface(), &SurfaceInterface::sizeChanged, this,
[this] {
......@@ -420,6 +423,9 @@ bool ShellClient::wantsInput() const
if (isInternal()) {
return false;
}
if (waylandServer()->inputMethodConnection() == m_shellSurface->client()) {
return false;
}
// if the window is not visible it doesn't get input
return isShown(true);
}
......
......@@ -189,6 +189,17 @@ int WaylandServer::createXWaylandConnection()
return sx[1];
}
int WaylandServer::createInputMethodConnection()
{
int sx[2];
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sx) < 0) {
qCWarning(KWIN_CORE) << "Could not create socket";
return -1;
}
m_inputMethodServerConnection = m_display->createClient(sx[0]);
return sx[1];
}
int WaylandServer::createQtConnection()
{
int sx[2];
......
......@@ -95,6 +95,11 @@ public:
**/
int createXWaylandConnection();
/**
* @returns file descriptor to the input method server's socket.
**/
int createInputMethodConnection();
/**
* @returns file descriptor for QtWayland
**/
......@@ -108,6 +113,9 @@ public:
KWayland::Server::ClientConnection *qtConnection() const {
return m_qtConnection;
}
KWayland::Server::ClientConnection *inputMethodConnection() const {
return m_inputMethodServerConnection;
}
KWayland::Server::ClientConnection *internalConnection() const {
return m_internalConnection.server;
}
......@@ -134,6 +142,7 @@ private:
KWayland::Server::PlasmaShellInterface *m_plasmaShell = nullptr;
KWayland::Server::QtSurfaceExtensionInterface *m_qtExtendedSurface = nullptr;
KWayland::Server::ClientConnection *m_xwaylandConnection = nullptr;
KWayland::Server::ClientConnection *m_inputMethodServerConnection = nullptr;
KWayland::Server::ClientConnection *m_qtConnection = nullptr;
KWayland::Client::ConnectionThread *m_qtClientConnection = nullptr;
struct {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment