From a138855d569fd4f9490d7936b6b5ac26af259bcd Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 12 Nov 2020 21:12:05 +0100 Subject: [PATCH] Hotfix for PushFocusScope() being utterly wrong (until we split the stacks), Added asserts on PopID to help catch bugs, Added GC trigger. --- imgui.cpp | 24 ++++++++++++++++-------- imgui_internal.h | 1 + imgui_widgets.cpp | 2 +- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ca7afd36..398e3900 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3845,7 +3845,7 @@ void ImGui::NewFrame() // Mark all windows as not visible and compact unused memory. IM_ASSERT(g.WindowsFocusOrder.Size == g.Windows.Size); - const float memory_compact_start_time = (g.IO.ConfigMemoryCompactTimer >= 0.0f) ? (float)g.Time - g.IO.ConfigMemoryCompactTimer : FLT_MAX; + const float memory_compact_start_time = (g.GcCompactAll || g.IO.ConfigMemoryCompactTimer < 0.0f) ? FLT_MAX : (float)g.Time - g.IO.ConfigMemoryCompactTimer; for (int i = 0; i != g.Windows.Size; i++) { ImGuiWindow* window = g.Windows[i]; @@ -3858,6 +3858,7 @@ void ImGui::NewFrame() if (!window->WasActive && !window->MemoryCompacted && window->LastTimeActive < memory_compact_start_time) GcCompactTransientWindowBuffers(window); } + g.GcCompactAll = false; // Closing the focused window restore focus to the first active root window in descending z-order if (g.NavWindow && !g.NavWindow->WasActive) @@ -6650,12 +6651,14 @@ void ImGui::ActivateItem(ImGuiID id) g.NavNextActivateId = id; } -// Note: this is storing in same stack as IDStack, so Push/Pop mismatch will be reported there. +// FIXME: this is storing in same stack as IDStack, so Push/Pop mismatch will be reported there. Maybe play nice and a separate in-context stack. void ImGui::PushFocusScope(ImGuiID id) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; + ImGuiID top_most_id = window->IDStack.back(); window->IDStack.push_back(window->DC.NavFocusScopeIdCurrent); + window->IDStack.push_back(top_most_id); window->DC.NavFocusScopeIdCurrent = id; } @@ -6665,6 +6668,8 @@ void ImGui::PopFocusScope() ImGuiWindow* window = g.CurrentWindow; window->DC.NavFocusScopeIdCurrent = window->IDStack.back(); window->IDStack.pop_back(); + IM_ASSERT(window->IDStack.Size > 1); // Too many PopID or PopFocusScope (or could be popping in a wrong/different window?) + window->IDStack.pop_back(); } void ImGui::SetKeyboardFocusHere(int offset) @@ -6763,6 +6768,7 @@ ImGuiID ImGui::GetIDWithSeed(const char* str, const char* str_end, ImGuiID seed) void ImGui::PopID() { ImGuiWindow* window = GImGui->CurrentWindow; + IM_ASSERT(window->IDStack.Size > 1); // Too many PopID or PopFocusScope (or could be popping in a wrong/different window?) window->IDStack.pop_back(); } @@ -10323,12 +10329,14 @@ void ImGui::ShowMetricsWindow(bool* p_open) ImGuiMetricsConfig* cfg = &g.DebugMetricsConfig; // Basic info - ImGui::Text("Dear ImGui %s", ImGui::GetVersion()); - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate); - ImGui::Text("%d vertices, %d indices (%d triangles)", io.MetricsRenderVertices, io.MetricsRenderIndices, io.MetricsRenderIndices / 3); - ImGui::Text("%d active windows (%d visible)", io.MetricsActiveWindows, io.MetricsRenderWindows); - ImGui::Text("%d active allocations", io.MetricsActiveAllocations); - ImGui::Separator(); + Text("Dear ImGui %s", ImGui::GetVersion()); + Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate); + Text("%d vertices, %d indices (%d triangles)", io.MetricsRenderVertices, io.MetricsRenderIndices, io.MetricsRenderIndices / 3); + Text("%d active windows (%d visible)", io.MetricsActiveWindows, io.MetricsRenderWindows); + Text("%d active allocations", io.MetricsActiveAllocations); + //SameLine(); if (SmallButton("GC")) { g.GcCompactAll = true; } + + Separator(); // Debugging enums enum { WRT_OuterRect, WRT_OuterRectClipped, WRT_InnerRect, WRT_InnerClipRect, WRT_WorkRect, WRT_Content, WRT_ContentRegionRect, WRT_Count }; // Windows Rect Type diff --git a/imgui_internal.h b/imgui_internal.h index a661c3a9..b46d665a 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1148,6 +1148,7 @@ struct ImGuiContext bool WithinFrameScope; // Set by NewFrame(), cleared by EndFrame() bool WithinFrameScopeWithImplicitWindow; // Set by NewFrame(), cleared by EndFrame() when the implicit debug window has been pushed bool WithinEndChild; // Set within EndChild() + bool GcCompactAll; // Request full GC bool TestEngineHookItems; // Will call test engine hooks: ImGuiTestEngineHook_ItemAdd(), ImGuiTestEngineHook_ItemInfo(), ImGuiTestEngineHook_Log() ImGuiID TestEngineHookIdInfo; // Will call test engine hooks: ImGuiTestEngineHook_IdInfo() from GetID() void* TestEngine; // Test engine user data diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 8fe841e1..4cb52b19 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -7489,7 +7489,7 @@ void ImGui::EndTabItem() IM_ASSERT(tab_bar->LastTabItemIdx >= 0); ImGuiTabItem* tab = &tab_bar->Tabs[tab_bar->LastTabItemIdx]; if (!(tab->Flags & ImGuiTabItemFlags_NoPushId)) - window->IDStack.pop_back(); + PopID(); } bool ImGui::TabItemButton(const char* label, ImGuiTabItemFlags flags)