From b87728bd2b2bdaa63efa13f390adb73ed3c40afd Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 29 Oct 2026 13:47:01 +0100 Subject: [PATCH] Tables: clamp vertical border Y2 position when not using scrolling table, so that ImDrawCmd AABB stays reasonable. This does not fix any screen visible issue, and should not be noticeable if correct. (context: investigated this while looking at #4678, but not actually directly related) --- docs/CHANGELOG.txt | 3 +++ imgui.h | 2 +- imgui_tables.cpp | 18 ++++++++++++------ 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index ec2cc0763..d0704cac1 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -78,6 +78,9 @@ Other Changes: - Popups: - Modals: fixed an assert displaying a modal in an environment where `io.DisplayFramebufferScale` is not an integer (regression in 1.93.0). (#9598) +- Tables: + - In non-scrolling tables, clamp lower border coordinates to stay within visible + range (no visible changes, but ImDrawCmd AABB becomes more sensible). - ImVec2: added a check for cases where a custom `IM_VEC2_CLASS_EXTRA` macro adds an extra `operator=` to ImVec2. This isn't supported but should not be needed as you should have a constructor to convert from your type to ImVec2. diff --git a/imgui.h b/imgui.h index 04c25c98e..9a2313a59 100644 --- a/imgui.h +++ b/imgui.h @@ -30,7 +30,7 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') #define IMGUI_VERSION "1.93.1 WIP" -#define IMGUI_VERSION_NUM 19301 +#define IMGUI_VERSION_NUM 19302 #define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000 #define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198 diff --git a/imgui_tables.cpp b/imgui_tables.cpp index e82c71dfb..a303760a0 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -2951,19 +2951,24 @@ static ImU32 TableGetColumnBorderCol(ImGuiTable* table, int order_n, int column_ void ImGui::TableDrawBorders(ImGuiTable* table) { ImGuiWindow* inner_window = table->InnerWindow; - if (!table->OuterWindow->ClipRect.Overlaps(table->OuterRect)) + if (!table->OuterWindow->ClipRect.Overlaps(table->OuterRect)) // Note how OuterWindow->ClipRect == table->Bg0ClipRectForDrawCmd return; ImDrawList* inner_drawlist = inner_window->DrawList; table->DrawSplitter->SetCurrentChannel(inner_drawlist, TABLE_DRAW_CHANNEL_BG0); - inner_drawlist->PushClipRect(table->Bg0ClipRectForDrawCmd.Min, table->Bg0ClipRectForDrawCmd.Max, false); + inner_drawlist->PushClipRect(table->OuterWindow->ClipRect.Min, table->OuterWindow->ClipRect.Max, false); + + const float border_size = TABLE_BORDER_SIZE; + + // For e.g. non scrolling table we limit vertex coordinates in order to keep ImDrawCmd AABB roughly within visible range. + const float draw_y2_limit = table->OuterWindow->ClipRect.Max.y + (2.0f * ImMax(border_size, inner_drawlist->_FringeScale)); // Draw inner border and resizing feedback ImGuiTableInstanceData* table_instance = TableGetInstanceData(table, table->InstanceCurrent); - const float border_size = TABLE_BORDER_SIZE; const float draw_y1 = ImMax(table->InnerRect.Min.y, (table->FreezeRowsCount >= 1 ? table->InnerRect.Min.y : table->WorkRect.Min.y) + table->AngledHeadersHeight) + ((table->Flags & ImGuiTableFlags_BordersOuterH) ? border_size : 0.0f); - const float draw_y2_body = table->InnerRect.Max.y; - const float draw_y2_head = table->IsUsingHeaders ? ImMin(table->InnerRect.Max.y, (table->FreezeRowsCount >= 1 ? table->InnerRect.Min.y : table->WorkRect.Min.y) + table_instance->LastTopHeadersRowHeight) : draw_y1; + const float draw_y2_body = ImMin(table->InnerRect.Max.y, draw_y2_limit); + const float draw_y2_head = table->IsUsingHeaders ? ImMin(draw_y2_body, (table->FreezeRowsCount >= 1 ? table->InnerRect.Min.y : table->WorkRect.Min.y) + table_instance->LastTopHeadersRowHeight) : draw_y1; + if (table->Flags & ImGuiTableFlags_BordersInnerV) { for (int order_n = 0; order_n < table->ColumnsCount; order_n++) @@ -3009,7 +3014,8 @@ void ImGui::TableDrawBorders(ImGuiTable* table) // parent. In inner_window, it won't reach out over scrollbars. Another weird solution would be to display part // of it in inner window, and the part that's over scrollbars in the outer window..) // Either solution currently won't allow us to use a larger border size: the border would clipped. - const ImRect outer_border = table->OuterRect; + ImRect outer_border = table->OuterRect; + outer_border.Max.y = ImMin(outer_border.Max.y, draw_y2_limit); // Clamp but keep bottom border non-visible. const ImU32 outer_col = table->BorderColorStrong; if ((table->Flags & ImGuiTableFlags_BordersOuter) == ImGuiTableFlags_BordersOuter) {