diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 6888283a98e..972f20a50de 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -272,17 +272,31 @@ void Viewport::_sub_window_update_order() { return; } - if (!gui.sub_windows[gui.sub_windows.size() - 1].window->get_flag(Window::FLAG_ALWAYS_ON_TOP)) { - int index = gui.sub_windows.size() - 1; - - while (index > 0 && gui.sub_windows[index - 1].window->get_flag(Window::FLAG_ALWAYS_ON_TOP)) { - --index; + // Reorder 'always on top' windows. + int last_index = gui.sub_windows.size() - 1; + for (int index = last_index, insert_index = last_index; index >= 0; index--) { + SubWindow sw = gui.sub_windows[index]; + Window *parent_window = sw.window->get_parent_visible_window(); + bool parent_is_always_on_top = (parent_window != nullptr) && parent_window->get_flag(Window::FLAG_ALWAYS_ON_TOP); + if (sw.window->get_flag(Window::FLAG_ALWAYS_ON_TOP) || (parent_is_always_on_top && sw.window->is_exclusive())) { + if (index != insert_index) { + gui.sub_windows.remove_at(index); + gui.sub_windows.insert(insert_index, sw); + } + insert_index--; } + } - if (index != (gui.sub_windows.size() - 1)) { - SubWindow sw = gui.sub_windows[gui.sub_windows.size() - 1]; - gui.sub_windows.remove_at(gui.sub_windows.size() - 1); - gui.sub_windows.insert(index, sw); + // Reorder exclusive children. + for (int parent_index = 0; parent_index < gui.sub_windows.size(); parent_index++) { + Window *exclusive_child = gui.sub_windows[parent_index].window->get_exclusive_child(); + if (exclusive_child != nullptr && exclusive_child->is_visible()) { + int child_index = _sub_window_find(exclusive_child); + if (child_index < parent_index) { + SubWindow sw = gui.sub_windows[child_index]; + gui.sub_windows.remove_at(child_index); + gui.sub_windows.insert(parent_index, sw); + } } }