Skip to content

Commit

Permalink
Modals: In the case of nested modal, made sure that focused or appear…
Browse files Browse the repository at this point in the history
…ing windows are moved below the lowest blocking modal (rather than the highest one). (#4317)

Fix FindBlockingkModal() which didn't do what the comments say for the first 2 lines.
This is also fixing a crash in FindBlockingModal() which can only happen with dock node, see "window_popup_nested_interruptions_2" and viewport_platform_focus_4" tests.
The dock-node related crash comes from the fact that automatic dock node and implicit debug window don't share a common ancestor, so ParentWindowInBeginStack ends up NULL before the loop had a chance to find a match.
  • Loading branch information
ocornut committed Jun 14, 2023
1 parent eec344c commit 89d3dab
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 10 deletions.
2 changes: 2 additions & 0 deletions docs/CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
19 changes: 9 additions & 10 deletions imgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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))
Expand All @@ -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;
}
Expand Down

0 comments on commit 89d3dab

Please sign in to comment.