From d66be7b99fc5c839cef7e9b7c32f46e57dc670bd Mon Sep 17 00:00:00 2001 From: Weng Xuetian Date: Mon, 13 Dec 2021 09:26:01 -0800 Subject: [PATCH] Forward xkb modifier changes to input method. Since not all the key are forwarded to input method, any modifier changes need to be forwarded to input method as long as keyboard grab is active. --- src/inputmethod.cpp | 15 +++++++++++++++ src/inputmethod.h | 1 + src/xkb.cpp | 22 +++++++++++++++++----- src/xkb.h | 6 ++++++ 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/inputmethod.cpp b/src/inputmethod.cpp index 12ce32958d..24ee6bd0a8 100644 --- a/src/inputmethod.cpp +++ b/src/inputmethod.cpp @@ -104,6 +104,8 @@ void InputMethod::init() connect(textInputV2, &TextInputV2Interface::enabledChanged, this, &InputMethod::textInputInterfaceV2EnabledChanged); connect(textInputV3, &TextInputV3Interface::enabledChanged, this, &InputMethod::textInputInterfaceV3EnabledChanged); } + + connect(input()->keyboard()->xkb(), &Xkb::modifierStateChanged, this, &InputMethod::forwardModifiers); } } @@ -484,6 +486,18 @@ void InputMethod::modifiers(quint32 serial, quint32 mods_depressed, quint32 mods xkb->updateModifiers(mods_depressed, mods_latched, mods_locked, group); } +void InputMethod::forwardModifiers() +{ + auto xkb = input()->keyboard()->xkb(); + if (m_keyboardGrab) { + m_keyboardGrab->sendModifiers(waylandServer()->display()->nextSerial(), + xkb->modifierState().depressed, + xkb->modifierState().latched, + xkb->modifierState().locked, + xkb->currentLayout()); + } +} + void InputMethod::adoptInputMethodContext() { auto inputContext = waylandServer()->inputMethod()->context(); @@ -640,6 +654,7 @@ void InputMethod::installKeyboardGrab(KWaylandServer::InputMethodGrabV1 *keyboar auto xkb = input()->keyboard()->xkb(); m_keyboardGrab = keyboardGrab; keyboardGrab->sendKeymap(xkb->keymapContents()); + forwardModifiers(); } void InputMethod::updateModifiersMap(const QByteArray &modifiers) diff --git a/src/inputmethod.h b/src/inputmethod.h index 578a268b7c..0ba9ce4a85 100644 --- a/src/inputmethod.h +++ b/src/inputmethod.h @@ -97,6 +97,7 @@ private: void updateModifiersMap(const QByteArray &modifiers); bool touchEventTriggered() const; + void forwardModifiers(); struct { QString text = QString(); diff --git a/src/xkb.cpp b/src/xkb.cpp index 2e8a505717..cb66780eb7 100644 --- a/src/xkb.cpp +++ b/src/xkb.cpp @@ -330,7 +330,10 @@ void Xkb::updateModifiers(uint32_t modsDepressed, uint32_t modsLatched, uint32_t if (!m_keymap || !m_state) { return; } - xkb_state_update_mask(m_state, modsDepressed, modsLatched, modsLocked, 0, 0, group); + // Avoid to create a infinite loop between input method and compositor. + if (xkb_state_update_mask(m_state, modsDepressed, modsLatched, modsLocked, 0, 0, group) == 0) { + return; + } updateModifiers(); forwardModifiers(); } @@ -400,10 +403,19 @@ void Xkb::updateModifiers() Q_EMIT ledsChanged(m_leds); } - m_currentLayout = xkb_state_serialize_layout(m_state, XKB_STATE_LAYOUT_EFFECTIVE); - m_modifierState.depressed = xkb_state_serialize_mods(m_state, xkb_state_component(XKB_STATE_MODS_DEPRESSED)); - m_modifierState.latched = xkb_state_serialize_mods(m_state, xkb_state_component(XKB_STATE_MODS_LATCHED)); - m_modifierState.locked = xkb_state_serialize_mods(m_state, xkb_state_component(XKB_STATE_MODS_LOCKED)); + const uint32_t newLayout = xkb_state_serialize_layout(m_state, XKB_STATE_LAYOUT_EFFECTIVE); + const uint32_t depressed = xkb_state_serialize_mods(m_state, XKB_STATE_MODS_DEPRESSED); + const uint32_t latched = xkb_state_serialize_mods(m_state, XKB_STATE_MODS_LATCHED); + const uint32_t locked = xkb_state_serialize_mods(m_state, XKB_STATE_MODS_LOCKED); + + if (newLayout != m_currentLayout || depressed != m_modifierState.depressed || latched != m_modifierState.latched || locked != m_modifierState.locked) { + m_currentLayout = newLayout; + m_modifierState.depressed = depressed; + m_modifierState.latched = latched; + m_modifierState.locked = locked; + + Q_EMIT modifierStateChanged(); + } } void Xkb::forwardModifiers() diff --git a/src/xkb.h b/src/xkb.h index 8d5b8e504b..e44f356fcf 100644 --- a/src/xkb.h +++ b/src/xkb.h @@ -81,6 +81,11 @@ public: quint32 currentLayout() const { return m_currentLayout; } + + const auto &modifierState() const + { + return m_modifierState; + } QString layoutName(xkb_layout_index_t index) const; QString layoutName() const; QString layoutShortName(int index) const; @@ -96,6 +101,7 @@ public: Q_SIGNALS: void ledsChanged(const LEDs &leds); + void modifierStateChanged(); private: void applyEnvironmentRules(xkb_rule_names &);