Fix #40059: Use Modifier Keys Between Windows on Win32 #110020

Merged
Harley Acheson merged 1 commits from Harley/blender:Win32WindowModifiers into main 2023-07-12 20:01:43 +02:00
2 changed files with 11 additions and 24 deletions

View File

@ -464,24 +464,27 @@ GHOST_TSuccess GHOST_SystemWin32::setCursorPosition(int32_t x, int32_t y)
GHOST_TSuccess GHOST_SystemWin32::getModifierKeys(GHOST_ModifierKeys &keys) const
{
bool down = HIBYTE(::GetKeyState(VK_LSHIFT)) != 0;
/* `GetAsyncKeyState` returns the current interrupt-level state of the hardware, which is needed
* when passing key states to a newly-activated window - #40059. Alterative `GetKeyState` only
* returns the state as processed by the thread's message queue. */
bool down = HIBYTE(::GetAsyncKeyState(VK_LSHIFT)) != 0;
keys.set(GHOST_kModifierKeyLeftShift, down);
down = HIBYTE(::GetKeyState(VK_RSHIFT)) != 0;
down = HIBYTE(::GetAsyncKeyState(VK_RSHIFT)) != 0;
keys.set(GHOST_kModifierKeyRightShift, down);
down = HIBYTE(::GetKeyState(VK_LMENU)) != 0;
down = HIBYTE(::GetAsyncKeyState(VK_LMENU)) != 0;
keys.set(GHOST_kModifierKeyLeftAlt, down);
down = HIBYTE(::GetKeyState(VK_RMENU)) != 0;
down = HIBYTE(::GetAsyncKeyState(VK_RMENU)) != 0;
keys.set(GHOST_kModifierKeyRightAlt, down);
down = HIBYTE(::GetKeyState(VK_LCONTROL)) != 0;
down = HIBYTE(::GetAsyncKeyState(VK_LCONTROL)) != 0;
keys.set(GHOST_kModifierKeyLeftControl, down);
down = HIBYTE(::GetKeyState(VK_RCONTROL)) != 0;
down = HIBYTE(::GetAsyncKeyState(VK_RCONTROL)) != 0;
keys.set(GHOST_kModifierKeyRightControl, down);
down = HIBYTE(::GetKeyState(VK_LWIN)) != 0;
down = HIBYTE(::GetAsyncKeyState(VK_LWIN)) != 0;
keys.set(GHOST_kModifierKeyLeftOS, down);
down = HIBYTE(::GetKeyState(VK_RWIN)) != 0;
down = HIBYTE(::GetAsyncKeyState(VK_RWIN)) != 0;
keys.set(GHOST_kModifierKeyRightOS, down);
return GHOST_kSuccess;

View File

@ -1267,24 +1267,8 @@ static bool ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_pt
break;
}
case GHOST_kEventWindowActivate: {
#ifdef WIN32
/* NOTE(@ideasman42): Alt-Tab on Windows-10 (22H2) can deactivate the window,
* then (in rare cases - approx 1 in 20) immediately call `WM_ACTIVATE` on the window
* (which isn't active) and doesn't receive modifier release events.
* This looks like a bug in MS-Windows, searching online other apps
* have run into similar issues although it's not clear exactly which.
*
* - Therefor activation must always clear modifiers
* or Alt-Tab can occasionally get stuck, see: #105381.
* - Unfortunately modifiers that are held before
* the window is active are ignored, see: #40059.
*/
wm_window_update_eventstate_modifiers_clear(wm, win);
#else
/* Ensure the event state matches modifiers (window was inactive). */
wm_window_update_eventstate_modifiers(wm, win);
#endif
/* Entering window, update mouse position (without sending an event). */
wm_window_update_eventstate(win);