diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index b1647740d..67d0ed5e2 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -144,7 +144,10 @@ Docking+Viewports Branch: - Docking: Clicking on the right-most close button of a docking node closes all windows. (#4186) - Docking: Fix IsWindowAppearing() and ImGuiCond_Appearing on docked windows. (#4177, #3982, #1497, #1061) -- Docking: Fix crash issues using DockBuilderRemoveNode() in some situations. (#3111, #3179, #3203, #4295) [@hsimyu] +- Docking: Fix crash using DockBuilderRemoveNode() in some situations. (#3111, #3179, #3203, #4295) [@hsimyu] +- Docking: Fix crash when a dock node gets re-qualified as dockspace>floating>dockspace, which tends to happen + when incorrectly calling DockBuilderAddNode() without ImGuiDockNodeFlags_Dockspace and using it as a Dockspace + on the next frame after the floating window hosting the node has been automatically created. (#3203, #4295) - Docking: Reworked node flags saving/inheritance so that flags enforced by docked windows via the DockNodeFlagsOverrideSet mechanism are are not left in empty dockspace nodes once the windows gets undocked. (#4292, #3834, #3633, #3521, #3492, #3335, #2999, #2648) diff --git a/imgui.cpp b/imgui.cpp index 4a1f51929..09774d488 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -13520,6 +13520,20 @@ static void ImGui::DockNodeUpdateForRootNode(ImGuiDockNode* node) } } +static void DockNodeSetupHostWindow(ImGuiDockNode* node, ImGuiWindow* host_window) +{ + // Remove ourselves from any previous different host window + // This can happen if a user mistakenly does (see #4295 for details): + // - N+0: DockBuilderAddNode(id, 0) // missing ImGuiDockNodeFlags_DockSpace + // - N+1: NewFrame() // will create floating host window for that node + // - N+1: DockSpace(id) // requalify node as dockspace, moving host window + if (node->HostWindow && node->HostWindow != host_window && node->HostWindow->DockNodeAsHost == node) + node->HostWindow->DockNodeAsHost = NULL; + + host_window->DockNodeAsHost = node; + node->HostWindow = host_window; +} + static void ImGui::DockNodeUpdate(ImGuiDockNode* node) { ImGuiContext& g = *GImGui; @@ -13668,8 +13682,8 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node) PopStyleVar(); beginned_into_host_window = true; - node->HostWindow = host_window = g.CurrentWindow; - host_window->DockNodeAsHost = node; + host_window = g.CurrentWindow; + DockNodeSetupHostWindow(node, host_window); host_window->DC.CursorPos = host_window->Pos; node->Pos = host_window->Pos; node->Size = host_window->Size; @@ -14986,9 +15000,8 @@ ImGuiID ImGui::DockSpace(ImGuiID id, const ImVec2& size_arg, ImGuiDockNodeFlags PopStyleVar(); ImGuiWindow* host_window = g.CurrentWindow; - host_window->DockNodeAsHost = node; + DockNodeSetupHostWindow(node, host_window); host_window->ChildId = window->GetID(title); - node->HostWindow = host_window; node->OnlyNodeWithWindows = NULL; IM_ASSERT(node->IsRootNode());