From 91704b773e7e636dd83afdd2871a4fa17fa78863 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 31 May 2021 17:06:46 +0200 Subject: [PATCH] Docking: Fix IsWindowAppearing() and ImGuiCond_Appearing on docked windows. (#4177, #3982, #1497, #1061) --- docs/CHANGELOG.txt | 5 ++++- imgui.cpp | 20 +++++++++++++++----- imgui_internal.h | 1 + 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 3562714f..23a83868 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -108,7 +108,10 @@ Other Changes: Normally the right way to disable compiling the demo is to set IMGUI_DISABLE_DEMO_WINDOWS, but we want to avoid implying that the file is required. - Backends: OpenGL3: Handle GL_CLIP_ORIGIN on <4.5 contexts if "GL_ARB_clip_control" extension is detected. (#4170, #3998) ->>>>>>> master + +Docking+Viewports Branch: + +- Docking: Fix IsWindowAppearing() and ImGuiCond_Appearing on docked windows. (#4177, #3982, #1497, #1061) ----------------------------------------------------------------------- diff --git a/imgui.cpp b/imgui.cpp index f79634a3..8593f7f4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6100,8 +6100,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) const bool first_begin_of_the_frame = (window->LastFrameActive != current_frame); window->IsFallbackWindow = (g.CurrentWindowStack.Size == 0 && g.WithinFrameScopeWithImplicitWindow); - // Update the Appearing flag - bool window_just_activated_by_user = (window->LastFrameActive < current_frame - 1); // Not using !WasActive because the implicit "Debug" window would always toggle off->on + // Update the Appearing flag (note: the BeginDocked() path may also set this to true later) + bool window_just_activated_by_user = (window->LastFrameActive < current_frame - 1); // Not using !WasActive because the implicit "Debug" window would always toggle off->on if (flags & ImGuiWindowFlags_Popup) { ImGuiPopupData& popup_ref = g.OpenPopupStack[g.BeginPopupStack.Size]; @@ -6136,6 +6136,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { bool has_dock_node = (window->DockId != 0 || window->DockNode != NULL); bool new_auto_dock_node = !has_dock_node && GetWindowAlwaysWantOwnTabBar(window); + bool dock_node_was_visible = window->DockNodeIsVisible; + bool dock_tab_was_visible = window->DockTabIsVisible; if (has_dock_node || new_auto_dock_node) { BeginDocked(window, p_open); @@ -6146,6 +6148,13 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Docking currently override constraints g.NextWindowData.Flags &= ~ImGuiNextWindowDataFlags_HasSizeConstraint; } + + // Update the Appearing flag (again) + if (window->DockTabIsVisible && !dock_tab_was_visible && dock_node_was_visible && !window->Appearing) + { + window->Appearing = true; + SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, true); + } } // Parent window is latched only on the first call to Begin() of the frame, so further append-calls can be done from a different window stack @@ -12957,7 +12966,7 @@ void ImGui::DockContextProcessUndockWindow(ImGuiContext* ctx, ImGuiWindow* windo window->DockId = 0; window->Collapsed = false; window->DockIsActive = false; - window->DockTabIsVisible = false; + window->DockNodeIsVisible = window->DockTabIsVisible = false; window->Size = window->SizeFull = FixLargeWindowsWhenUndocking(window->SizeFull, window->Viewport); MarkIniSettingsDirty(); @@ -15503,7 +15512,7 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open) else { window->DockIsActive = true; - window->DockTabIsVisible = false; + window->DockNodeIsVisible = window->DockTabIsVisible = false; } return; } @@ -15518,7 +15527,7 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open) if (node->HostWindow == NULL) { window->DockIsActive = (node->State == ImGuiDockNodeState_HostWindowHiddenBecauseWindowsAreResizing); - window->DockTabIsVisible = false; + window->DockNodeIsVisible = window->DockTabIsVisible = false; if (node->Windows.Size > 1) DockNodeHideWindowDuringHostWindowCreation(window); return; @@ -15542,6 +15551,7 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open) SetNextWindowSize(node->Size); g.NextWindowData.PosUndock = false; // Cancel implicit undocking of SetNextWindowPos() window->DockIsActive = true; + window->DockNodeIsVisible = true; window->DockTabIsVisible = false; if (node->SharedFlags & ImGuiDockNodeFlags_KeepAliveOnly) return; diff --git a/imgui_internal.h b/imgui_internal.h index 2673fc81..ce0ea241 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -2101,6 +2101,7 @@ struct IMGUI_API ImGuiWindow // Docking bool DockIsActive :1; // When docking artifacts are actually visible. When this is set, DockNode is guaranteed to be != NULL. ~~ (DockNode != NULL) && (DockNode->Windows.Size > 1). + bool DockNodeIsVisible :1; bool DockTabIsVisible :1; // Is our window visible this frame? ~~ is the corresponding tab selected? bool DockTabWantClose :1; short DockOrder; // Order of the last time the window was visible within its DockNode. This is used to reorder windows that are reappearing on the same frame. Same value between windows that were active and windows that were none are possible.