From e87dd0e65dd2786c50a7cfa411d0448140ffc8f1 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 12 Apr 2021 19:21:49 +0200 Subject: [PATCH] Docking: Fixed multiple simultaneously reappearing window from appearing undocked in their initial frame. --- docs/CHANGELOG.txt | 1 + imgui.cpp | 22 ++++++++++++++-------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 4ec781ad..72ff5f4e 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -138,6 +138,7 @@ Docking Branch: - Docking: Dockspace() never draws a background. (#3924) - Docking: undocking nodes/windows covering most of the monitor max their size down to 90% to ease further manipulations. - Docking: Fixed restoring of tab order within a dockspace or a split node. +- Docking: Fixed multiple simultaneously reappearing window from appearing undocked in their initial frame. - Viewports: Hotfix for crash in monitor array access, caused by 4b9bc4902. (#3967) - Backends, Viewports: GLFW: Add a workaround for stuck keys after closing a GLFW window (#3837). - Backends, Viewports: Vulkan: Rebuild swapchain on VK_SUBOPTIMAL_KHR. (#3881) diff --git a/imgui.cpp b/imgui.cpp index d9376ef1..4086b326 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -13006,6 +13006,12 @@ int ImGui::DockNodeGetTabOrder(ImGuiWindow* window) return tab ? tab_bar->GetTabOrder(tab) : -1; } +static void DockNodeHideWindowDuringHostWindowCreation(ImGuiWindow* window) +{ + window->Hidden = true; + window->HiddenFramesCanSkipItems = window->Active ? 1 : 2; +} + static void ImGui::DockNodeAddWindow(ImGuiDockNode* node, ImGuiWindow* window, bool add_to_tab_bar) { ImGuiContext& g = *GImGui; (void)g; @@ -13018,6 +13024,12 @@ static void ImGui::DockNodeAddWindow(ImGuiDockNode* node, ImGuiWindow* window, b IM_ASSERT(window->DockNode == NULL || window->DockNodeAsHost == NULL); IMGUI_DEBUG_LOG_DOCKING("DockNodeAddWindow node 0x%08X window '%s'\n", node->ID, window->Name); + // If more than 2 windows appeared on the same frame leading to the creation of a new hosting window, + // we'll hide windows until the host window is ready. Hide the 1st window after its been output (so it is not visible for one frame). + // We will call DockNodeHideWindowDuringHostWindowCreation() on ourselves in Begin() + if (node->HostWindow == NULL && node->Windows.Size == 1 && node->Windows[0]->WasActive == false) + DockNodeHideWindowDuringHostWindowCreation(node->Windows[0]); + node->Windows.push_back(window); node->WantHiddenTabBarUpdate = true; window->DockNode = node; @@ -13025,14 +13037,6 @@ static void ImGui::DockNodeAddWindow(ImGuiDockNode* node, ImGuiWindow* window, b window->DockIsActive = (node->Windows.Size > 1); window->DockTabWantClose = false; - // If more than 2 windows appeared on the same frame, we'll create a new hosting DockNode from the point of the second window submission. - // Then we need to hide the first window (after its been output) otherwise it would be visible as a standalone window for one frame. - if (node->HostWindow == NULL && node->Windows.Size == 2 && node->Windows[0]->WasActive == false) - { - node->Windows[0]->Hidden = true; - node->Windows[0]->HiddenFramesCanSkipItems = 1; - } - // When reactivating a node with one or two loose window, the window pos/size/viewport are authoritative over the node storage. // In particular it is important we init the viewport from the first window so we don't create two viewports and drop one. if (node->HostWindow == NULL && node->IsFloatingNode()) @@ -15427,6 +15431,8 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open) { window->DockIsActive = (node->State == ImGuiDockNodeState_HostWindowHiddenBecauseWindowsAreResizing); window->DockTabIsVisible = false; + if (node->Windows.Size > 1) + DockNodeHideWindowDuringHostWindowCreation(window); return; }