Hotfix for PushFocusScope() being utterly wrong (until we split the stacks), Added asserts on PopID to help catch bugs, Added GC trigger.

This commit is contained in:
ocornut 2020-11-12 21:12:05 +01:00
parent 78f1d2d319
commit a138855d56
3 changed files with 18 additions and 9 deletions

View File

@ -3845,7 +3845,7 @@ void ImGui::NewFrame()
// Mark all windows as not visible and compact unused memory. // Mark all windows as not visible and compact unused memory.
IM_ASSERT(g.WindowsFocusOrder.Size == g.Windows.Size); 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++) for (int i = 0; i != g.Windows.Size; i++)
{ {
ImGuiWindow* window = g.Windows[i]; ImGuiWindow* window = g.Windows[i];
@ -3858,6 +3858,7 @@ void ImGui::NewFrame()
if (!window->WasActive && !window->MemoryCompacted && window->LastTimeActive < memory_compact_start_time) if (!window->WasActive && !window->MemoryCompacted && window->LastTimeActive < memory_compact_start_time)
GcCompactTransientWindowBuffers(window); GcCompactTransientWindowBuffers(window);
} }
g.GcCompactAll = false;
// Closing the focused window restore focus to the first active root window in descending z-order // Closing the focused window restore focus to the first active root window in descending z-order
if (g.NavWindow && !g.NavWindow->WasActive) if (g.NavWindow && !g.NavWindow->WasActive)
@ -6650,12 +6651,14 @@ void ImGui::ActivateItem(ImGuiID id)
g.NavNextActivateId = 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) void ImGui::PushFocusScope(ImGuiID id)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow; ImGuiWindow* window = g.CurrentWindow;
ImGuiID top_most_id = window->IDStack.back();
window->IDStack.push_back(window->DC.NavFocusScopeIdCurrent); window->IDStack.push_back(window->DC.NavFocusScopeIdCurrent);
window->IDStack.push_back(top_most_id);
window->DC.NavFocusScopeIdCurrent = id; window->DC.NavFocusScopeIdCurrent = id;
} }
@ -6665,6 +6668,8 @@ void ImGui::PopFocusScope()
ImGuiWindow* window = g.CurrentWindow; ImGuiWindow* window = g.CurrentWindow;
window->DC.NavFocusScopeIdCurrent = window->IDStack.back(); window->DC.NavFocusScopeIdCurrent = window->IDStack.back();
window->IDStack.pop_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) void ImGui::SetKeyboardFocusHere(int offset)
@ -6763,6 +6768,7 @@ ImGuiID ImGui::GetIDWithSeed(const char* str, const char* str_end, ImGuiID seed)
void ImGui::PopID() void ImGui::PopID()
{ {
ImGuiWindow* window = GImGui->CurrentWindow; 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(); window->IDStack.pop_back();
} }
@ -10323,12 +10329,14 @@ void ImGui::ShowMetricsWindow(bool* p_open)
ImGuiMetricsConfig* cfg = &g.DebugMetricsConfig; ImGuiMetricsConfig* cfg = &g.DebugMetricsConfig;
// Basic info // Basic info
ImGui::Text("Dear ImGui %s", ImGui::GetVersion()); Text("Dear ImGui %s", ImGui::GetVersion());
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate); 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); 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); Text("%d active windows (%d visible)", io.MetricsActiveWindows, io.MetricsRenderWindows);
ImGui::Text("%d active allocations", io.MetricsActiveAllocations); Text("%d active allocations", io.MetricsActiveAllocations);
ImGui::Separator(); //SameLine(); if (SmallButton("GC")) { g.GcCompactAll = true; }
Separator();
// Debugging enums // Debugging enums
enum { WRT_OuterRect, WRT_OuterRectClipped, WRT_InnerRect, WRT_InnerClipRect, WRT_WorkRect, WRT_Content, WRT_ContentRegionRect, WRT_Count }; // Windows Rect Type enum { WRT_OuterRect, WRT_OuterRectClipped, WRT_InnerRect, WRT_InnerClipRect, WRT_WorkRect, WRT_Content, WRT_ContentRegionRect, WRT_Count }; // Windows Rect Type

View File

@ -1148,6 +1148,7 @@ struct ImGuiContext
bool WithinFrameScope; // Set by NewFrame(), cleared by EndFrame() 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 WithinFrameScopeWithImplicitWindow; // Set by NewFrame(), cleared by EndFrame() when the implicit debug window has been pushed
bool WithinEndChild; // Set within EndChild() bool WithinEndChild; // Set within EndChild()
bool GcCompactAll; // Request full GC
bool TestEngineHookItems; // Will call test engine hooks: ImGuiTestEngineHook_ItemAdd(), ImGuiTestEngineHook_ItemInfo(), ImGuiTestEngineHook_Log() bool TestEngineHookItems; // Will call test engine hooks: ImGuiTestEngineHook_ItemAdd(), ImGuiTestEngineHook_ItemInfo(), ImGuiTestEngineHook_Log()
ImGuiID TestEngineHookIdInfo; // Will call test engine hooks: ImGuiTestEngineHook_IdInfo() from GetID() ImGuiID TestEngineHookIdInfo; // Will call test engine hooks: ImGuiTestEngineHook_IdInfo() from GetID()
void* TestEngine; // Test engine user data void* TestEngine; // Test engine user data

View File

@ -7489,7 +7489,7 @@ void ImGui::EndTabItem()
IM_ASSERT(tab_bar->LastTabItemIdx >= 0); IM_ASSERT(tab_bar->LastTabItemIdx >= 0);
ImGuiTabItem* tab = &tab_bar->Tabs[tab_bar->LastTabItemIdx]; ImGuiTabItem* tab = &tab_bar->Tabs[tab_bar->LastTabItemIdx];
if (!(tab->Flags & ImGuiTabItemFlags_NoPushId)) if (!(tab->Flags & ImGuiTabItemFlags_NoPushId))
window->IDStack.pop_back(); PopID();
} }
bool ImGui::TabItemButton(const char* label, ImGuiTabItemFlags flags) bool ImGui::TabItemButton(const char* label, ImGuiTabItemFlags flags)