virtualkeyboard: add text-input-v3 support
This commit is contained in:
parent
a433fb08a3
commit
6d433bdfc9
6 changed files with 245 additions and 56 deletions
|
@ -13,6 +13,10 @@ ecm_add_qtwayland_client_protocol(KWinIntegrationTestFramework_SOURCES
|
||||||
PROTOCOL ${WaylandProtocols_DATADIR}/unstable/input-method/input-method-unstable-v1.xml
|
PROTOCOL ${WaylandProtocols_DATADIR}/unstable/input-method/input-method-unstable-v1.xml
|
||||||
BASENAME input-method-unstable-v1
|
BASENAME input-method-unstable-v1
|
||||||
)
|
)
|
||||||
|
ecm_add_qtwayland_client_protocol(KWinIntegrationTestFramework_SOURCES
|
||||||
|
PROTOCOL ${WaylandProtocols_DATADIR}/unstable/text-input/text-input-unstable-v3.xml
|
||||||
|
BASENAME text-input-unstable-v3
|
||||||
|
)
|
||||||
ecm_add_qtwayland_client_protocol(KWinIntegrationTestFramework_SOURCES
|
ecm_add_qtwayland_client_protocol(KWinIntegrationTestFramework_SOURCES
|
||||||
PROTOCOL protocols/wlr-layer-shell-unstable-v1.xml
|
PROTOCOL protocols/wlr-layer-shell-unstable-v1.xml
|
||||||
BASENAME wlr-layer-shell-unstable-v1
|
BASENAME wlr-layer-shell-unstable-v1
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <KWayland/Client/xdgshell.h>
|
#include <KWayland/Client/xdgshell.h>
|
||||||
|
|
||||||
#include "qwayland-wlr-layer-shell-unstable-v1.h"
|
#include "qwayland-wlr-layer-shell-unstable-v1.h"
|
||||||
|
#include "qwayland-text-input-unstable-v3.h"
|
||||||
#include "qwayland-xdg-shell.h"
|
#include "qwayland-xdg-shell.h"
|
||||||
|
|
||||||
namespace KWayland
|
namespace KWayland
|
||||||
|
@ -47,6 +48,8 @@ class TextInputManager;
|
||||||
namespace QtWayland
|
namespace QtWayland
|
||||||
{
|
{
|
||||||
class zwp_input_panel_surface_v1;
|
class zwp_input_panel_surface_v1;
|
||||||
|
class zwp_text_input_v3;
|
||||||
|
class zwp_text_input_manager_v3;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace KWin
|
namespace KWin
|
||||||
|
@ -86,6 +89,17 @@ namespace Test
|
||||||
|
|
||||||
class MockInputMethod;
|
class MockInputMethod;
|
||||||
|
|
||||||
|
class TextInputManagerV3 : public QtWayland::zwp_text_input_manager_v3
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~TextInputManagerV3() override { destroy(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
class TextInputV3 : public QtWayland::zwp_text_input_v3
|
||||||
|
{
|
||||||
|
~TextInputV3() override { destroy(); }
|
||||||
|
};
|
||||||
|
|
||||||
class LayerShellV1 : public QtWayland::zwlr_layer_shell_v1
|
class LayerShellV1 : public QtWayland::zwlr_layer_shell_v1
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -222,6 +236,7 @@ enum class AdditionalWaylandInterface {
|
||||||
TextInputManagerV2 = 1 << 10,
|
TextInputManagerV2 = 1 << 10,
|
||||||
InputMethodV1 = 1 << 11,
|
InputMethodV1 = 1 << 11,
|
||||||
LayerShellV1 = 1 << 12,
|
LayerShellV1 = 1 << 12,
|
||||||
|
TextInputManagerV3 = 1 << 13
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(AdditionalWaylandInterfaces, AdditionalWaylandInterface)
|
Q_DECLARE_FLAGS(AdditionalWaylandInterfaces, AdditionalWaylandInterface)
|
||||||
/**
|
/**
|
||||||
|
@ -272,6 +287,8 @@ LayerSurfaceV1 *createLayerSurfaceV1(KWayland::Client::Surface *surface,
|
||||||
KWayland::Client::Output *output = nullptr,
|
KWayland::Client::Output *output = nullptr,
|
||||||
LayerShellV1::layer layer = LayerShellV1::layer_top);
|
LayerShellV1::layer layer = LayerShellV1::layer_top);
|
||||||
|
|
||||||
|
TextInputManagerV3 *waylandTextInputManagerV3();
|
||||||
|
|
||||||
enum class CreationSetup {
|
enum class CreationSetup {
|
||||||
CreateOnly,
|
CreateOnly,
|
||||||
CreateAndConfigure, /// commit and wait for the configure event, making this surface ready to commit buffers
|
CreateAndConfigure, /// commit and wait for the configure event, making this surface ready to commit buffers
|
||||||
|
|
|
@ -208,6 +208,7 @@ static struct {
|
||||||
MockInputMethod *inputMethodV1 = nullptr;
|
MockInputMethod *inputMethodV1 = nullptr;
|
||||||
QtWayland::zwp_input_method_context_v1 *inputMethodContextV1 = nullptr;
|
QtWayland::zwp_input_method_context_v1 *inputMethodContextV1 = nullptr;
|
||||||
LayerShellV1 *layerShellV1 = nullptr;
|
LayerShellV1 *layerShellV1 = nullptr;
|
||||||
|
TextInputManagerV3 *textInputManagerV3 = nullptr;
|
||||||
} s_waylandConnection;
|
} s_waylandConnection;
|
||||||
|
|
||||||
class MockInputMethod : public QtWayland::zwp_input_method_v1
|
class MockInputMethod : public QtWayland::zwp_input_method_v1
|
||||||
|
@ -323,6 +324,13 @@ bool setupWaylandConnection(AdditionalWaylandInterfaces flags)
|
||||||
s_waylandConnection.layerShellV1->init(*registry, name, version);
|
s_waylandConnection.layerShellV1->init(*registry, name, version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (flags & AdditionalWaylandInterface::TextInputManagerV3) {
|
||||||
|
// do something
|
||||||
|
if (interface == QByteArrayLiteral("zwp_text_input_manager_v3")) {
|
||||||
|
s_waylandConnection.textInputManagerV3 = new TextInputManagerV3();
|
||||||
|
s_waylandConnection.textInputManagerV3->init(*registry, name, version);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (interface == QByteArrayLiteral("xdg_wm_base")) {
|
if (interface == QByteArrayLiteral("xdg_wm_base")) {
|
||||||
s_waylandConnection.xdgShell = new XdgShell();
|
s_waylandConnection.xdgShell = new XdgShell();
|
||||||
s_waylandConnection.xdgShell->init(*registry, name, version);
|
s_waylandConnection.xdgShell->init(*registry, name, version);
|
||||||
|
@ -566,6 +574,11 @@ TextInputManager *waylandTextInputManager()
|
||||||
return s_waylandConnection.textInputManager;
|
return s_waylandConnection.textInputManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TextInputManagerV3 *waylandTextInputManagerV3()
|
||||||
|
{
|
||||||
|
return s_waylandConnection.textInputManagerV3;
|
||||||
|
}
|
||||||
|
|
||||||
QVector<KWayland::Client::Output *> waylandOutputs()
|
QVector<KWayland::Client::Output *> waylandOutputs()
|
||||||
{
|
{
|
||||||
return s_waylandConnection.outputs;
|
return s_waylandConnection.outputs;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "virtualkeyboard.h"
|
#include "virtualkeyboard.h"
|
||||||
#include "virtualkeyboard_dbus.h"
|
#include "virtualkeyboard_dbus.h"
|
||||||
#include "qwayland-input-method-unstable-v1.h"
|
#include "qwayland-input-method-unstable-v1.h"
|
||||||
|
#include "qwayland-text-input-unstable-v3.h"
|
||||||
|
|
||||||
#include <QTest>
|
#include <QTest>
|
||||||
#include <QSignalSpy>
|
#include <QSignalSpy>
|
||||||
|
@ -33,6 +34,7 @@
|
||||||
#include <KWayland/Client/surface.h>
|
#include <KWayland/Client/surface.h>
|
||||||
#include <KWayland/Client/xdgshell.h>
|
#include <KWayland/Client/xdgshell.h>
|
||||||
#include <KWayland/Client/textinput.h>
|
#include <KWayland/Client/textinput.h>
|
||||||
|
#include <KWayland/Client/seat.h>
|
||||||
|
|
||||||
using namespace KWin;
|
using namespace KWin;
|
||||||
using namespace KWayland::Client;
|
using namespace KWayland::Client;
|
||||||
|
@ -49,6 +51,7 @@ private Q_SLOTS:
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
void testOpenClose();
|
void testOpenClose();
|
||||||
|
void testEnableDisableV3();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -77,7 +80,9 @@ void VirtualKeyboardTest::initTestCase()
|
||||||
void VirtualKeyboardTest::init()
|
void VirtualKeyboardTest::init()
|
||||||
{
|
{
|
||||||
QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Seat |
|
QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Seat |
|
||||||
Test::AdditionalWaylandInterface::TextInputManagerV2 | Test::AdditionalWaylandInterface::InputMethodV1));
|
Test::AdditionalWaylandInterface::TextInputManagerV2 |
|
||||||
|
Test::AdditionalWaylandInterface::InputMethodV1 |
|
||||||
|
Test::AdditionalWaylandInterface::TextInputManagerV3));
|
||||||
|
|
||||||
|
|
||||||
screens()->setCurrent(0);
|
screens()->setCurrent(0);
|
||||||
|
@ -149,6 +154,40 @@ void VirtualKeyboardTest::testOpenClose()
|
||||||
QVERIFY(Test::waitForWindowDestroyed(client));
|
QVERIFY(Test::waitForWindowDestroyed(client));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VirtualKeyboardTest::testEnableDisableV3()
|
||||||
|
{
|
||||||
|
QSignalSpy clientAddedSpy(workspace(), &Workspace::clientAdded);
|
||||||
|
QSignalSpy clientRemovedSpy(workspace(), &Workspace::clientRemoved);
|
||||||
|
QVERIFY(clientAddedSpy.isValid());
|
||||||
|
|
||||||
|
// Create an xdg_toplevel surface and wait for the compositor to catch up.
|
||||||
|
QScopedPointer<Surface> surface(Test::createSurface());
|
||||||
|
QScopedPointer<XdgShellSurface> shellSurface(Test::createXdgShellStableSurface(surface.data()));
|
||||||
|
AbstractClient *client = Test::renderAndWaitForShown(surface.data(), QSize(1280, 1024), Qt::red);
|
||||||
|
QVERIFY(client);
|
||||||
|
QVERIFY(client->isActive());
|
||||||
|
QCOMPARE(client->frameGeometry().size(), QSize(1280, 1024));
|
||||||
|
|
||||||
|
Test::TextInputV3 *textInputV3 = new Test::TextInputV3();
|
||||||
|
textInputV3->init(Test::waylandTextInputManagerV3()->get_text_input(*(Test::waylandSeat())));
|
||||||
|
textInputV3->enable();
|
||||||
|
// just enabling the text-input should not show it but rather on commit
|
||||||
|
QVERIFY(!clientAddedSpy.wait(100));
|
||||||
|
|
||||||
|
textInputV3->commit();
|
||||||
|
|
||||||
|
QVERIFY(clientAddedSpy.wait());
|
||||||
|
AbstractClient *keyboardClient = clientAddedSpy.last().first().value<AbstractClient *>();
|
||||||
|
QVERIFY(keyboardClient);
|
||||||
|
QVERIFY(keyboardClient->isInputMethod());
|
||||||
|
|
||||||
|
// disable text input and ensure that it is not hiding input panel without commit
|
||||||
|
textInputV3->disable();
|
||||||
|
QVERIFY(!clientRemovedSpy.wait(100));
|
||||||
|
textInputV3->commit();
|
||||||
|
QVERIFY(clientRemovedSpy.wait());
|
||||||
|
}
|
||||||
|
|
||||||
WAYLANDTEST_MAIN(VirtualKeyboardTest)
|
WAYLANDTEST_MAIN(VirtualKeyboardTest)
|
||||||
|
|
||||||
#include "virtualkeyboard_test.moc"
|
#include "virtualkeyboard_test.moc"
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <KWaylandServer/display.h>
|
#include <KWaylandServer/display.h>
|
||||||
#include <KWaylandServer/seat_interface.h>
|
#include <KWaylandServer/seat_interface.h>
|
||||||
#include <KWaylandServer/textinput_v2_interface.h>
|
#include <KWaylandServer/textinput_v2_interface.h>
|
||||||
|
#include <KWaylandServer/textinput_v3_interface.h>
|
||||||
#include <KWaylandServer/surface_interface.h>
|
#include <KWaylandServer/surface_interface.h>
|
||||||
#include <KWaylandServer/inputmethod_v1_interface.h>
|
#include <KWaylandServer/inputmethod_v1_interface.h>
|
||||||
|
|
||||||
|
@ -29,6 +30,9 @@
|
||||||
#include <QDBusPendingCall>
|
#include <QDBusPendingCall>
|
||||||
#include <QDBusMessage>
|
#include <QDBusMessage>
|
||||||
|
|
||||||
|
#include <linux/input-event-codes.h>
|
||||||
|
#include <xkbcommon/xkbcommon-keysyms.h>
|
||||||
|
|
||||||
using namespace KWaylandServer;
|
using namespace KWaylandServer;
|
||||||
|
|
||||||
namespace KWin
|
namespace KWin
|
||||||
|
@ -85,6 +89,8 @@ void VirtualKeyboard::init()
|
||||||
|
|
||||||
if (waylandServer()) {
|
if (waylandServer()) {
|
||||||
waylandServer()->display()->createTextInputManagerV2();
|
waylandServer()->display()->createTextInputManagerV2();
|
||||||
|
waylandServer()->display()->createTextInputManagerV3();
|
||||||
|
|
||||||
connect(workspace(), &Workspace::clientAdded, this, &VirtualKeyboard::clientAdded);
|
connect(workspace(), &Workspace::clientAdded, this, &VirtualKeyboard::clientAdded);
|
||||||
connect(waylandServer()->seat(), &SeatInterface::focusedTextInputSurfaceChanged, this, &VirtualKeyboard::handleFocusedSurfaceChanged);
|
connect(waylandServer()->seat(), &SeatInterface::focusedTextInputSurfaceChanged, this, &VirtualKeyboard::handleFocusedSurfaceChanged);
|
||||||
|
|
||||||
|
@ -94,8 +100,14 @@ void VirtualKeyboard::init()
|
||||||
connect(textInputV2, &TextInputV2Interface::surroundingTextChanged, this, &VirtualKeyboard::surroundingTextChanged);
|
connect(textInputV2, &TextInputV2Interface::surroundingTextChanged, this, &VirtualKeyboard::surroundingTextChanged);
|
||||||
connect(textInputV2, &TextInputV2Interface::contentTypeChanged, this, &VirtualKeyboard::contentTypeChanged);
|
connect(textInputV2, &TextInputV2Interface::contentTypeChanged, this, &VirtualKeyboard::contentTypeChanged);
|
||||||
connect(textInputV2, &TextInputV2Interface::requestReset, this, &VirtualKeyboard::requestReset);
|
connect(textInputV2, &TextInputV2Interface::requestReset, this, &VirtualKeyboard::requestReset);
|
||||||
connect(textInputV2, &TextInputV2Interface::enabledChanged, this, &VirtualKeyboard::textInputInterfaceEnabledChanged);
|
connect(textInputV2, &TextInputV2Interface::enabledChanged, this, &VirtualKeyboard::textInputInterfaceV2EnabledChanged);
|
||||||
connect(textInputV2, &TextInputV2Interface::stateCommitted, this, &VirtualKeyboard::stateCommitted);
|
connect(textInputV2, &TextInputV2Interface::stateCommitted, this, &VirtualKeyboard::stateCommitted);
|
||||||
|
|
||||||
|
TextInputV3Interface *textInputV3 = waylandServer()->seat()->textInputV3();
|
||||||
|
connect(textInputV3, &TextInputV3Interface::enabledChanged, this, &VirtualKeyboard::textInputInterfaceV3EnabledChanged);
|
||||||
|
connect(textInputV3, &TextInputV3Interface::surroundingTextChanged, this, &VirtualKeyboard::surroundingTextChanged);
|
||||||
|
connect(textInputV3, &TextInputV3Interface::contentTypeChanged, this, &VirtualKeyboard::contentTypeChanged);
|
||||||
|
connect(textInputV3, &TextInputV3Interface::stateCommitted, this, &VirtualKeyboard::stateCommitted);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,38 +171,54 @@ void VirtualKeyboard::handleFocusedSurfaceChanged()
|
||||||
|
|
||||||
void VirtualKeyboard::surroundingTextChanged()
|
void VirtualKeyboard::surroundingTextChanged()
|
||||||
{
|
{
|
||||||
auto t = waylandServer()->seat()->textInputV2();
|
auto t2 = waylandServer()->seat()->textInputV2();
|
||||||
|
auto t3 = waylandServer()->seat()->textInputV3();
|
||||||
auto inputContext = waylandServer()->inputMethod()->context();
|
auto inputContext = waylandServer()->inputMethod()->context();
|
||||||
if (!inputContext) {
|
if (!inputContext) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
inputContext->sendSurroundingText(t->surroundingText(), t->surroundingTextCursorPosition(), t->surroundingTextSelectionAnchor());
|
if (t2 && t2->isEnabled()) {
|
||||||
|
inputContext->sendSurroundingText(t2->surroundingText(), t2->surroundingTextCursorPosition(), t2->surroundingTextSelectionAnchor());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (t3 && t3->isEnabled()) {
|
||||||
|
inputContext->sendSurroundingText(t3->surroundingText(), t3->surroundingTextCursorPosition(), t3->surroundingTextSelectionAnchor());
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualKeyboard::contentTypeChanged()
|
void VirtualKeyboard::contentTypeChanged()
|
||||||
{
|
{
|
||||||
auto t = waylandServer()->seat()->textInputV2();
|
auto t2 = waylandServer()->seat()->textInputV2();
|
||||||
|
auto t3 = waylandServer()->seat()->textInputV3();
|
||||||
auto inputContext = waylandServer()->inputMethod()->context();
|
auto inputContext = waylandServer()->inputMethod()->context();
|
||||||
if (!inputContext) {
|
if (!inputContext) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
inputContext->sendContentType(t->contentHints(), t->contentPurpose());
|
if (t2 && t2->isEnabled()) {
|
||||||
|
inputContext->sendContentType(t2->contentHints(), t2->contentPurpose());
|
||||||
|
}
|
||||||
|
if (t3 && t3->isEnabled()) {
|
||||||
|
inputContext->sendContentType(t3->contentHints(), t3->contentPurpose());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualKeyboard::requestReset()
|
void VirtualKeyboard::requestReset()
|
||||||
{
|
{
|
||||||
auto t = waylandServer()->seat()->textInputV2();
|
auto t2 = waylandServer()->seat()->textInputV2();
|
||||||
auto inputContext = waylandServer()->inputMethod()->context();
|
auto inputContext = waylandServer()->inputMethod()->context();
|
||||||
if (!inputContext) {
|
if (!inputContext) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
inputContext->sendReset();
|
inputContext->sendReset();
|
||||||
inputContext->sendSurroundingText(t->surroundingText(), t->surroundingTextCursorPosition(), t->surroundingTextSelectionAnchor());
|
if (t2 && t2->isEnabled()) {
|
||||||
inputContext->sendPreferredLanguage(t->preferredLanguage());
|
inputContext->sendSurroundingText(t2->surroundingText(), t2->surroundingTextCursorPosition(), t2->surroundingTextSelectionAnchor());
|
||||||
inputContext->sendContentType(t->contentHints(), t->contentPurpose());
|
inputContext->sendPreferredLanguage(t2->preferredLanguage());
|
||||||
|
inputContext->sendContentType(t2->contentHints(), t2->contentPurpose());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualKeyboard::textInputInterfaceEnabledChanged()
|
void VirtualKeyboard::textInputInterfaceV2EnabledChanged()
|
||||||
{
|
{
|
||||||
auto t = waylandServer()->seat()->textInputV2();
|
auto t = waylandServer()->seat()->textInputV2();
|
||||||
if (t->isEnabled()) {
|
if (t->isEnabled()) {
|
||||||
|
@ -204,6 +232,21 @@ void VirtualKeyboard::textInputInterfaceEnabledChanged()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VirtualKeyboard::textInputInterfaceV3EnabledChanged()
|
||||||
|
{
|
||||||
|
auto t3 = waylandServer()->seat()->textInputV3();
|
||||||
|
if (t3->isEnabled()) {
|
||||||
|
waylandServer()->inputMethod()->sendActivate();
|
||||||
|
adoptInputMethodContext();
|
||||||
|
} else {
|
||||||
|
waylandServer()->inputMethod()->sendDeactivate();
|
||||||
|
// reset value of preedit when textinput is disabled
|
||||||
|
preedit.text = QString();
|
||||||
|
preedit.begin = 0;
|
||||||
|
preedit.end = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void VirtualKeyboard::stateCommitted(uint32_t serial)
|
void VirtualKeyboard::stateCommitted(uint32_t serial)
|
||||||
{
|
{
|
||||||
auto inputContext = waylandServer()->inputMethod()->context();
|
auto inputContext = waylandServer()->inputMethod()->context();
|
||||||
|
@ -232,98 +275,160 @@ void VirtualKeyboard::setEnabled(bool enabled)
|
||||||
QDBusConnection::sessionBus().asyncCall(msg);
|
QDBusConnection::sessionBus().asyncCall(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static quint32 keysymToKeycode(quint32 sym)
|
||||||
|
{
|
||||||
|
switch(sym) {
|
||||||
|
case XKB_KEY_BackSpace:
|
||||||
|
return KEY_BACKSPACE;
|
||||||
|
case XKB_KEY_Return:
|
||||||
|
return KEY_ENTER;
|
||||||
|
case XKB_KEY_Left:
|
||||||
|
return KEY_LEFT;
|
||||||
|
case XKB_KEY_Right:
|
||||||
|
return KEY_RIGHT;
|
||||||
|
case XKB_KEY_Up:
|
||||||
|
return KEY_UP;
|
||||||
|
case XKB_KEY_Down:
|
||||||
|
return KEY_DOWN;
|
||||||
|
default:
|
||||||
|
return KEY_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void keysymReceived(quint32 serial, quint32 time, quint32 sym, bool pressed, Qt::KeyboardModifiers modifiers)
|
static void keysymReceived(quint32 serial, quint32 time, quint32 sym, bool pressed, Qt::KeyboardModifiers modifiers)
|
||||||
{
|
{
|
||||||
Q_UNUSED(serial)
|
Q_UNUSED(serial)
|
||||||
Q_UNUSED(time)
|
Q_UNUSED(time)
|
||||||
auto t = waylandServer()->seat()->textInputV2();
|
auto t2 = waylandServer()->seat()->textInputV2();
|
||||||
if (t && t->isEnabled()) {
|
if (t2 && t2->isEnabled()) {
|
||||||
if (pressed) {
|
if (pressed) {
|
||||||
t->keysymPressed(sym, modifiers);
|
t2->keysymPressed(sym, modifiers);
|
||||||
} else {
|
} else {
|
||||||
t->keysymReleased(sym, modifiers);
|
t2->keysymReleased(sym, modifiers);
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto t3 = waylandServer()->seat()->textInputV3();
|
||||||
|
if (t3 && t3->isEnabled()) {
|
||||||
|
if (pressed) {
|
||||||
|
waylandServer()->seat()->keyPressed(keysymToKeycode(sym));
|
||||||
|
} else {
|
||||||
|
waylandServer()->seat()->keyReleased(keysymToKeycode(sym));
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void commitString(qint32 serial, const QString &text)
|
static void commitString(qint32 serial, const QString &text)
|
||||||
{
|
{
|
||||||
Q_UNUSED(serial)
|
Q_UNUSED(serial)
|
||||||
auto t = waylandServer()->seat()->textInputV2();
|
auto t2 = waylandServer()->seat()->textInputV2();
|
||||||
if (t && t->isEnabled()) {
|
if (t2 && t2->isEnabled()) {
|
||||||
t->commit(text.toUtf8());
|
t2->commitString(text.toUtf8());
|
||||||
t->preEdit({}, {});
|
t2->preEdit({}, {});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
auto t3 = waylandServer()->seat()->textInputV3();
|
||||||
|
if (t3 && t3->isEnabled()) {
|
||||||
static void setPreeditCursor(qint32 index)
|
t3->commitString(text.toUtf8());
|
||||||
{
|
t3->done();
|
||||||
auto t = waylandServer()->seat()->textInputV2();
|
return;
|
||||||
if (t && t->isEnabled()) {
|
|
||||||
t->setPreEditCursor(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void setPreeditString(uint32_t serial, const QString &text, const QString &commit)
|
|
||||||
{
|
|
||||||
Q_UNUSED(serial)
|
|
||||||
auto t = waylandServer()->seat()->textInputV2();
|
|
||||||
if (t && t->isEnabled()) {
|
|
||||||
t->preEdit(text.toUtf8(), commit.toUtf8());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void deleteSurroundingText(int32_t index, uint32_t length)
|
static void deleteSurroundingText(int32_t index, uint32_t length)
|
||||||
{
|
{
|
||||||
auto t = waylandServer()->seat()->textInputV2();
|
auto t2 = waylandServer()->seat()->textInputV2();
|
||||||
if (t && t->isEnabled()) {
|
if (t2 && t2->isEnabled()) {
|
||||||
t->deleteSurroundingText(index, length);
|
t2->deleteSurroundingText(index, length);
|
||||||
|
}
|
||||||
|
auto t3 = waylandServer()->seat()->textInputV3();
|
||||||
|
if (t3 && t3->isEnabled()) {
|
||||||
|
t3->deleteSurroundingText(index, length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setCursorPosition(qint32 index, qint32 anchor)
|
static void setCursorPosition(qint32 index, qint32 anchor)
|
||||||
{
|
{
|
||||||
auto t = waylandServer()->seat()->textInputV2();
|
auto t2 = waylandServer()->seat()->textInputV2();
|
||||||
if (t && t->isEnabled()) {
|
if (t2 && t2->isEnabled()) {
|
||||||
t->setCursorPosition(index, anchor);
|
t2->setCursorPosition(index, anchor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setLanguage(uint32_t serial, const QString &language)
|
static void setLanguage(uint32_t serial, const QString &language)
|
||||||
{
|
{
|
||||||
Q_UNUSED(serial)
|
Q_UNUSED(serial)
|
||||||
auto t = waylandServer()->seat()->textInputV2();
|
auto t2 = waylandServer()->seat()->textInputV2();
|
||||||
if (t && t->isEnabled()) {
|
if (t2 && t2->isEnabled()) {
|
||||||
t->setLanguage(language.toUtf8());
|
t2->setLanguage(language.toUtf8());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setTextDirection(uint32_t serial, Qt::LayoutDirection direction)
|
static void setTextDirection(uint32_t serial, Qt::LayoutDirection direction)
|
||||||
{
|
{
|
||||||
Q_UNUSED(serial)
|
Q_UNUSED(serial)
|
||||||
auto t = waylandServer()->seat()->textInputV2();
|
auto t2 = waylandServer()->seat()->textInputV2();
|
||||||
if (t && t->isEnabled()) {
|
if (t2 && t2->isEnabled()) {
|
||||||
t->setTextDirection(direction);
|
t2->setTextDirection(direction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualKeyboard::setPreeditCursor(qint32 index)
|
||||||
|
{
|
||||||
|
auto t2 = waylandServer()->seat()->textInputV2();
|
||||||
|
if (t2 && t2->isEnabled()) {
|
||||||
|
t2->setPreEditCursor(index);
|
||||||
|
}
|
||||||
|
auto t3 = waylandServer()->seat()->textInputV3();
|
||||||
|
if (t3 && t3->isEnabled()) {
|
||||||
|
preedit.begin = index;
|
||||||
|
preedit.end = index;
|
||||||
|
t3->sendPreEditString(preedit.text, preedit.begin, preedit.end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void VirtualKeyboard::setPreeditString(uint32_t serial, const QString &text, const QString &commit)
|
||||||
|
{
|
||||||
|
Q_UNUSED(serial)
|
||||||
|
auto t2 = waylandServer()->seat()->textInputV2();
|
||||||
|
if (t2 && t2->isEnabled()) {
|
||||||
|
t2->preEdit(text.toUtf8(), commit.toUtf8());
|
||||||
|
}
|
||||||
|
auto t3 = waylandServer()->seat()->textInputV3();
|
||||||
|
if (t3 && t3->isEnabled()) {
|
||||||
|
preedit.text = text;
|
||||||
|
t3->sendPreEditString(preedit.text, preedit.begin, preedit.end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualKeyboard::adoptInputMethodContext()
|
void VirtualKeyboard::adoptInputMethodContext()
|
||||||
{
|
{
|
||||||
auto inputContext = waylandServer()->inputMethod()->context();
|
auto inputContext = waylandServer()->inputMethod()->context();
|
||||||
TextInputV2Interface *ti = waylandServer()->seat()->textInputV2();
|
|
||||||
|
|
||||||
inputContext->sendSurroundingText(ti->surroundingText(), ti->surroundingTextCursorPosition(), ti->surroundingTextSelectionAnchor());
|
TextInputV2Interface *t2 = waylandServer()->seat()->textInputV2();
|
||||||
inputContext->sendPreferredLanguage(ti->preferredLanguage());
|
TextInputV3Interface *t3 = waylandServer()->seat()->textInputV3();
|
||||||
inputContext->sendContentType(ti->contentHints(), ti->contentPurpose());
|
|
||||||
|
if (t2 && t2->isEnabled()) {
|
||||||
|
inputContext->sendSurroundingText(t2->surroundingText(), t2->surroundingTextCursorPosition(), t2->surroundingTextSelectionAnchor());
|
||||||
|
inputContext->sendPreferredLanguage(t2->preferredLanguage());
|
||||||
|
inputContext->sendContentType(t2->contentHints(), t2->contentPurpose());
|
||||||
|
connect(inputContext, &KWaylandServer::InputMethodContextV1Interface::language, waylandServer(), &setLanguage);
|
||||||
|
connect(inputContext, &KWaylandServer::InputMethodContextV1Interface::textDirection, waylandServer(), &setTextDirection);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t3 && t3->isEnabled()) {
|
||||||
|
inputContext->sendSurroundingText(t3->surroundingText(), t3->surroundingTextCursorPosition(), t3->surroundingTextSelectionAnchor());
|
||||||
|
inputContext->sendContentType(t3->contentHints(), t3->contentPurpose());
|
||||||
|
}
|
||||||
|
|
||||||
connect(inputContext, &KWaylandServer::InputMethodContextV1Interface::keysym, waylandServer(), &keysymReceived);
|
connect(inputContext, &KWaylandServer::InputMethodContextV1Interface::keysym, waylandServer(), &keysymReceived);
|
||||||
connect(inputContext, &KWaylandServer::InputMethodContextV1Interface::commitString, waylandServer(), &commitString);
|
connect(inputContext, &KWaylandServer::InputMethodContextV1Interface::commitString, waylandServer(), &commitString);
|
||||||
connect(inputContext, &KWaylandServer::InputMethodContextV1Interface::preeditCursor, waylandServer(), &setPreeditCursor);
|
|
||||||
connect(inputContext, &KWaylandServer::InputMethodContextV1Interface::preeditString, waylandServer(), &setPreeditString);
|
|
||||||
connect(inputContext, &KWaylandServer::InputMethodContextV1Interface::deleteSurroundingText, waylandServer(), &deleteSurroundingText);
|
connect(inputContext, &KWaylandServer::InputMethodContextV1Interface::deleteSurroundingText, waylandServer(), &deleteSurroundingText);
|
||||||
connect(inputContext, &KWaylandServer::InputMethodContextV1Interface::cursorPosition, waylandServer(), &setCursorPosition);
|
connect(inputContext, &KWaylandServer::InputMethodContextV1Interface::cursorPosition, waylandServer(), &setCursorPosition);
|
||||||
connect(inputContext, &KWaylandServer::InputMethodContextV1Interface::language, waylandServer(), &setLanguage);
|
connect(inputContext, &KWaylandServer::InputMethodContextV1Interface::preeditString, this, &VirtualKeyboard::setPreeditString);
|
||||||
connect(inputContext, &KWaylandServer::InputMethodContextV1Interface::textDirection, waylandServer(), &setTextDirection);
|
connect(inputContext, &KWaylandServer::InputMethodContextV1Interface::preeditCursor, this, &VirtualKeyboard::setPreeditCursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualKeyboard::updateSni()
|
void VirtualKeyboard::updateSni()
|
||||||
|
|
|
@ -42,15 +42,26 @@ private Q_SLOTS:
|
||||||
void surroundingTextChanged();
|
void surroundingTextChanged();
|
||||||
void contentTypeChanged();
|
void contentTypeChanged();
|
||||||
void requestReset();
|
void requestReset();
|
||||||
void textInputInterfaceEnabledChanged();
|
void textInputInterfaceV2EnabledChanged();
|
||||||
|
void textInputInterfaceV3EnabledChanged();
|
||||||
void stateCommitted(uint32_t serial);
|
void stateCommitted(uint32_t serial);
|
||||||
|
|
||||||
|
// inputcontext slots
|
||||||
|
void setPreeditString(uint32_t serial, const QString &text, const QString &commit);
|
||||||
|
void setPreeditCursor(qint32 index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setEnabled(bool enable);
|
void setEnabled(bool enable);
|
||||||
void updateSni();
|
void updateSni();
|
||||||
void updateInputPanelState();
|
void updateInputPanelState();
|
||||||
void adoptInputMethodContext();
|
void adoptInputMethodContext();
|
||||||
|
|
||||||
|
struct {
|
||||||
|
QString text = QString();
|
||||||
|
quint32 begin = 0;
|
||||||
|
quint32 end = 0;
|
||||||
|
} preedit;
|
||||||
|
|
||||||
bool m_enabled = false;
|
bool m_enabled = false;
|
||||||
KStatusNotifierItem *m_sni = nullptr;
|
KStatusNotifierItem *m_sni = nullptr;
|
||||||
QPointer<AbstractClient> m_inputClient;
|
QPointer<AbstractClient> m_inputClient;
|
||||||
|
|
Loading…
Reference in a new issue