fix(wayland): sync locked modifiers from EI keyboard modifiers event
fixes: #8437
This commit is contained in:
parent
23b0d7792d
commit
ac475f0b1b
5 changed files with 50 additions and 1 deletions
|
|
@ -345,6 +345,20 @@ void EiKeyState::updateXkbState(uint32_t keyval, bool isPressed)
|
|||
xkb_state_update_key(m_xkbState, keyval, isPressed ? XKB_KEY_DOWN : XKB_KEY_UP);
|
||||
}
|
||||
|
||||
void EiKeyState::updateLockedModifiers(xkb_mod_mask_t lockedMods)
|
||||
{
|
||||
// The compositor's lock state (Caps/Num/Scroll Lock) is authoritative; it
|
||||
// also covers locks toggled while we weren't seeing the key events.
|
||||
const auto depressedMods = xkb_state_serialize_mods(m_xkbState, XKB_STATE_MODS_DEPRESSED);
|
||||
const auto latchedMods = xkb_state_serialize_mods(m_xkbState, XKB_STATE_MODS_LATCHED);
|
||||
const auto depressedLayout = xkb_state_serialize_layout(m_xkbState, XKB_STATE_LAYOUT_DEPRESSED);
|
||||
const auto latchedLayout = xkb_state_serialize_layout(m_xkbState, XKB_STATE_LAYOUT_LATCHED);
|
||||
const auto lockedLayout = xkb_state_serialize_layout(m_xkbState, XKB_STATE_LAYOUT_LOCKED);
|
||||
xkb_state_update_mask(
|
||||
m_xkbState, depressedMods, latchedMods, lockedMods, depressedLayout, latchedLayout, lockedLayout
|
||||
);
|
||||
}
|
||||
|
||||
void EiKeyState::clearStaleModifiers()
|
||||
{
|
||||
const auto lockedMods = xkb_state_serialize_mods(m_xkbState, XKB_STATE_MODS_LOCKED);
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ public:
|
|||
void pollPressedKeys(KeyButtonSet &pressedKeys) const override;
|
||||
KeyID mapKeyFromKeyval(std::uint32_t keyval) const;
|
||||
void updateXkbState(std::uint32_t keyval, bool isPressed);
|
||||
void updateLockedModifiers(xkb_mod_mask_t lockedMods);
|
||||
void clearStaleModifiers() override;
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -1025,7 +1025,8 @@ void EiScreen::handleSystemEvent(const Event &)
|
|||
}
|
||||
break;
|
||||
case EI_EVENT_KEYBOARD_MODIFIERS:
|
||||
// FIXME
|
||||
LOG_VERBOSE("event: keyboard modifiers locked=0x%x", ei_event_keyboard_get_xkb_mods_locked(event));
|
||||
m_keyState->updateLockedModifiers(ei_event_keyboard_get_xkb_mods_locked(event));
|
||||
break;
|
||||
|
||||
// events below are for a receiver context (barriers)
|
||||
|
|
|
|||
|
|
@ -102,4 +102,36 @@ void EiKeyStateTests::clearStaleModifiers_shiftDownAndNumLockOn_shiftClearedAndN
|
|||
QVERIFY((keyState.pollActiveModifiers() & KeyModifierNumLock) != 0);
|
||||
}
|
||||
|
||||
void EiKeyStateTests::updateLockedModifiers_compositorLockState_numLockFollowsCompositor()
|
||||
{
|
||||
// Real modifier Mod2 is index 4 (Shift, Lock, Control, Mod1, Mod2, ...).
|
||||
constexpr std::uint32_t xkbMod2Mask = 1 << 4;
|
||||
|
||||
TestAppUtil appUtil;
|
||||
EventQueue eventQueue;
|
||||
deskflow::EiKeyState keyState(nullptr, &eventQueue);
|
||||
|
||||
QTemporaryFile keymapFile;
|
||||
QVERIFY(keymapFile.open());
|
||||
const QByteArray keymapData = QByteArray::fromRawData(TestKeymap, sizeof(TestKeymap) - 1);
|
||||
QCOMPARE(keymapFile.write(keymapData), keymapData.size());
|
||||
QVERIFY(keymapFile.flush());
|
||||
keyState.init(keymapFile.handle(), keymapFile.size());
|
||||
|
||||
keyState.updateXkbState(LeftShiftKeycode, true);
|
||||
QVERIFY((keyState.pollActiveModifiers() & KeyModifierNumLock) == 0);
|
||||
|
||||
// NumLock toggled on locally, reported by the compositor
|
||||
keyState.updateLockedModifiers(xkbMod2Mask);
|
||||
QVERIFY((keyState.pollActiveModifiers() & KeyModifierNumLock) != 0);
|
||||
QVERIFY((keyState.pollActiveModifiers() & KeyModifierShift) != 0);
|
||||
|
||||
keyState.clearStaleModifiers();
|
||||
QVERIFY((keyState.pollActiveModifiers() & KeyModifierNumLock) != 0);
|
||||
|
||||
// NumLock toggled off locally
|
||||
keyState.updateLockedModifiers(0);
|
||||
QVERIFY((keyState.pollActiveModifiers() & KeyModifierNumLock) == 0);
|
||||
}
|
||||
|
||||
QTEST_MAIN(EiKeyStateTests)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ class EiKeyStateTests : public QObject
|
|||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
void clearStaleModifiers_shiftDownAndNumLockOn_shiftClearedAndNumLockPreserved();
|
||||
void updateLockedModifiers_compositorLockState_numLockFollowsCompositor();
|
||||
|
||||
private:
|
||||
Arch m_arch;
|
||||
|
|
|
|||
Loading…
Reference in a new issue