From 437edb45ca84d0a2a374a51568010da6fca10c08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Fri, 13 Jan 2017 20:41:21 +0100 Subject: [PATCH] Use an InputEventSpy to notify about key and modifier state changes Summary: Instead of emitting the key state changed and modifier state changed signals from the right point before processing the events, let's use an InputEventSpy to do that. The spies were introduced to be called directly before the event processing. So the contract still holds. Reviewers: #kwin, #plasma_on_wayland Subscribers: plasma-devel, kwin Tags: #plasma_on_wayland, #kwin Differential Revision: https://phabricator.kde.org/D4128 --- keyboard_input.cpp | 64 +++++++++++++++++++++++++++++++++++++++------- keyboard_input.h | 2 ++ 2 files changed, 57 insertions(+), 9 deletions(-) diff --git a/keyboard_input.cpp b/keyboard_input.cpp index 21ccc19190..f48deefea9 100644 --- a/keyboard_input.cpp +++ b/keyboard_input.cpp @@ -506,10 +506,64 @@ KeyboardInputRedirection::KeyboardInputRedirection(InputRedirection *parent) KeyboardInputRedirection::~KeyboardInputRedirection() = default; +class KeyStateChangedSpy : public InputEventSpy +{ +public: + KeyStateChangedSpy(InputRedirection *input) + : m_input(input) + { + } + + void keyEvent(KeyEvent *event) override + { + if (event->isAutoRepeat()) { + return; + } + emit m_input->keyStateChanged(event->nativeScanCode(), event->type() == QEvent::KeyPress ? InputRedirection::KeyboardKeyPressed : InputRedirection::KeyboardKeyReleased); + } + +private: + InputRedirection *m_input; +}; + +class ModifiersChangedSpy : public InputEventSpy +{ +public: + ModifiersChangedSpy(InputRedirection *input) + : m_input(input) + , m_modifiers() + { + } + + void keyEvent(KeyEvent *event) override + { + if (event->isAutoRepeat()) { + return; + } + updateModifiers(event->modifiers()); + } + + void updateModifiers(Qt::KeyboardModifiers mods) + { + if (mods == m_modifiers) { + return; + } + emit m_input->keyboardModifiersChanged(mods, m_modifiers); + m_modifiers = mods; + } + +private: + InputRedirection *m_input; + Qt::KeyboardModifiers m_modifiers; +}; + void KeyboardInputRedirection::init() { Q_ASSERT(!m_inited); m_inited = true; + m_input->installInputEventSpy(new KeyStateChangedSpy(m_input)); + m_modifiersChangedSpy = new ModifiersChangedSpy(m_input); + m_input->installInputEventSpy(m_modifiersChangedSpy); // setup key repeat m_keyRepeat.timer = new QTimer(this); @@ -644,12 +698,7 @@ void KeyboardInputRedirection::processKey(uint32_t key, InputRedirection::Keyboa } if (!autoRepeat) { - emit m_input->keyStateChanged(key, state); - const Qt::KeyboardModifiers oldMods = modifiers(); m_xkb->updateKey(key, state); - if (oldMods != modifiers()) { - emit m_input->keyboardModifiersChanged(modifiers(), oldMods); - } } const xkb_keysym_t keySym = m_xkb->currentKeysym(); @@ -686,11 +735,8 @@ void KeyboardInputRedirection::processModifiers(uint32_t modsDepressed, uint32_t return; } // TODO: send to proper Client and also send when active Client changes - Qt::KeyboardModifiers oldMods = modifiers(); m_xkb->updateModifiers(modsDepressed, modsLatched, modsLocked, group); - if (oldMods != modifiers()) { - emit m_input->keyboardModifiersChanged(modifiers(), oldMods); - } + m_modifiersChangedSpy->updateModifiers(modifiers()); } void KeyboardInputRedirection::processKeymapChange(int fd, uint32_t size) diff --git a/keyboard_input.h b/keyboard_input.h index f473a569d4..729de26ebd 100644 --- a/keyboard_input.h +++ b/keyboard_input.h @@ -43,6 +43,7 @@ namespace KWin { class InputRedirection; +class ModifiersChangedSpy; class Toplevel; namespace LibInput @@ -179,6 +180,7 @@ private: quint32 time = 0; QTimer *timer = nullptr; } m_keyRepeat; + ModifiersChangedSpy *m_modifiersChangedSpy = nullptr; }; inline