diff --git a/src/lib/platform/OSXKeyState.cpp b/src/lib/platform/OSXKeyState.cpp index 7a8e42cd..b86bb04b 100644 --- a/src/lib/platform/OSXKeyState.cpp +++ b/src/lib/platform/OSXKeyState.cpp @@ -458,6 +458,47 @@ COSXKeyState::pollPressedKeys(KeyButtonSet& pressedKeys) const } } +void +COSXKeyState::fixStickyKeys() +{ + KeyModifierMask synergyMask = getActiveModifiers(); + KeyModifierMask hardwareMask = pollActiveModifiers(); + if (synergyMask != hardwareMask) { + + // modifier key stuck + // compute changed modifiers + KeyModifierMask changed = (hardwareMask ^ synergyMask); + + if (changed) { + KeyButton kb; + CString keyFixed; + // synthesize changed modifier keys + if ((changed & KeyModifierShift) != 0) { + kb = mapVirtualKeyToKeyButton(s_shiftVK); + fakeKeyUp(kb); + keyFixed.append("shift "); + } + if ((changed & KeyModifierControl) != 0) { + kb = mapVirtualKeyToKeyButton(s_controlVK); + fakeKeyUp(kb); + keyFixed.append("ctrl "); + } + if ((changed & KeyModifierAlt) != 0) { + kb = mapVirtualKeyToKeyButton(s_altVK); + fakeKeyUp(kb); + keyFixed.append("alt "); + } + if ((changed & KeyModifierSuper) != 0) { + kb = mapVirtualKeyToKeyButton(s_superVK); + fakeKeyUp(kb); + keyFixed.append("cmd "); + } + + LOG((CLOG_DEBUG "fixed stuck modifier key: %s", keyFixed.c_str())); + } + } +} + void COSXKeyState::getKeyMap(CKeyMap& keyMap) { diff --git a/src/lib/platform/OSXKeyState.h b/src/lib/platform/OSXKeyState.h index fad80701..9030b373 100644 --- a/src/lib/platform/OSXKeyState.h +++ b/src/lib/platform/OSXKeyState.h @@ -99,7 +99,7 @@ public: pollActiveModifiers() const; virtual SInt32 pollActiveGroup() const; virtual void pollPressedKeys(KeyButtonSet& pressedKeys) const; - + void fixStickyKeys(); protected: // CKeyState overrides virtual void getKeyMap(CKeyMap& keyMap); diff --git a/src/lib/platform/OSXScreen.cpp b/src/lib/platform/OSXScreen.cpp index cf58aaa2..1484dc7e 100644 --- a/src/lib/platform/OSXScreen.cpp +++ b/src/lib/platform/OSXScreen.cpp @@ -527,6 +527,8 @@ COSXScreen::postMouseEvent(CGPoint& pos) const void COSXScreen::fakeMouseButton(ButtonID id, bool press) { + m_keyState->fixStickyKeys(); + NXEventHandle handle = NXOpenEventStatus(); double clickTime = NXClickTime(handle);