diff --git a/3rdparty/dear-imgui/imgui.cpp b/3rdparty/dear-imgui/imgui.cpp index 16b880efb..94be3a81c 100644 --- a/3rdparty/dear-imgui/imgui.cpp +++ b/3rdparty/dear-imgui/imgui.cpp @@ -3557,7 +3557,10 @@ void ImGui::EndFrame() IM_ASSERT(g.Initialized); if (g.FrameCountEnded == g.FrameCount) // Don't process EndFrame() multiple times. return; - IM_ASSERT(g.FrameScopeActive && "Forgot to call ImGui::NewFrame()"); + IM_ASSERT(g.FrameScopeActive && "Forgot to call ImGui::NewFrame()?"); + + g.FrameScopeActive = false; + g.FrameCountEnded = g.FrameCount; // Notify OS when our Input Method Editor cursor has moved (e.g. CJK inputs using Microsoft IME) if (g.IO.ImeSetInputScreenPosFn && ImLengthSqr(g.PlatformImeLastPos - g.PlatformImePos) > 0.0001f) @@ -3566,8 +3569,23 @@ void ImGui::EndFrame() g.PlatformImeLastPos = g.PlatformImePos; } - // Hide implicit "Debug" window if it hasn't been used - IM_ASSERT(g.CurrentWindowStack.Size == 1); // Mismatched Begin()/End() calls, did you forget to call end on g.CurrentWindow->Name? + // Report when there is a mismatch of Begin/BeginChild vs End/EndChild calls. Important: Remember that the Begin/BeginChild API requires you + // to always call End/EndChild even if Begin/BeginChild returns false! (this is unfortunately inconsistent with most other Begin* API). + if (g.CurrentWindowStack.Size != 1) + { + if (g.CurrentWindowStack.Size > 1) + { + IM_ASSERT(g.CurrentWindowStack.Size == 1 && "Mismatched Begin/BeginChild vs End/EndChild calls: did you forget to call End/EndChild?"); + while (g.CurrentWindowStack.Size > 1) // FIXME-ERRORHANDLING + End(); + } + else + { + IM_ASSERT(g.CurrentWindowStack.Size == 1 && "Mismatched Begin/BeginChild vs End/EndChild calls: did you call End/EndChild too much?"); + } + } + + // Hide implicit/fallback "Debug" window if it hasn't been used if (g.CurrentWindow && !g.CurrentWindow->WriteAccessed) g.CurrentWindow->Active = false; End(); @@ -3660,9 +3678,6 @@ void ImGui::EndFrame() g.IO.MouseWheel = g.IO.MouseWheelH = 0.0f; memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters)); memset(g.IO.NavInputs, 0, sizeof(g.IO.NavInputs)); - - g.FrameScopeActive = false; - g.FrameCountEnded = g.FrameCount; } void ImGui::Render() @@ -3703,7 +3718,7 @@ void ImGui::Render() g.IO.MetricsRenderVertices = g.DrawData.TotalVtxCount; g.IO.MetricsRenderIndices = g.DrawData.TotalIdxCount; - // Render. If user hasn't set a callback then they may retrieve the draw data via GetDrawData() + // (Legacy) Call the Render callback function. The current prefer way is to let the user retrieve GetDrawData() and call the render function themselves. #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS if (g.DrawData.CmdListsCount > 0 && g.IO.RenderDrawListsFn != NULL) g.IO.RenderDrawListsFn(&g.DrawData); @@ -5246,6 +5261,13 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_first_use, void ImGui::End() { ImGuiContext& g = *GImGui; + + if (g.CurrentWindowStack.Size <= 1 && g.FrameScopeActive) + { + IM_ASSERT(g.CurrentWindowStack.Size > 1 && "Calling End() too many times!"); + return; // FIXME-ERRORHANDLING + } + ImGuiWindow* window = g.CurrentWindow; if (window->DC.ColumnsSet != NULL)