Skip to content

Docking: Fix dock split of current window before End() assertion trigger#9475

Open
SuperRonan wants to merge 1 commit into
ocornut:dockingfrom
SuperRonan:ronan/bug_split_docking
Open

Docking: Fix dock split of current window before End() assertion trigger#9475
SuperRonan wants to merge 1 commit into
ocornut:dockingfrom
SuperRonan:ronan/bug_split_docking

Conversation

@SuperRonan

Copy link
Copy Markdown
Contributor

Problem:

An assertion is raised when calling ImGui::DockBuilderSplitNode() on a DockId which owns a window that is currently being declared (between Begin() and End()).

More precisely:

We have an ImGuiID dock_id, and an ImGuiDockNode* n correponding to it; we also have an ImGuiWindow* w that is currently being declared and such as n->Windows[0] = w (being the first window in the list is important).
We call ImGui::DockBuilderSplitNode(dock_id, ...), which calls ImGui::DockNodeTreeSplit(ctx, n, ...), which creates two child nodes, and moves windows from the parent n to one of the children.
DockNodeMoveWindows(dst, src) adds src's windows to dst one at the time using DockNodeAddWindow(). The latter sets window->DockIsActive = (node->Windows.Size > 1);, which is going to be false for the first window of the list to be moved (w).
Latter, during End() of w, an assertion will fail:

if ((window->Flags & ImGuiWindowFlags_ChildWindow) && !(window->Flags & ImGuiWindowFlags_DockNodeHost) && !window->DockIsActive)
    IM_ASSERT_USER_ERROR(g.WithinEndChildID == window->ID, "Must call EndChild() and not End()!");

This assertion should not be checked because window->DockIsActive should have been true (it would have been the case if w was not the first window in the list n->Window, and it is not the case for other windows docked to n).

I have made a basic example to illustrate this issue. It is available in a separate commit e81ac55.

Note that this issue does not exists if docking manipulation is done outside of window declaration (such as docking manipulation done with the mouse).

Solution:

I am proposing to fix the above w->DockIsActive == false that appears to be erroneous.
I don't have a complete overview of the docking system, so the solution I am proposing in this PR might not be the best (Still I checked that all tests of the test engine passed).

I prefer not touching to window->DockIsActive = (node->Windows.Size > 1); in DockNodeAddWindow().
I think it makes most sense to fix it in DockNodeMoveWindows() (this current PR). Although this issue was found with a splitting, other docking operations that move windows from one node to another may trigger the same assertion error, and the source of the problems is in DockNodeMoveWindows().

Alternatively, the initial error maybe was to use the DockBuilder on the dock of a window during its declaration. We could explicitely forbid these kind of manipulations, but I am not very fond of such restrictions.

- Fix erroneous reset `window->DockIsActive` to `false` of first docked window in `ImGui::DockNodeMoveWindows()`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant