Windows: fixed a single-axis auto-resizing feedback loop issue with nested containers and varying scrollbar visibility. (#9352)

This commit is contained in:
ocornut
2026-04-08 21:26:16 +02:00
parent a9bd173d89
commit 1870a779e1
3 changed files with 9 additions and 3 deletions
+3
View File
@@ -51,6 +51,9 @@ Other Changes:
- Fixed issues reporting ideal size to parent window/container: (#9352, #7651) - Fixed issues reporting ideal size to parent window/container: (#9352, #7651)
- When both scrollbars are visible but only one of ScrollX/ScrollY was explicitly requested. - When both scrollbars are visible but only one of ScrollX/ScrollY was explicitly requested.
- When vertical scrollbar was not at the top, the computation was often incorrect. - When vertical scrollbar was not at the top, the computation was often incorrect.
- Windows:
- Fixed a single-axis auto-resizing feedback loop issue with nested containers
and varying scrollbar visibility. (#9352)
- Fonts: - Fonts:
- imgui_freetype: add FreeType headers & compiled version in 'About Dear ImGui' details. - imgui_freetype: add FreeType headers & compiled version in 'About Dear ImGui' details.
- Clipper: - Clipper:
+4 -2
View File
@@ -6768,8 +6768,10 @@ static ImVec2 CalcWindowAutoFitSize(ImGuiWindow* window, const ImVec2& size_cont
// When the window cannot fit all contents (either because of constraints, either because screen is too small), // When the window cannot fit all contents (either because of constraints, either because screen is too small),
// we are growing the size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than ViewportSize-WindowPadding. // we are growing the size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than ViewportSize-WindowPadding.
ImVec2 size_auto_fit_after_constraint = CalcWindowSizeAfterConstraint(window, size_auto_fit); ImVec2 size_auto_fit_after_constraint = CalcWindowSizeAfterConstraint(window, size_auto_fit);
bool will_have_scrollbar_x = (size_auto_fit_after_constraint.x < size_contents.x + size_pad.x + decoration_w_without_scrollbars && !(window->Flags & ImGuiWindowFlags_NoScrollbar) && (window->Flags & ImGuiWindowFlags_HorizontalScrollbar)) || (window->Flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar); float size_contents_for_scrollbar_x = (axis_mask & 1) ? size_contents.x : window->ContentSize.x; // See #9352. In theory this should use same logic as `window->ScrollbarY = ...` codepath in Begin(). Needs some plumbling.
bool will_have_scrollbar_y = (size_auto_fit_after_constraint.y < size_contents.y + size_pad.y + decoration_h_without_scrollbars && !(window->Flags & ImGuiWindowFlags_NoScrollbar)) || (window->Flags & ImGuiWindowFlags_AlwaysVerticalScrollbar); float size_contents_for_scrollbar_y = (axis_mask & 2) ? size_contents.y : window->ContentSize.y;
bool will_have_scrollbar_x = (size_auto_fit_after_constraint.x < size_contents_for_scrollbar_x + size_pad.x + decoration_w_without_scrollbars && !(window->Flags & ImGuiWindowFlags_NoScrollbar) && (window->Flags & ImGuiWindowFlags_HorizontalScrollbar)) || (window->Flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar);
bool will_have_scrollbar_y = (size_auto_fit_after_constraint.y < size_contents_for_scrollbar_y + size_pad.y + decoration_h_without_scrollbars && !(window->Flags & ImGuiWindowFlags_NoScrollbar)) || (window->Flags & ImGuiWindowFlags_AlwaysVerticalScrollbar);
if (will_have_scrollbar_x) if (will_have_scrollbar_x)
size_auto_fit.y += style.ScrollbarSize; size_auto_fit.y += style.ScrollbarSize;
if (will_have_scrollbar_y) if (will_have_scrollbar_y)
+2 -1
View File
@@ -1566,7 +1566,7 @@ void ImGui::EndTable()
else if (temp_data->UserOuterSize.x <= 0.0f) else if (temp_data->UserOuterSize.x <= 0.0f)
{ {
// Some references for this: #7651 + tests "table_reported_size", "table_reported_size_outer" equivalent Y block, #9352 // Some references for this: #7651 + tests "table_reported_size", "table_reported_size_outer" equivalent Y block, #9352
// - FIXME-TABLE: Would make sense to pre-compute expected scrollbar visibility/sizes to generally save a frame of feedback? // - FIXME-TABLE: Would make sense to pre-compute expected scrollbar visibility/sizes to generally save a frame of feedback? See broken test in 'table_reported_size_outer'
const float outer_content_max_x = table->OuterRect.Min.x + table->ColumnsAutoFitWidth; const float outer_content_max_x = table->OuterRect.Min.x + table->ColumnsAutoFitWidth;
const float decoration_size = table->TempData->AngledHeadersExtraWidth + ((inner_window != outer_window) ? inner_window->ScrollbarSizes.x : 0.0f); const float decoration_size = table->TempData->AngledHeadersExtraWidth + ((inner_window != outer_window) ? inner_window->ScrollbarSizes.x : 0.0f);
outer_window->DC.IdealMaxPos.x = ImMax(outer_window->DC.IdealMaxPos.x, outer_content_max_x + decoration_size - temp_data->UserOuterSize.x); outer_window->DC.IdealMaxPos.x = ImMax(outer_window->DC.IdealMaxPos.x, outer_content_max_x + decoration_size - temp_data->UserOuterSize.x);
@@ -1578,6 +1578,7 @@ void ImGui::EndTable()
} }
if (temp_data->UserOuterSize.y <= 0.0f) if (temp_data->UserOuterSize.y <= 0.0f)
{ {
// (same comment as above)
const float outer_content_size_y = (inner_window == outer_window) ? (inner_content_max_y - table->InnerRect.Min.y) : (inner_content_max_y - inner_window->DC.CursorStartPos.y); const float outer_content_size_y = (inner_window == outer_window) ? (inner_content_max_y - table->InnerRect.Min.y) : (inner_content_max_y - inner_window->DC.CursorStartPos.y);
const float outer_content_max_y = table->OuterRect.Min.y + outer_content_size_y; const float outer_content_max_y = table->OuterRect.Min.y + outer_content_size_y;
const float decoration_size = (inner_window != outer_window ? inner_window->ScrollbarSizes.y : 0.0f); const float decoration_size = (inner_window != outer_window ? inner_window->ScrollbarSizes.y : 0.0f);