From 11f6292cb5d9d44d043ea24de95bac0873423a7d Mon Sep 17 00:00:00 2001 From: Weng Xuetian Date: Mon, 13 Dec 2021 09:23:23 -0800 Subject: [PATCH] Move input keyboard filter to be just before the key is sent to application. Features like global shortcuts should be handled before the input method. --- src/input.cpp | 20 ++++++++++++++++++++ src/inputmethod.cpp | 27 +++++---------------------- src/inputmethod.h | 3 +++ 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/src/input.cpp b/src/input.cpp index cd76b8e97c..5ca8d8bd51 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -18,6 +18,7 @@ #include "input_event.h" #include "input_event_spy.h" #include "inputbackend.h" +#include "inputmethod.h" #include "keyboard_input.h" #include "main.h" #include "pointer_input.h" @@ -44,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -1487,6 +1489,23 @@ public: } }; +class InputKeyboardFilter : public InputEventFilter +{ +public: + bool keyEvent(QKeyEvent *event) override + { + if (auto keyboardGrab = InputMethod::self()->keyboardGrab()) { + if (event->isAutoRepeat()) { + return true; + } + auto newState = event->type() == QEvent::KeyPress ? KWaylandServer::KeyboardKeyState::Pressed : KWaylandServer::KeyboardKeyState::Released; + keyboardGrab->sendKey(waylandServer()->display()->nextSerial(), event->timestamp(), event->nativeScanCode(), newState); + return true; + } + return false; + } +}; + /** * The remaining default input filter which forwards events to other windows */ @@ -2450,6 +2469,7 @@ void InputRedirection::setupInputFilters() installInputEventFilter(new DecorationEventFilter); installInputEventFilter(new WindowActionInputFilter); installInputEventFilter(new InternalWindowEventFilter); + installInputEventFilter(new InputKeyboardFilter); installInputEventFilter(new ForwardInputFilter); installInputEventFilter(new TabletInputFilter); } diff --git a/src/inputmethod.cpp b/src/inputmethod.cpp index 88b9ee5f16..12ce32958d 100644 --- a/src/inputmethod.cpp +++ b/src/inputmethod.cpp @@ -630,33 +630,16 @@ bool InputMethod::isActive() const return waylandServer()->inputMethod()->context(); } -class InputKeyboardFilter : public InputEventFilter { -public: - InputKeyboardFilter(KWaylandServer::InputMethodGrabV1 *grab) - : m_keyboardGrab(grab) - { - } - - bool keyEvent(QKeyEvent *event) override { - if (event->isAutoRepeat()) { - return true; - } - auto newState = event->type() == QEvent::KeyPress ? KWaylandServer::KeyboardKeyState::Pressed : KWaylandServer::KeyboardKeyState::Released; - m_keyboardGrab->sendKey(waylandServer()->display()->nextSerial(), event->timestamp(), event->nativeScanCode(), newState); - return true; - } - InputMethodGrabV1 *const m_keyboardGrab; -}; +KWaylandServer::InputMethodGrabV1 *InputMethod::keyboardGrab() +{ + return isActive() ? m_keyboardGrab : nullptr; +} void InputMethod::installKeyboardGrab(KWaylandServer::InputMethodGrabV1 *keyboardGrab) { auto xkb = input()->keyboard()->xkb(); - auto filter = new InputKeyboardFilter(keyboardGrab); + m_keyboardGrab = keyboardGrab; keyboardGrab->sendKeymap(xkb->keymapContents()); - input()->prependInputEventFilter(filter); - connect(keyboardGrab, &QObject::destroyed, input(), [filter] { - input()->uninstallInputEventFilter(filter); - }); } void InputMethod::updateModifiersMap(const QByteArray &modifiers) diff --git a/src/inputmethod.h b/src/inputmethod.h index 6f06c663fe..578a268b7c 100644 --- a/src/inputmethod.h +++ b/src/inputmethod.h @@ -57,6 +57,8 @@ public: void setPanel(InputPanelV1Client* client); void setInputMethodCommand(const QString &path); + KWaylandServer::InputMethodGrabV1 *keyboardGrab(); + Q_SIGNALS: void activeChanged(bool active); void enabledChanged(bool enabled); @@ -106,6 +108,7 @@ private: quint32 m_serial = 0; QPointer m_inputClient; QPointer m_trackedClient; + QPointer m_keyboardGrab; QProcess *m_inputMethodProcess = nullptr; QTimer m_inputMethodCrashTimer;