diff options
author | Campbell Barton <campbell@blender.org> | 2022-08-26 15:24:08 +0300 |
---|---|---|
committer | Campbell Barton <campbell@blender.org> | 2022-08-27 00:36:00 +0300 |
commit | 37d835f0bca28a7cbf577385d9828636e7811cc5 (patch) | |
tree | ca9ab4d2abcd5e22cb9148b30d7016ebb66175d6 /intern | |
parent | 07ccb9b5735ce7a12e40c1243032e18d8ed42737 (diff) |
Fix T100582: Windows-10 Switching Desktops locks Ctrl Key
Regression in recent fix for T66088 [0]. caused by much older problem
introduced with [1] & [2].
Unlike other platforms, as of [1] GHOST/Win32 was keeping track of the
pressed modifier keys.
Since GHOST/Win32 cleared the modifier state on window activation [2]
and only changes to modifier state would generate key events, activating
the window and releasing the modifier would not send the release event.
Resolve this by removing the stored modifier state from GHOST/Win32,
always passing modifier press/release events through to Blender
(matching other GHOST back-ends).
Instead, use key-repeat detection to prevent repeated modifier keys
from being generated - an alternate solution to T26446.
[0]: 8bc76bf4b957c51ddc5a13c6305f05c64b218a27
[1]: d6b43fed313b60bb6a269680b3c5622955b8a690
[2]: 6b987910e43ff5f91512a3c361ea3141590d4e45
Diffstat (limited to 'intern')
-rw-r--r-- | intern/ghost/intern/GHOST_SystemWin32.cpp | 97 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemWin32.h | 27 |
2 files changed, 19 insertions, 105 deletions
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index 31483377c73..3fd0e455fb6 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -534,16 +534,9 @@ GHOST_TSuccess GHOST_SystemWin32::exit() return GHOST_System::exit(); } -GHOST_TKey GHOST_SystemWin32::hardKey(RAWINPUT const &raw, - bool *r_keyDown, - bool *r_is_repeated_modifier) +GHOST_TKey GHOST_SystemWin32::hardKey(RAWINPUT const &raw, bool *r_keyDown) { - bool is_repeated_modifier = false; - - GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); GHOST_TKey key = GHOST_kKeyUnknown; - GHOST_ModifierKeys modifiers; - system->retrieveModifierKeys(modifiers); // RI_KEY_BREAK doesn't work for sticky keys release, so we also // check for the up message @@ -553,56 +546,6 @@ GHOST_TKey GHOST_SystemWin32::hardKey(RAWINPUT const &raw, key = this->convertKey(raw.data.keyboard.VKey, raw.data.keyboard.MakeCode, (raw.data.keyboard.Flags & (RI_KEY_E1 | RI_KEY_E0))); - - // extra handling of modifier keys: don't send repeats out from GHOST - if (key >= GHOST_kKeyLeftShift && key <= GHOST_kKeyRightAlt) { - bool changed = false; - GHOST_TModifierKey modifier; - switch (key) { - case GHOST_kKeyLeftShift: { - changed = (modifiers.get(GHOST_kModifierKeyLeftShift) != *r_keyDown); - modifier = GHOST_kModifierKeyLeftShift; - break; - } - case GHOST_kKeyRightShift: { - changed = (modifiers.get(GHOST_kModifierKeyRightShift) != *r_keyDown); - modifier = GHOST_kModifierKeyRightShift; - break; - } - case GHOST_kKeyLeftControl: { - changed = (modifiers.get(GHOST_kModifierKeyLeftControl) != *r_keyDown); - modifier = GHOST_kModifierKeyLeftControl; - break; - } - case GHOST_kKeyRightControl: { - changed = (modifiers.get(GHOST_kModifierKeyRightControl) != *r_keyDown); - modifier = GHOST_kModifierKeyRightControl; - break; - } - case GHOST_kKeyLeftAlt: { - changed = (modifiers.get(GHOST_kModifierKeyLeftAlt) != *r_keyDown); - modifier = GHOST_kModifierKeyLeftAlt; - break; - } - case GHOST_kKeyRightAlt: { - changed = (modifiers.get(GHOST_kModifierKeyRightAlt) != *r_keyDown); - modifier = GHOST_kModifierKeyRightAlt; - break; - } - default: - break; - } - - if (changed) { - modifiers.set(modifier, *r_keyDown); - system->storeModifierKeys(modifiers); - } - else { - is_repeated_modifier = true; - } - } - - *r_is_repeated_modifier = is_repeated_modifier; return key; } @@ -1182,34 +1125,33 @@ void GHOST_SystemWin32::processWheelEvent(GHOST_WindowWin32 *window, WPARAM wPar GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RAWINPUT const &raw) { + const char vk = raw.data.keyboard.VKey; bool keyDown = false; - bool is_repeated_modifier = false; GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); - GHOST_TKey key = system->hardKey(raw, &keyDown, &is_repeated_modifier); + GHOST_TKey key = system->hardKey(raw, &keyDown); GHOST_EventKey *event; + bool is_repeat = false; + bool is_repeated_modifier = false; + if (keyDown) { + if (system->m_keycode_last_repeat_key == vk) { + is_repeat = true; + is_repeated_modifier = (key >= GHOST_kKeyLeftShift && key <= GHOST_kKeyRightAlt); + } + system->m_keycode_last_repeat_key = vk; + } + else { + if (system->m_keycode_last_repeat_key == vk) { + system->m_keycode_last_repeat_key = 0; + } + } + /* We used to check `if (key != GHOST_kKeyUnknown)`, but since the message * values `WM_SYSKEYUP`, `WM_KEYUP` and `WM_CHAR` are ignored, we capture * those events here as well. */ if (!is_repeated_modifier) { - char vk = raw.data.keyboard.VKey; char utf8_char[6] = {0}; char ascii = 0; - bool is_repeat = false; - - /* Unlike on Linux, not all keys can send repeat events. E.g. modifier keys don't. */ - if (keyDown) { - if (system->m_keycode_last_repeat_key == vk) { - is_repeat = true; - } - system->m_keycode_last_repeat_key = vk; - } - else { - if (system->m_keycode_last_repeat_key == vk) { - system->m_keycode_last_repeat_key = 0; - } - } - wchar_t utf16[3] = {0}; BYTE state[256] = {0}; int r; @@ -1907,9 +1849,6 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, * If the windows use different input queues, the message is sent asynchronously, * so the window is activated immediately. */ { - GHOST_ModifierKeys modifiers; - modifiers.clear(); - system->storeModifierKeys(modifiers); system->m_wheelDeltaAccum = 0; system->m_keycode_last_repeat_key = 0; event = processWindowEvent(LOWORD(wParam) ? GHOST_kEventWindowActivate : diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h index b40f5e3fd75..c9de3b22d54 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.h +++ b/intern/ghost/intern/GHOST_SystemWin32.h @@ -299,7 +299,7 @@ class GHOST_SystemWin32 : public GHOST_System { * \param vk: Pointer to virtual key. * \return The GHOST key (GHOST_kKeyUnknown if no match). */ - GHOST_TKey hardKey(RAWINPUT const &raw, bool *r_keyDown, bool *r_is_repeated_modifier); + GHOST_TKey hardKey(RAWINPUT const &raw, bool *r_keyDown); /** * Creates mouse button event. @@ -417,19 +417,6 @@ class GHOST_SystemWin32 : public GHOST_System { void processTrackpad(); /** - * Returns the local state of the modifier keys (from the message queue). - * \param keys: The state of the keys. - */ - inline void retrieveModifierKeys(GHOST_ModifierKeys &keys) const; - - /** - * Stores the state of the modifier keys locally. - * For internal use only! - * param keys The new state of the modifier keys. - */ - inline void storeModifierKeys(const GHOST_ModifierKeys &keys); - - /** * Check current key layout for AltGr */ inline void handleKeyboardChange(void); @@ -446,8 +433,6 @@ class GHOST_SystemWin32 : public GHOST_System { */ int setConsoleWindowState(GHOST_TConsoleWindowState action); - /** The current state of the modifier keys. */ - GHOST_ModifierKeys m_modifierKeys; /** The virtual-key code (VKey) of the last press event. Used to detect repeat events. */ unsigned short m_keycode_last_repeat_key; /** State variable set at initialization. */ @@ -472,16 +457,6 @@ class GHOST_SystemWin32 : public GHOST_System { int m_wheelDeltaAccum; }; -inline void GHOST_SystemWin32::retrieveModifierKeys(GHOST_ModifierKeys &keys) const -{ - keys = m_modifierKeys; -} - -inline void GHOST_SystemWin32::storeModifierKeys(const GHOST_ModifierKeys &keys) -{ - m_modifierKeys = keys; -} - inline void GHOST_SystemWin32::handleKeyboardChange(void) { m_keylayout = GetKeyboardLayout(0); // get keylayout for current thread |