From cffa2072caa15a09bcc205c8f20631dabf5c6a5c Mon Sep 17 00:00:00 2001 From: Alvin Wong Date: Thu, 25 Jul 2024 05:19:08 +0800 Subject: [PATCH] Windows: Make exclusive transient windows act like native modal windows Use `EnableWindow` to disable the transient parent so that clicking on it will set focus to the exclusive window, flash its title bar and produce a beep, which is the native behaviour of modal dialogs on Windows. --- platform/windows/display_server_windows.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 020ef0c31b3..264bda5debc 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -1391,6 +1391,11 @@ void DisplayServerWindows::show_window(WindowID p_id) { if (wd.always_on_top) { SetWindowPos(wd.hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | ((wd.no_focus || wd.is_popup) ? SWP_NOACTIVATE : 0)); } + + if (wd.exclusive && wd.transient_parent != INVALID_WINDOW_ID) { + WindowData &wd_parent = windows[wd.transient_parent]; + EnableWindow(wd_parent.hWnd, false); + } } void DisplayServerWindows::delete_sub_window(WindowID p_window) { @@ -1412,6 +1417,11 @@ void DisplayServerWindows::delete_sub_window(WindowID p_window) { prop_store->Release(); } + if (wd.exclusive && wd.transient_parent != INVALID_WINDOW_ID) { + WindowData &wd_parent = windows[wd.transient_parent]; + EnableWindow(wd_parent.hWnd, true); + } + while (wd.transient_children.size()) { window_set_transient(*wd.transient_children.begin(), INVALID_WINDOW_ID); } @@ -1748,10 +1758,12 @@ void DisplayServerWindows::window_set_exclusive(WindowID p_window, bool p_exclus if (wd.exclusive != p_exclusive) { wd.exclusive = p_exclusive; if (wd.transient_parent != INVALID_WINDOW_ID) { + WindowData &wd_parent = windows[wd.transient_parent]; if (wd.exclusive) { - WindowData &wd_parent = windows[wd.transient_parent]; SetWindowLongPtr(wd.hWnd, GWLP_HWNDPARENT, (LONG_PTR)wd_parent.hWnd); + EnableWindow(wd_parent.hWnd, false); } else { + EnableWindow(wd_parent.hWnd, true); SetWindowLongPtr(wd.hWnd, GWLP_HWNDPARENT, (LONG_PTR) nullptr); } } @@ -1781,6 +1793,7 @@ void DisplayServerWindows::window_set_transient(WindowID p_window, WindowID p_pa wd_parent.transient_children.erase(p_window); if (wd_window.exclusive) { + EnableWindow(wd_parent.hWnd, true); SetWindowLongPtr(wd_window.hWnd, GWLP_HWNDPARENT, (LONG_PTR) nullptr); } } else { @@ -1793,6 +1806,7 @@ void DisplayServerWindows::window_set_transient(WindowID p_window, WindowID p_pa if (wd_window.exclusive) { SetWindowLongPtr(wd_window.hWnd, GWLP_HWNDPARENT, (LONG_PTR)wd_parent.hWnd); + EnableWindow(wd_parent.hWnd, false); } } } @@ -5424,6 +5438,9 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, if (wd_transient_parent) { wd.transient_parent = p_transient_parent; wd_transient_parent->transient_children.insert(id); + if (p_exclusive) { + EnableWindow(wd_transient_parent->hWnd, false); + } } if (is_dark_mode_supported() && dark_title_available) {