From c653a1123a353d033abb6f566ba92a28da260d1b Mon Sep 17 00:00:00 2001 From: GamingMinds-DanielC Date: Mon, 11 Dec 2023 13:33:45 +0100 Subject: [PATCH 1/2] Don't bring appearing host window to front unless any of the contained windows require initial focus --- imgui.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 624abba32..4605966a9 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -16712,13 +16712,19 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node) node->Size = host_window->Size; // We set ImGuiWindowFlags_NoFocusOnAppearing because we don't want the host window to take full focus (e.g. steal NavWindow) - // But we still it bring it to the front of display. There's no way to choose this precise behavior via window flags. + // But we still it bring it to the front of display unless all appearing windows have ImGuiWindowFlags_NoFocusOnAppearing set. If none of the + // windows wants initial focus, the host will not be brought to the front. There's no way to choose this precise behavior via window flags. // One simple case to ponder if: window A has a toggle to create windows B/C/D. Dock B/C/D together, clear the toggle and enable it again. // When reappearing B/C/D will request focus and be moved to the top of the display pile, but they are not linked to the dock host window // during the frame they appear. The dock host window would keep its old display order, and the sorting in EndFrame would move B/C/D back // after the dock host window, losing their top-most status. if (node->HostWindow->Appearing) - BringWindowToDisplayFront(node->HostWindow); + for (ImGuiWindow* window : node->Windows) + if (window->Appearing && !(window->Flags & ImGuiWindowFlags_NoFocusOnAppearing)) + { + BringWindowToDisplayFront(node->HostWindow); + break; + } node->AuthorityForPos = node->AuthorityForSize = node->AuthorityForViewport = ImGuiDataAuthority_Auto; } From c070207d7c2190db34781d35e6005f76afb651d5 Mon Sep 17 00:00:00 2001 From: GamingMinds-DanielC Date: Tue, 12 Dec 2023 12:51:40 +0100 Subject: [PATCH 2/2] Fixed some corner cases and programmatic docking --- imgui.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 4605966a9..8278a84b7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -16712,20 +16712,29 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node) node->Size = host_window->Size; // We set ImGuiWindowFlags_NoFocusOnAppearing because we don't want the host window to take full focus (e.g. steal NavWindow) - // But we still it bring it to the front of display unless all appearing windows have ImGuiWindowFlags_NoFocusOnAppearing set. If none of the + // But we still bring it to the front of display unless all appearing windows have ImGuiWindowFlags_NoFocusOnAppearing set. If none of the // windows wants initial focus, the host will not be brought to the front. There's no way to choose this precise behavior via window flags. - // One simple case to ponder if: window A has a toggle to create windows B/C/D. Dock B/C/D together, clear the toggle and enable it again. + // One simple case to ponder is: window A has a toggle to create windows B/C/D. Dock B/C/D together, clear the toggle and enable it again. // When reappearing B/C/D will request focus and be moved to the top of the display pile, but they are not linked to the dock host window // during the frame they appear. The dock host window would keep its old display order, and the sorting in EndFrame would move B/C/D back // after the dock host window, losing their top-most status. if (node->HostWindow->Appearing) + { + // If any of the appearing windows wants focus or any of the other windows currently has the focus, bring the host window to front. + // In addition to appearing windows, this handles all cases where one or multiple windows are manually docked. for (ImGuiWindow* window : node->Windows) - if (window->Appearing && !(window->Flags & ImGuiWindowFlags_NoFocusOnAppearing)) + if (window->Appearing ? !(window->Flags & ImGuiWindowFlags_NoFocusOnAppearing) : (window == g.NavWindow)) { BringWindowToDisplayFront(node->HostWindow); break; } + // If the host window was not brought to the front, bring it behind the reference window to preserve its display order. + // This neatly handles all remaining cases of programmatically docking windows into the host window. + if (node->HostWindow != g.Windows.back() && ref_window) + BringWindowToDisplayBehind(node->HostWindow, ref_window); + } + node->AuthorityForPos = node->AuthorityForSize = node->AuthorityForViewport = ImGuiDataAuthority_Auto; } else if (node->ParentNode)