Internals: Begin: update ->Hidden flags only on first begin of the frame. (ignore whitespace to see simple diff)

# Conflicts:
#	imgui.cpp
This commit is contained in:
ocornut 2020-09-01 15:24:24 +02:00
parent 34077c0140
commit fc625d249f

View File

@ -5602,6 +5602,7 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar
ImGuiWindowFlags flags = window->Flags; ImGuiWindowFlags flags = window->Flags;
// Ensure that ScrollBar doesn't read last frame's SkipItems // Ensure that ScrollBar doesn't read last frame's SkipItems
IM_ASSERT(window->BeginCount == 0);
window->SkipItems = false; window->SkipItems = false;
// Draw window + handle manual resize // Draw window + handle manual resize
@ -6626,49 +6627,53 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->BeginCount++; window->BeginCount++;
g.NextWindowData.ClearFlags(); g.NextWindowData.ClearFlags();
// When we are about to select this tab (which will only be visible on the _next frame_), flag it with a non-zero HiddenFramesCannotSkipItems. // Update visibility
// This will have the important effect of actually returning true in Begin() and not setting SkipItems, allowing an earlier submission of the window contents. if (first_begin_of_the_frame)
// This is analogous to regular windows being hidden from one frame.
// It is especially important as e.g. nested TabBars would otherwise generate flicker in the form of one empty frame, or focus requests won't be processed.
if (window->DockIsActive && !window->DockTabIsVisible)
{ {
if (window->LastFrameJustFocused == g.FrameCount) // When we are about to select this tab (which will only be visible on the _next frame_), flag it with a non-zero HiddenFramesCannotSkipItems.
window->HiddenFramesCannotSkipItems = 1; // This will have the important effect of actually returning true in Begin() and not setting SkipItems, allowing an earlier submission of the window contents.
else // This is analogous to regular windows being hidden from one frame.
window->HiddenFramesCanSkipItems = 1; // It is especially important as e.g. nested TabBars would otherwise generate flicker in the form of one empty frame, or focus requests won't be processed.
} if (window->DockIsActive && !window->DockTabIsVisible)
{
if (flags & ImGuiWindowFlags_ChildWindow) if (window->LastFrameJustFocused == g.FrameCount)
{ window->HiddenFramesCannotSkipItems = 1;
// Child window can be out of sight and have "negative" clip windows. else
// Mark them as collapsed so commands are skipped earlier (we can't manually collapse them because they have no title bar).
IM_ASSERT((flags & ImGuiWindowFlags_NoTitleBar) != 0 || (window->DockIsActive));
if (!(flags & ImGuiWindowFlags_AlwaysAutoResize) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0)
if (window->OuterRectClipped.Min.x >= window->OuterRectClipped.Max.x || window->OuterRectClipped.Min.y >= window->OuterRectClipped.Max.y)
window->HiddenFramesCanSkipItems = 1; window->HiddenFramesCanSkipItems = 1;
}
// Hide along with parent or if parent is collapsed if (flags & ImGuiWindowFlags_ChildWindow)
if (parent_window && (parent_window->Collapsed || parent_window->HiddenFramesCanSkipItems > 0)) {
// Child window can be out of sight and have "negative" clip windows.
// Mark them as collapsed so commands are skipped earlier (we can't manually collapse them because they have no title bar).
IM_ASSERT((flags & ImGuiWindowFlags_NoTitleBar) != 0 || (window->DockIsActive));
if (!(flags & ImGuiWindowFlags_AlwaysAutoResize) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0)
if (window->OuterRectClipped.Min.x >= window->OuterRectClipped.Max.x || window->OuterRectClipped.Min.y >= window->OuterRectClipped.Max.y)
window->HiddenFramesCanSkipItems = 1;
// Hide along with parent or if parent is collapsed
if (parent_window && (parent_window->Collapsed || parent_window->HiddenFramesCanSkipItems > 0))
window->HiddenFramesCanSkipItems = 1;
if (parent_window && (parent_window->Collapsed || parent_window->HiddenFramesCannotSkipItems > 0))
window->HiddenFramesCannotSkipItems = 1;
}
// Don't render if style alpha is 0.0 at the time of Begin(). This is arbitrary and inconsistent but has been there for a long while (may remove at some point)
if (style.Alpha <= 0.0f)
window->HiddenFramesCanSkipItems = 1; window->HiddenFramesCanSkipItems = 1;
if (parent_window && (parent_window->Collapsed || parent_window->HiddenFramesCannotSkipItems > 0))
window->HiddenFramesCannotSkipItems = 1; // Update the Hidden flag
window->Hidden = (window->HiddenFramesCanSkipItems > 0) || (window->HiddenFramesCannotSkipItems > 0);
// Update the SkipItems flag, used to early out of all items functions (no layout required)
bool skip_items = false;
if (window->Collapsed || !window->Active || window->Hidden)
if (window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0 && window->HiddenFramesCannotSkipItems <= 0)
skip_items = true;
window->SkipItems = skip_items;
} }
// Don't render if style alpha is 0.0 at the time of Begin(). This is arbitrary and inconsistent but has been there for a long while (may remove at some point) return !window->SkipItems;
if (style.Alpha <= 0.0f)
window->HiddenFramesCanSkipItems = 1;
// Update the Hidden flag
window->Hidden = (window->HiddenFramesCanSkipItems > 0) || (window->HiddenFramesCannotSkipItems > 0);
// Update the SkipItems flag, used to early out of all items functions (no layout required)
bool skip_items = false;
if (window->Collapsed || !window->Active || window->Hidden)
if (window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0 && window->HiddenFramesCannotSkipItems <= 0)
skip_items = true;
window->SkipItems = skip_items;
return !skip_items;
} }
void ImGui::End() void ImGui::End()