From 24f3cb9b5c1b089b56a9601e175ac9d33a86dda0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 3 Mar 2023 23:04:28 +1100 Subject: [PATCH] Fix #105381: Alt-Tab causes Alt to stick with multiple monitors on WIN32 Window activation events on Windows-10 don't seem to be reliable as it's possible for Alt-Tab to trigger WM_ACTIVATE on a window when switching away from it. As detecting the keys which are held relies on a valid active state - this meant Alt could become stuck when using Alt-Tab to switch between windows. Disable reading modifiers on activation for WIN32, activating the window now clears modifiers on WIN32. This isn't ideal as held modifiers wont be detected, re-introducing the error reported in #40059. --- source/blender/windowmanager/intern/wm_window.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 94f2aaddb8d..ca0e3355557 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1233,8 +1233,24 @@ static bool ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_pt } 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);