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.
This commit is contained in:
Alvin Wong 2024-07-25 05:19:08 +08:00
parent 0e9caa2d9c
commit cffa2072ca
1 changed files with 18 additions and 1 deletions

View File

@ -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) {
if (wd.exclusive) {
WindowData &wd_parent = windows[wd.transient_parent];
if (wd.exclusive) {
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) {