fix: client to server modifier press/release

Pressing a modifier on the client and moving to the server and releasing
it breaks the modifier on the client. This resolves the issue.
This commit is contained in:
enzious 2025-10-18 05:03:15 -05:00 committed by Nick Bolton
parent ea7a493c13
commit b8bd6903e4
7 changed files with 28 additions and 0 deletions

View file

@ -103,6 +103,16 @@ public:
*/ */
virtual void fakeAllKeysUp() = 0; virtual void fakeAllKeysUp() = 0;
//! Clear stale modifiers
/*!
Clears stuck modifier state in platform-specific keyboard tracking (e.g. XKB).
Default implementation does nothing.
*/
virtual void clearStaleModifiers()
{
// Default implementation does nothing
}
//! Fake ctrl+alt+del //! Fake ctrl+alt+del
/*! /*!
Synthesize a press of ctrl+alt+del. Return true if processing is Synthesize a press of ctrl+alt+del. Return true if processing is

View file

@ -187,6 +187,7 @@ public:
KeyModifierMask pollActiveModifiers() const override = 0; KeyModifierMask pollActiveModifiers() const override = 0;
int32_t pollActiveGroup() const override = 0; int32_t pollActiveGroup() const override = 0;
void pollPressedKeys(KeyButtonSet &pressedKeys) const override = 0; void pollPressedKeys(KeyButtonSet &pressedKeys) const override = 0;
void clearStaleModifiers() override = 0;
protected: protected:
//! Handle system event //! Handle system event

View file

@ -760,6 +760,7 @@ void KeyState::updateKeyState()
} }
// get the current modifier state // get the current modifier state
clearStaleModifiers();
m_mask = pollActiveModifiers(); m_mask = pollActiveModifiers();
// set active modifiers // set active modifiers

View file

@ -85,6 +85,11 @@ void PlatformScreen::pollPressedKeys(KeyButtonSet &pressedKeys) const
getKeyState()->pollPressedKeys(pressedKeys); getKeyState()->pollPressedKeys(pressedKeys);
} }
void PlatformScreen::clearStaleModifiers()
{
getKeyState()->clearStaleModifiers();
}
int32_t PlatformScreen::mapClientScrollDirection(int32_t x) const int32_t PlatformScreen::mapClientScrollDirection(int32_t x) const
{ {
return (m_invertScrollDirection ? -x : x); return (m_invertScrollDirection ? -x : x);

View file

@ -62,6 +62,7 @@ public:
KeyModifierMask pollActiveModifiers() const override; KeyModifierMask pollActiveModifiers() const override;
int32_t pollActiveGroup() const override; int32_t pollActiveGroup() const override;
void pollPressedKeys(KeyButtonSet &pressedKeys) const override; void pollPressedKeys(KeyButtonSet &pressedKeys) const override;
void clearStaleModifiers() override;
// IPlatformScreen overrides // IPlatformScreen overrides
void enable() override = 0; void enable() override = 0;

View file

@ -309,4 +309,13 @@ void EiKeyState::updateXkbState(uint32_t keyval, bool isPressed)
xkb_state_update_key(m_xkbState, keyval, isPressed ? XKB_KEY_DOWN : XKB_KEY_UP); xkb_state_update_key(m_xkbState, keyval, isPressed ? XKB_KEY_DOWN : XKB_KEY_UP);
} }
void EiKeyState::clearStaleModifiers()
{
// Recreate the XKB state to clear stuck modifiers that happen when
// modifier keys are press on client and released on server
if (m_xkbState) {
xkb_state_unref(m_xkbState);
}
m_xkbState = xkb_state_new(m_xkbKeymap);
}
} // namespace deskflow } // namespace deskflow

View file

@ -35,6 +35,7 @@ public:
void pollPressedKeys(KeyButtonSet &pressedKeys) const override; void pollPressedKeys(KeyButtonSet &pressedKeys) const override;
KeyID mapKeyFromKeyval(std::uint32_t keyval) const; KeyID mapKeyFromKeyval(std::uint32_t keyval) const;
void updateXkbState(std::uint32_t keyval, bool isPressed); void updateXkbState(std::uint32_t keyval, bool isPressed);
void clearStaleModifiers() override;
protected: protected:
// KeyState overrides // KeyState overrides