Fix popup shows behind always_on_top parent.

This commit is contained in:
Zae
2024-12-10 01:35:25 +08:00
parent aa8d9b83f6
commit 2211b1bf91
5 changed files with 44 additions and 14 deletions

View File

@@ -1542,6 +1542,21 @@ DisplayServer::WindowID DisplayServerWindows::create_sub_window(WindowMode p_mod
return window_id;
}
bool DisplayServerWindows::_is_always_on_top_recursive(WindowID p_window) const {
ERR_FAIL_COND_V(!windows.has(p_window), false);
const WindowData &wd = windows[p_window];
if (wd.always_on_top) {
return true;
}
if (wd.transient_parent != INVALID_WINDOW_ID) {
return _is_always_on_top_recursive(wd.transient_parent);
}
return false;
}
void DisplayServerWindows::show_window(WindowID p_id) {
ERR_FAIL_COND(!windows.has(p_id));
@@ -1569,7 +1584,7 @@ void DisplayServerWindows::show_window(WindowID p_id) {
SetForegroundWindow(wd.hWnd); // Slightly higher priority.
SetFocus(wd.hWnd); // Set keyboard focus.
}
if (wd.always_on_top) {
if (_is_always_on_top_recursive(p_id)) {
SetWindowPos(wd.hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | ((wd.no_focus || wd.is_popup) ? SWP_NOACTIVATE : 0));
}
}
@@ -2192,7 +2207,7 @@ void DisplayServerWindows::_update_window_style(WindowID p_window, bool p_repain
set_icon(icon);
}
SetWindowPos(wd.hWnd, wd.always_on_top ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | ((wd.no_focus || wd.is_popup) ? SWP_NOACTIVATE : 0));
SetWindowPos(wd.hWnd, _is_always_on_top_recursive(p_window) ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | ((wd.no_focus || wd.is_popup) ? SWP_NOACTIVATE : 0));
if (p_repaint) {
RECT rect;

View File

@@ -628,6 +628,8 @@ class DisplayServerWindows : public DisplayServer {
void _drag_event(WindowID p_window, float p_x, float p_y, int idx);
void _touch_event(WindowID p_window, bool p_pressed, float p_x, float p_y, int idx);
bool _is_always_on_top_recursive(WindowID p_window) const;
void _update_window_style(WindowID p_window, bool p_repaint = true);
void _update_window_mouse_passthrough(WindowID p_window);