diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2024-04-06 13:06:04 +0200 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2024-04-06 13:06:04 +0200 |
commit | 02cb74e2234228c2888d56e11db2c7ea9f91725d (patch) | |
tree | d55bf4c50731842598bf9c222f95938d45a4e39b | |
parent | 655e93d5846b2ef8ebb7d22c8878f51b8f22b312 (diff) | |
parent | 9240034d3c6c41fd8e027663f82e61be9386c882 (diff) | |
download | redot-engine-02cb74e2234228c2888d56e11db2c7ea9f91725d.tar.gz |
Merge pull request #84363 from RandomShaper/win_focus_activ
Robustify handling of activation & focus on Windows
-rw-r--r-- | platform/windows/display_server_windows.cpp | 87 | ||||
-rw-r--r-- | platform/windows/display_server_windows.h | 1 |
2 files changed, 20 insertions, 68 deletions
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index e540b7617f..2e007b5efc 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -3709,63 +3709,18 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA return MA_NOACTIVATE; // Do not activate, but process mouse messages. } } break; - case WM_SETFOCUS: { - windows[window_id].window_has_focus = true; - last_focused_window = window_id; - - // Restore mouse mode. - _set_mouse_mode_impl(mouse_mode); - - if (!app_focused) { - if (OS::get_singleton()->get_main_loop()) { - OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_IN); - } - app_focused = true; - } - } break; - case WM_KILLFOCUS: { - windows[window_id].window_has_focus = false; - last_focused_window = window_id; - - // Release capture unconditionally because it can be set due to dragging, in addition to captured mode. - ReleaseCapture(); - - // Release every touch to avoid sticky points. - for (const KeyValue<int, Vector2> &E : touch_state) { - _touch_event(window_id, false, E.value.x, E.value.y, E.key); - } - touch_state.clear(); - - bool self_steal = false; - HWND new_hwnd = (HWND)wParam; - if (IsWindow(new_hwnd)) { - self_steal = true; + case WM_ACTIVATEAPP: { + bool new_app_focused = (bool)wParam; + if (new_app_focused == app_focused) { + break; } - - if (!self_steal) { - if (OS::get_singleton()->get_main_loop()) { - OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT); - } - app_focused = false; + app_focused = new_app_focused; + if (OS::get_singleton()->get_main_loop()) { + OS::get_singleton()->get_main_loop()->notification(app_focused ? MainLoop::NOTIFICATION_APPLICATION_FOCUS_IN : MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT); } } break; - case WM_ACTIVATE: { // Watch for window activate message. - if (!windows[window_id].window_focused) { - _process_activate_event(window_id, wParam, lParam); - } else { - windows[window_id].saved_wparam = wParam; - windows[window_id].saved_lparam = lParam; - - // Run a timer to prevent event catching warning if the focused window is closing. - windows[window_id].focus_timer_id = SetTimer(windows[window_id].hWnd, 2, USER_TIMER_MINIMUM, (TIMERPROC) nullptr); - } - if (wParam != WA_INACTIVE) { - track_mouse_leave_event(hWnd); - - if (!IsIconic(hWnd)) { - SetFocus(hWnd); - } - } + case WM_ACTIVATE: { + _process_activate_event(window_id, wParam, lParam); return 0; // Return to the message loop. } break; case WM_GETMINMAXINFO: { @@ -3864,9 +3819,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } break; case WM_CLOSE: // Did we receive a close message? { - if (windows[window_id].focus_timer_id != 0U) { - KillTimer(windows[window_id].hWnd, windows[window_id].focus_timer_id); - } _send_window_event(windows[window_id], WINDOW_EVENT_CLOSE_REQUEST); return 0; // Jump back. @@ -4625,10 +4577,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA if (!Main::is_iterating()) { Main::iteration(); } - } else if (wParam == windows[window_id].focus_timer_id) { - _process_activate_event(window_id, windows[window_id].saved_wparam, windows[window_id].saved_lparam); - KillTimer(windows[window_id].hWnd, wParam); - windows[window_id].focus_timer_id = 0U; } } break; case WM_SYSKEYUP: @@ -4834,20 +4782,25 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { void DisplayServerWindows::_process_activate_event(WindowID p_window_id, WPARAM wParam, LPARAM lParam) { if (LOWORD(wParam) == WA_ACTIVE || LOWORD(wParam) == WA_CLICKACTIVE) { - _send_window_event(windows[p_window_id], WINDOW_EVENT_FOCUS_IN); - windows[p_window_id].window_focused = true; + last_focused_window = p_window_id; alt_mem = false; control_mem = false; shift_mem = false; gr_mem = false; - - // Restore mouse mode. _set_mouse_mode_impl(mouse_mode); + if (!IsIconic(windows[p_window_id].hWnd)) { + SetFocus(windows[p_window_id].hWnd); + } + windows[p_window_id].window_focused = true; + _send_window_event(windows[p_window_id], WINDOW_EVENT_FOCUS_IN); } else { // WM_INACTIVE. Input::get_singleton()->release_pressed_events(); - _send_window_event(windows[p_window_id], WINDOW_EVENT_FOCUS_OUT); - windows[p_window_id].window_focused = false; + track_mouse_leave_event(windows[p_window_id].hWnd); + // Release capture unconditionally because it can be set due to dragging, in addition to captured mode. + ReleaseCapture(); alt_mem = false; + windows[p_window_id].window_focused = false; + _send_window_event(windows[p_window_id], WINDOW_EVENT_FOCUS_OUT); } if ((tablet_get_current_driver() == "wintab") && wintab_available && windows[p_window_id].wtctx) { diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index 1191f22968..cb209948b1 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -402,7 +402,6 @@ class DisplayServerWindows : public DisplayServer { // Timers. uint32_t move_timer_id = 0U; - uint32_t focus_timer_id = 0U; HANDLE wtctx; LOGCONTEXTW wtlc; |