diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 36c075eed..e2b33e182 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -54,6 +54,11 @@ Docking+Viewports Branch: - Nav: fixed a crash that could occur when opening a popup following the processing of a global shortcut while no windows were focused (the fix done in 1.92.3 was incomplete for docking branch). +- Viewports: fixed an issue inferring Z-order when attempting to merge a viewport + back in the the main/hosting viewport. (#8948) + Note that for GLFW/SDL2/OSX backends, which do not support honoring ParentViewportID. + setting io.ConfigViewportsNoDefaultParent=true will align imgui's expectation with + what the backend does. - Viewports: DestroyContext() does not call DestroyPlatformWindows() anymore at it assumed to be unnecessary as backensd should have done it and we check that backends have been shutdown since 1.90.4. Changed into asserts. (#7175, #8945) diff --git a/imgui.cpp b/imgui.cpp index 4bc16f9e1..2ef0d0706 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -16326,6 +16326,15 @@ static bool ImGui::GetWindowAlwaysWantOwnViewport(ImGuiWindow* window) return false; } + +// Heuristic, see #8948: depends on how backends handle OS-level parenting. +static bool IsViewportAbove(ImGuiViewportP* potential_above, ImGuiViewportP* potential_below) +{ + if (potential_above->LastFocusedStampCount > potential_below->LastFocusedStampCount || potential_above->ParentViewportId == potential_below->ID) // FIXME: Should follow the ParentViewportId list. + return true; + return false; +} + static bool ImGui::UpdateTryMergeWindowIntoHostViewport(ImGuiWindow* window, ImGuiViewportP* viewport) { ImGuiContext& g = *GImGui; @@ -16340,14 +16349,12 @@ static bool ImGui::UpdateTryMergeWindowIntoHostViewport(ImGuiWindow* window, ImG if (GetWindowAlwaysWantOwnViewport(window)) return false; - // FIXME: Can't use g.WindowsFocusOrder[] for root windows only as we care about Z order. If we maintained a DisplayOrder along with FocusOrder we could.. - for (ImGuiWindow* window_behind : g.Windows) + for (ImGuiViewportP* viewport_2 : g.Viewports) { - if (window_behind == window) - break; - if (window_behind->WasActive && window_behind->ViewportOwned && !(window_behind->Flags & ImGuiWindowFlags_ChildWindow)) - if (window_behind->Viewport->GetMainRect().Overlaps(window->Rect())) - return false; + if (viewport_2 == viewport || viewport_2 == window->Viewport) + continue; + if (IsViewportAbove(viewport_2, viewport) && viewport_2->GetMainRect().Overlaps(window->Rect())) + return false; } // Move to the existing viewport, Move child/hosted windows as well (FIXME-OPT: iterate child)