[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.
This commit is contained in:
parent
1d78430acc
commit
98bcdbe70a
5 changed files with 54 additions and 0 deletions
|
@ -174,6 +174,22 @@ void ApplicationWayland::continueStartupWithX()
|
||||||
::exit(1);
|
::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
|
// start the applications passed to us as command line arguments
|
||||||
if (!m_applicationsToStart.isEmpty()) {
|
if (!m_applicationsToStart.isEmpty()) {
|
||||||
QProcessEnvironment environment = QProcessEnvironment::systemEnvironment();
|
QProcessEnvironment environment = QProcessEnvironment::systemEnvironment();
|
||||||
|
@ -418,6 +434,7 @@ KWIN_EXPORT int kdemain(int argc, char * argv[])
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
qunsetenv("QT_DEVICE_PIXEL_RATIO");
|
qunsetenv("QT_DEVICE_PIXEL_RATIO");
|
||||||
|
qunsetenv("QT_IM_MODULE");
|
||||||
qputenv("WAYLAND_SOCKET", QByteArray::number(server->createQtConnection()));
|
qputenv("WAYLAND_SOCKET", QByteArray::number(server->createQtConnection()));
|
||||||
qputenv("QT_WAYLAND_DISABLE_WINDOWDECORATION", "1");
|
qputenv("QT_WAYLAND_DISABLE_WINDOWDECORATION", "1");
|
||||||
KWin::ApplicationWayland a(argc, argv);
|
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."));
|
QCommandLineOption drmOption(QStringLiteral("drm"), i18n("Render through drm node."));
|
||||||
parser.addOption(drmOption);
|
parser.addOption(drmOption);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QCommandLineOption inputMethodOption(QStringLiteral("inputmethod"),
|
||||||
|
i18n("Input method that KWin starts."),
|
||||||
|
QStringLiteral("path/to/imserver"));
|
||||||
|
parser.addOption(inputMethodOption);
|
||||||
|
|
||||||
parser.addPositionalArgument(QStringLiteral("applications"),
|
parser.addPositionalArgument(QStringLiteral("applications"),
|
||||||
i18n("Applications to start once Wayland and Xwayland server are started"),
|
i18n("Applications to start once Wayland and Xwayland server are started"),
|
||||||
QStringLiteral("[/path/to/application...]"));
|
QStringLiteral("[/path/to/application...]"));
|
||||||
|
@ -576,6 +599,7 @@ KWIN_EXPORT int kdemain(int argc, char * argv[])
|
||||||
|
|
||||||
a.setStartXwayland(parser.isSet(xwaylandOption));
|
a.setStartXwayland(parser.isSet(xwaylandOption));
|
||||||
a.setApplicationsToStart(parser.positionalArguments());
|
a.setApplicationsToStart(parser.positionalArguments());
|
||||||
|
a.setInputMethodServerToStart(parser.value(inputMethodOption));
|
||||||
a.start();
|
a.start();
|
||||||
|
|
||||||
return a.exec();
|
return a.exec();
|
||||||
|
|
|
@ -40,6 +40,9 @@ public:
|
||||||
void setApplicationsToStart(const QStringList &applications) {
|
void setApplicationsToStart(const QStringList &applications) {
|
||||||
m_applicationsToStart = applications;
|
m_applicationsToStart = applications;
|
||||||
}
|
}
|
||||||
|
void setInputMethodServerToStart(const QString &inputMethodServer) {
|
||||||
|
m_inputMethodServerToStart = inputMethodServer;
|
||||||
|
}
|
||||||
|
|
||||||
bool notify(QObject *o, QEvent *e) override;
|
bool notify(QObject *o, QEvent *e) override;
|
||||||
|
|
||||||
|
@ -56,6 +59,7 @@ private:
|
||||||
bool m_startXWayland = false;
|
bool m_startXWayland = false;
|
||||||
int m_xcbConnectionFd = -1;
|
int m_xcbConnectionFd = -1;
|
||||||
QStringList m_applicationsToStart;
|
QStringList m_applicationsToStart;
|
||||||
|
QString m_inputMethodServerToStart;
|
||||||
QProcess *m_xwaylandProcess = nullptr;
|
QProcess *m_xwaylandProcess = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,9 @@ ShellClient::ShellClient(ShellSurfaceInterface *surface)
|
||||||
setGeometry(QRect(QPoint(0, 0), m_clientSize));
|
setGeometry(QRect(QPoint(0, 0), m_clientSize));
|
||||||
setDesktop(VirtualDesktopManager::self()->current());
|
setDesktop(VirtualDesktopManager::self()->current());
|
||||||
}
|
}
|
||||||
|
if (waylandServer()->inputMethodConnection() == m_shellSurface->client()) {
|
||||||
|
m_windowType = NET::OnScreenDisplay;
|
||||||
|
}
|
||||||
|
|
||||||
connect(surface->surface(), &SurfaceInterface::sizeChanged, this,
|
connect(surface->surface(), &SurfaceInterface::sizeChanged, this,
|
||||||
[this] {
|
[this] {
|
||||||
|
@ -420,6 +423,9 @@ bool ShellClient::wantsInput() const
|
||||||
if (isInternal()) {
|
if (isInternal()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (waylandServer()->inputMethodConnection() == m_shellSurface->client()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// if the window is not visible it doesn't get input
|
// if the window is not visible it doesn't get input
|
||||||
return isShown(true);
|
return isShown(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,6 +189,17 @@ int WaylandServer::createXWaylandConnection()
|
||||||
return sx[1];
|
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 WaylandServer::createQtConnection()
|
||||||
{
|
{
|
||||||
int sx[2];
|
int sx[2];
|
||||||
|
|
|
@ -95,6 +95,11 @@ public:
|
||||||
**/
|
**/
|
||||||
int createXWaylandConnection();
|
int createXWaylandConnection();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns file descriptor to the input method server's socket.
|
||||||
|
**/
|
||||||
|
int createInputMethodConnection();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns file descriptor for QtWayland
|
* @returns file descriptor for QtWayland
|
||||||
**/
|
**/
|
||||||
|
@ -108,6 +113,9 @@ public:
|
||||||
KWayland::Server::ClientConnection *qtConnection() const {
|
KWayland::Server::ClientConnection *qtConnection() const {
|
||||||
return m_qtConnection;
|
return m_qtConnection;
|
||||||
}
|
}
|
||||||
|
KWayland::Server::ClientConnection *inputMethodConnection() const {
|
||||||
|
return m_inputMethodServerConnection;
|
||||||
|
}
|
||||||
KWayland::Server::ClientConnection *internalConnection() const {
|
KWayland::Server::ClientConnection *internalConnection() const {
|
||||||
return m_internalConnection.server;
|
return m_internalConnection.server;
|
||||||
}
|
}
|
||||||
|
@ -134,6 +142,7 @@ private:
|
||||||
KWayland::Server::PlasmaShellInterface *m_plasmaShell = nullptr;
|
KWayland::Server::PlasmaShellInterface *m_plasmaShell = nullptr;
|
||||||
KWayland::Server::QtSurfaceExtensionInterface *m_qtExtendedSurface = nullptr;
|
KWayland::Server::QtSurfaceExtensionInterface *m_qtExtendedSurface = nullptr;
|
||||||
KWayland::Server::ClientConnection *m_xwaylandConnection = nullptr;
|
KWayland::Server::ClientConnection *m_xwaylandConnection = nullptr;
|
||||||
|
KWayland::Server::ClientConnection *m_inputMethodServerConnection = nullptr;
|
||||||
KWayland::Server::ClientConnection *m_qtConnection = nullptr;
|
KWayland::Server::ClientConnection *m_qtConnection = nullptr;
|
||||||
KWayland::Client::ConnectionThread *m_qtClientConnection = nullptr;
|
KWayland::Client::ConnectionThread *m_qtClientConnection = nullptr;
|
||||||
struct {
|
struct {
|
||||||
|
|
Loading…
Reference in a new issue