diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index b15f9ed57..9e1d752d3 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -41,6 +41,8 @@ Other changes: - Clipper: Rework inner logic to allow functioning with a zero-clear constructor. This is order to facilitate usage for language bindings (e.g cimgui or dear_binding) where user may not be callinga constructor manually. (#5856) +- Modals: In the case of nested modal, made sure that focused or appearing windows are + moved below the lowest blocking modal (rather than the highest one). (#4317) - IsItemHovered: Tweaked default value of io.HoverDelayNormal from 0.30 to 0.35 (used when using the ImGuiHoveredFlags_DelayNormal flag). (#1485) - Tooltips: Tweak default offset for non-drag and drop tooltips so underlying items diff --git a/imgui.cpp b/imgui.cpp index 1c222d316..f97ca3b1a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6093,12 +6093,13 @@ void ImGui::UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags // When a modal popup is open, newly created windows that want focus (i.e. are not popups and do not specify ImGuiWindowFlags_NoFocusOnAppearing) // should be positioned behind that modal window, unless the window was created inside the modal begin-stack. // In case of multiple stacked modals newly created window honors begin stack order and does not go below its own modal parent. -// - Window // FindBlockingModal() returns Modal1 -// - Window // .. returns Modal1 +// - WindowA // FindBlockingModal() returns Modal1 +// - WindowB // .. returns Modal1 // - Modal1 // .. returns Modal2 -// - Window // .. returns Modal2 -// - Window // .. returns Modal2 +// - WindowC // .. returns Modal2 +// - WindowD // .. returns Modal2 // - Modal2 // .. returns Modal2 +// - WindowE // .. returns NULL // Notes: // - FindBlockingModal(NULL) == NULL is generally equivalent to GetTopMostPopupModal() == NULL. // Only difference is here we check for ->Active/WasActive but it may be unecessary. @@ -6109,7 +6110,7 @@ ImGuiWindow* ImGui::FindBlockingModal(ImGuiWindow* window) return NULL; // Find a modal that has common parent with specified window. Specified window should be positioned behind that modal. - for (int i = g.OpenPopupStack.Size - 1; i >= 0; i--) + for (int i = 0; i < g.OpenPopupStack.Size; i++) { ImGuiWindow* popup_window = g.OpenPopupStack.Data[i].Window; if (popup_window == NULL || !(popup_window->Flags & ImGuiWindowFlags_Modal)) @@ -6118,11 +6119,9 @@ ImGuiWindow* ImGui::FindBlockingModal(ImGuiWindow* window) continue; if (window == NULL) // FindBlockingModal(NULL) test for if FocusWindow(NULL) is naturally possible via a mouse click. return popup_window; - if (IsWindowWithinBeginStackOf(window, popup_window)) // Window is rendered over last modal, no render order change needed. - break; - for (ImGuiWindow* parent = popup_window->ParentWindowInBeginStack->RootWindow; parent != NULL; parent = parent->ParentWindowInBeginStack->RootWindow) - if (IsWindowWithinBeginStackOf(window, parent)) - return popup_window; // Place window above its begin stack parent. + if (IsWindowWithinBeginStackOf(window, popup_window)) // Window may be over modal + continue; + return popup_window; // Place window right below first block modal } return NULL; }