From f93b1cbf8f9f991a7a0c3616a17a3ca2cb34598c Mon Sep 17 00:00:00 2001 From: Kevin Harder Date: Sun, 26 Apr 2026 14:14:47 -0500 Subject: [PATCH 1/5] Fixes #5072. TableView reserves space for later columns when laying out MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A wide column (e.g. a long Description) previously consumed all available viewport width and pushed subsequent columns off-screen. Each visible column now reserves at least its header width (or configured MinWidth) during layout so wide columns are clamped instead of starving later columns. The reservation only inspects column headers and styles — it never iterates cell rows — so paginated or very large ITableSource implementations remain performant. --- .../Views/TableView/TableView.Content.cs | 100 ++++++++++++++-- .../Views/TableViewTests.cs | 111 ++++++++++++++++++ 2 files changed, 203 insertions(+), 8 deletions(-) diff --git a/Terminal.Gui/Views/TableView/TableView.Content.cs b/Terminal.Gui/Views/TableView/TableView.Content.cs index 93bd81176f..4fb52adc42 100644 --- a/Terminal.Gui/Views/TableView/TableView.Content.cs +++ b/Terminal.Gui/Views/TableView/TableView.Content.cs @@ -182,7 +182,8 @@ public void EnsureValidScrollOffsets () int lastColIdx = nonHiddenColumns.Any () ? nonHiddenColumns.Last ().colIdx : -1; //right border - contentSize.Width += Style.ShowVerticalHeaderLines || Style.ShowVerticalCellLines ? 1 : 0; + int borderWidth = Style.ShowVerticalHeaderLines || Style.ShowVerticalCellLines ? 1 : 0; + contentSize.Width += borderWidth; var startRow = 0; int rowsToRender = Table.Rows; @@ -195,8 +196,9 @@ public void EnsureValidScrollOffsets () } // Calculate the content size based on the table's data - foreach ((int colIdx, ColumnStyle? colStyle) in nonHiddenColumns) + for (var i = 0; i < nonHiddenColumns.Count; i++) { + (int colIdx, ColumnStyle? colStyle) = nonHiddenColumns [i]; int maxContentSize = CalculateMaxCellWidth (colIdx, colStyle, startRow, rowsToRender) + padding; int colWidth = maxContentSize + padding; @@ -212,21 +214,34 @@ public void EnsureValidScrollOffsets () } } - // ToDo: MinAcceptableWidth handling? - // if (colStyle is { MinAcceptableWidth: > 0 } - bool isVeryLast = colIdx == lastColIdx; if (isVeryLast) { - //remaining space for last column - int remainingSpace = Viewport.Width - contentSize.Width - (Style.ShowVerticalHeaderLines || Style.ShowVerticalCellLines ? 1 : 0); + // remaining space for last column + int remainingSpace = Viewport.Width - contentSize.Width - borderWidth; if (Style.ExpandLastColumn && colWidth < remainingSpace) { colWidth = remainingSpace; } } + else if (Viewport.Width > 0) + { + // Reserve at least the header width for each subsequent visible column so that a wide + // column does not consume all viewport space and push later columns off-screen. This is + // O(columns) — we never iterate cell rows here. See issue #5072. + int reservedForRemaining = ReserveSpaceForRemainingColumns (nonHiddenColumns, i + 1); + int availableForThisCol = Viewport.Width - contentSize.Width - reservedForRemaining - borderWidth - 1; // -1 for this column's separator + + // Don't shrink below this column's own minimum (header width or configured minimum) + int thisColMin = MinimumWidthFor (colIdx, colStyle); + + if (colWidth > availableForThisCol && availableForThisCol >= thisColMin) + { + colWidth = availableForThisCol; + } + } columnsToRender.Add (new ColumnToRender (colIdx, contentSize.Width, colWidth + 1, lastColIdx == colIdx)); @@ -240,7 +255,7 @@ public void EnsureValidScrollOffsets () } // for left border - contentSize.Width += Style.ShowVerticalHeaderLines || Style.ShowVerticalCellLines ? 1 : 0; + contentSize.Width += borderWidth; } else { @@ -267,4 +282,73 @@ public void EnsureValidScrollOffsets () return contentSize; } + + /// + /// Returns the minimum render width to reserve for a column that has not yet been laid out, based on its header + /// width and any configured minimum (clamped to and + /// ). This intentionally does not inspect cell data — it is O(1) per column to + /// keep large or paginated implementations performant. + /// + private int MinimumWidthFor (int colIdx, ColumnStyle? colStyle) + { + int min = _table!.ColumnNames [colIdx].GetColumns (); + + if (min < 1) + { + min = 1; + } + + if (colStyle is { MinWidth: > 0 } && colStyle.MinWidth > min) + { + min = colStyle.MinWidth; + } + + if (MinCellWidth > 0 && MinCellWidth > min) + { + min = MinCellWidth; + } + + // Don't reserve more than the column's own ceiling + int ceiling = MaxCellWidth; + + if (colStyle is { } && colStyle.MaxWidth < ceiling) + { + ceiling = colStyle.MaxWidth; + } + + if (ceiling < 1) + { + ceiling = 1; + } + + if (min > ceiling) + { + min = ceiling; + } + + return min; + } + + /// + /// Returns the total horizontal space (including inter-column separators) that should be reserved for the + /// visible columns starting at in . + /// + private int ReserveSpaceForRemainingColumns (List<(int colIdx, ColumnStyle? colStyle)> nonHiddenColumns, int startIndex) + { + var reserved = 0; + + for (int j = startIndex; j < nonHiddenColumns.Count; j++) + { + (int otherColIdx, ColumnStyle? otherColStyle) = nonHiddenColumns [j]; + reserved += MinimumWidthFor (otherColIdx, otherColStyle); + + // Separator between this reserved column and the next reserved column + if (j < nonHiddenColumns.Count - 1) + { + reserved += 1; + } + } + + return reserved; + } } diff --git a/Tests/UnitTestsParallelizable/Views/TableViewTests.cs b/Tests/UnitTestsParallelizable/Views/TableViewTests.cs index 7d1fe8e004..cd0667333f 100644 --- a/Tests/UnitTestsParallelizable/Views/TableViewTests.cs +++ b/Tests/UnitTestsParallelizable/Views/TableViewTests.cs @@ -549,4 +549,115 @@ public void Test_CalculateMaxCellWidth_UsesGraphemeWidth () headerRow }'"); } + + // Claude - Opus 4.5 + // Verifies fix for #5072: a column with very wide content must not consume all viewport space + // and push later columns off-screen. Each subsequent visible column should be reserved at least + // its header width. + [Fact] + public void Calculate_WideColumn_DoesNotStarveLaterColumns () + { + DataTable dt = new (); + dt.Columns.Add ("Description"); + dt.Columns.Add ("Status"); + dt.Columns.Add ("Owner"); + dt.Rows.Add (new string ('x', 200), "ok", "me"); + + TableView tableView = new () + { + Table = new DataTableSource (dt), + Viewport = new Rectangle (0, 0, 40, 5) + }; + tableView.BeginInit (); + tableView.EndInit (); + tableView.RefreshContentSize (); + + TableView.ColumnToRender [] columns = GetColumnsToRender (tableView); + + Assert.Equal (3, columns.Length); + + // Description must be clamped so that Status and Owner fit + TableView.ColumnToRender description = columns [0]; + TableView.ColumnToRender status = columns [1]; + TableView.ColumnToRender owner = columns [2]; + + Assert.True (description.X >= 0); + Assert.True (status.X > description.X); + Assert.True (owner.X > status.X); + + // Every column's right edge must lie within the viewport + Assert.True (description.X + description.Width - 1 <= tableView.Viewport.Width, + $"Description right edge {description.X + description.Width - 1} exceeds viewport {tableView.Viewport.Width}"); + Assert.True (status.X + status.Width - 1 <= tableView.Viewport.Width, + $"Status right edge {status.X + status.Width - 1} exceeds viewport {tableView.Viewport.Width}"); + Assert.True (owner.X + owner.Width - 1 <= tableView.Viewport.Width, + $"Owner right edge {owner.X + owner.Width - 1} exceeds viewport {tableView.Viewport.Width}"); + + // Status and Owner each must have at least header-width room (excluding separator) + Assert.True (status.Width - 1 >= "Status".Length, $"Status got width {status.Width - 1}"); + Assert.True (owner.Width - 1 >= "Owner".Length, $"Owner got width {owner.Width - 1}"); + } + + // Claude - Opus 4.5 + // When the viewport is too small to fit even minimum widths for every column, layout falls back + // to the prior left-to-right packing (columns may extend past the viewport, accessible via + // horizontal scrolling). + [Fact] + public void Calculate_NarrowViewport_StillProducesLayout () + { + DataTable dt = new (); + dt.Columns.Add ("Description"); + dt.Columns.Add ("Status"); + dt.Columns.Add ("Owner"); + dt.Rows.Add (new string ('x', 50), "ok", "me"); + + TableView tableView = new () + { + Table = new DataTableSource (dt), + Viewport = new Rectangle (0, 0, 10, 5) + }; + tableView.BeginInit (); + tableView.EndInit (); + tableView.RefreshContentSize (); + + TableView.ColumnToRender [] columns = GetColumnsToRender (tableView); + + Assert.Equal (3, columns.Length); + + // Each column should have a positive width + Assert.All (columns, c => Assert.True (c.Width > 0, $"Column {c.Column} got non-positive width {c.Width}")); + } + + // Claude - Opus 4.5 + // Single-column tables should still expand to fill the viewport when ExpandLastColumn is true. + [Fact] + public void Calculate_SingleColumn_StillExpandsLastColumn () + { + DataTable dt = new (); + dt.Columns.Add ("Only"); + dt.Rows.Add ("hi"); + + TableView tableView = new () + { + Table = new DataTableSource (dt), + Viewport = new Rectangle (0, 0, 30, 5) + }; + tableView.BeginInit (); + tableView.EndInit (); + tableView.RefreshContentSize (); + + TableView.ColumnToRender [] columns = GetColumnsToRender (tableView); + + Assert.Single (columns); + Assert.True (columns [0].Width >= tableView.Viewport.Width - 2, + $"Single column width {columns [0].Width} should fill viewport {tableView.Viewport.Width}"); + } + + private static TableView.ColumnToRender [] GetColumnsToRender (TableView tableView) + { + FieldInfo? field = typeof (TableView).GetField ("_columnsToRenderCache", BindingFlags.Instance | BindingFlags.NonPublic); + Assert.NotNull (field); + + return (TableView.ColumnToRender []?)field!.GetValue (tableView) ?? []; + } } From 8a7a51c8053dae242588086ca5c5341de1320ecf Mon Sep 17 00:00:00 2001 From: Kevin Harder Date: Sun, 26 Apr 2026 14:38:10 -0500 Subject: [PATCH 2/5] Tighten TableView column-bounds test to use strict inequality Right-edge check now uses < Viewport.Width instead of <= per code review. Co-Authored-By: Claude Opus 4.7 (1M context) --- Tests/UnitTestsParallelizable/Views/TableViewTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Tests/UnitTestsParallelizable/Views/TableViewTests.cs b/Tests/UnitTestsParallelizable/Views/TableViewTests.cs index cd0667333f..821c3ecf7b 100644 --- a/Tests/UnitTestsParallelizable/Views/TableViewTests.cs +++ b/Tests/UnitTestsParallelizable/Views/TableViewTests.cs @@ -586,11 +586,11 @@ public void Calculate_WideColumn_DoesNotStarveLaterColumns () Assert.True (owner.X > status.X); // Every column's right edge must lie within the viewport - Assert.True (description.X + description.Width - 1 <= tableView.Viewport.Width, + Assert.True (description.X + description.Width - 1 < tableView.Viewport.Width, $"Description right edge {description.X + description.Width - 1} exceeds viewport {tableView.Viewport.Width}"); - Assert.True (status.X + status.Width - 1 <= tableView.Viewport.Width, + Assert.True (status.X + status.Width - 1 < tableView.Viewport.Width, $"Status right edge {status.X + status.Width - 1} exceeds viewport {tableView.Viewport.Width}"); - Assert.True (owner.X + owner.Width - 1 <= tableView.Viewport.Width, + Assert.True (owner.X + owner.Width - 1 < tableView.Viewport.Width, $"Owner right edge {owner.X + owner.Width - 1} exceeds viewport {tableView.Viewport.Width}"); // Status and Owner each must have at least header-width room (excluding separator) From 9972ff446573b8ed26f573a97f0e05ab37e0b74f Mon Sep 17 00:00:00 2001 From: Kevin Harder Date: Sun, 26 Apr 2026 14:50:22 -0500 Subject: [PATCH 3/5] Restore foreach loop in TableView.CalculateContentSize Use a manual index counter rather than converting the loop to for, and revert the unrelated borderWidth local-variable extraction. The fix only needs the index to compute the slice of remaining columns to reserve space for. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../Views/TableView/TableView.Content.cs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/Terminal.Gui/Views/TableView/TableView.Content.cs b/Terminal.Gui/Views/TableView/TableView.Content.cs index 4fb52adc42..085734017f 100644 --- a/Terminal.Gui/Views/TableView/TableView.Content.cs +++ b/Terminal.Gui/Views/TableView/TableView.Content.cs @@ -182,8 +182,7 @@ public void EnsureValidScrollOffsets () int lastColIdx = nonHiddenColumns.Any () ? nonHiddenColumns.Last ().colIdx : -1; //right border - int borderWidth = Style.ShowVerticalHeaderLines || Style.ShowVerticalCellLines ? 1 : 0; - contentSize.Width += borderWidth; + contentSize.Width += Style.ShowVerticalHeaderLines || Style.ShowVerticalCellLines ? 1 : 0; var startRow = 0; int rowsToRender = Table.Rows; @@ -196,9 +195,10 @@ public void EnsureValidScrollOffsets () } // Calculate the content size based on the table's data - for (var i = 0; i < nonHiddenColumns.Count; i++) + var columnIndex = 0; + + foreach ((int colIdx, ColumnStyle? colStyle) in nonHiddenColumns) { - (int colIdx, ColumnStyle? colStyle) = nonHiddenColumns [i]; int maxContentSize = CalculateMaxCellWidth (colIdx, colStyle, startRow, rowsToRender) + padding; int colWidth = maxContentSize + padding; @@ -218,8 +218,8 @@ public void EnsureValidScrollOffsets () if (isVeryLast) { - // remaining space for last column - int remainingSpace = Viewport.Width - contentSize.Width - borderWidth; + //remaining space for last column + int remainingSpace = Viewport.Width - contentSize.Width - (Style.ShowVerticalHeaderLines || Style.ShowVerticalCellLines ? 1 : 0); if (Style.ExpandLastColumn && colWidth < remainingSpace) { @@ -231,7 +231,8 @@ public void EnsureValidScrollOffsets () // Reserve at least the header width for each subsequent visible column so that a wide // column does not consume all viewport space and push later columns off-screen. This is // O(columns) — we never iterate cell rows here. See issue #5072. - int reservedForRemaining = ReserveSpaceForRemainingColumns (nonHiddenColumns, i + 1); + int reservedForRemaining = ReserveSpaceForRemainingColumns (nonHiddenColumns, columnIndex + 1); + int borderWidth = Style.ShowVerticalHeaderLines || Style.ShowVerticalCellLines ? 1 : 0; int availableForThisCol = Viewport.Width - contentSize.Width - reservedForRemaining - borderWidth - 1; // -1 for this column's separator // Don't shrink below this column's own minimum (header width or configured minimum) @@ -252,10 +253,12 @@ public void EnsureValidScrollOffsets () // for separator symbols between columns contentSize.Width += 1; } + + columnIndex++; } // for left border - contentSize.Width += borderWidth; + contentSize.Width += Style.ShowVerticalHeaderLines || Style.ShowVerticalCellLines ? 1 : 0; } else { From db6258dbae9fbee5b32f5fe1cd62d3d8830debf3 Mon Sep 17 00:00:00 2001 From: Kevin Harder Date: Mon, 27 Apr 2026 12:06:13 -0500 Subject: [PATCH 4/5] Updated table col width calculation and added wide example --- Examples/UICatalog/Scenarios/TableEditor.cs | 31 ++++++++++++ .../Views/TableView/TableView.Content.cs | 48 ++++++++----------- 2 files changed, 52 insertions(+), 27 deletions(-) diff --git a/Examples/UICatalog/Scenarios/TableEditor.cs b/Examples/UICatalog/Scenarios/TableEditor.cs index 338d38ec51..955d778eed 100644 --- a/Examples/UICatalog/Scenarios/TableEditor.cs +++ b/Examples/UICatalog/Scenarios/TableEditor.cs @@ -221,6 +221,7 @@ public override void Main () [ new MenuItem { Title = "_OpenBigExample", Action = () => OpenExample (true) }, new MenuItem { Title = "_OpenSmallExample", Action = () => OpenExample (false) }, + new MenuItem { Title = "Open_WideColumnExample", Action = OpenWideColumnExample }, new MenuItem { Title = "OpenCharacter_Map", Action = OpenUnicodeMap }, new MenuItem { Title = "OpenTreeExample", Action = OpenTreeExample }, new MenuItem { Title = "_CloseExample", Action = CloseExample }, @@ -883,6 +884,36 @@ private void OpenExample (bool big) private void OpenSimple (bool big) => SetTable (BuildSimpleDataTable (big ? 30 : 5, big ? 1000 : 5)); + // Demonstrates the fix for #5072: a column with very wide content used to consume all viewport + // space and push later columns off-screen. With the fix, "Description" is clamped so "Status" and + // "Owner" remain visible at their header widths. + private void OpenWideColumnExample () + { + DataTable dt = new (); + dt.Columns.Add ("Id", typeof (int)); + dt.Columns.Add ("Description", typeof (string)); + dt.Columns.Add ("Status", typeof (string)); + dt.Columns.Add ("Owner", typeof (string)); + + string [] statuses = ["Open", "InProgress", "Blocked", "Done"]; + string [] owners = ["Alice", "Bob", "Carol", "Dan"]; + + for (var i = 0; i < 25; i++) + { + dt.Rows.Add ( + i, + $"Row {i}: " + new string ('x', 120 + i % 40), + statuses [i % statuses.Length], + owners [i % owners.Length]); + } + + SetTable (dt); + + // Clear any styles inherited from a previous example + _tableView!.Style.ColumnStyles.Clear (); + _tableView!.Update (); + } + private void OpenTreeExample () { _tableView!.Style.ColumnStyles.Clear (); diff --git a/Terminal.Gui/Views/TableView/TableView.Content.cs b/Terminal.Gui/Views/TableView/TableView.Content.cs index 085734017f..cf0965ff33 100644 --- a/Terminal.Gui/Views/TableView/TableView.Content.cs +++ b/Terminal.Gui/Views/TableView/TableView.Content.cs @@ -181,6 +181,24 @@ public void EnsureValidScrollOffsets () int lastColIdx = nonHiddenColumns.Any () ? nonHiddenColumns.Last ().colIdx : -1; + // Precompute per-column minimum widths and a suffix sum so that "space reserved for remaining + // columns" is O(1) per column. The whole layout pass stays O(columns) + int columnCount = nonHiddenColumns.Count; + int [] minWidths = new int [columnCount]; + int [] reservedFromIndex = new int [columnCount + 1]; + + for (var i = 0; i < columnCount; i++) + { + (int colIdx, ColumnStyle? colStyle) = nonHiddenColumns [i]; + minWidths [i] = MinimumWidthFor (colIdx, colStyle); + } + + for (int i = columnCount - 1; i >= 0; i--) + { + int separator = i < columnCount - 1 ? 1 : 0; + reservedFromIndex [i] = minWidths [i] + separator + reservedFromIndex [i + 1]; + } + //right border contentSize.Width += Style.ShowVerticalHeaderLines || Style.ShowVerticalCellLines ? 1 : 0; @@ -229,14 +247,13 @@ public void EnsureValidScrollOffsets () else if (Viewport.Width > 0) { // Reserve at least the header width for each subsequent visible column so that a wide - // column does not consume all viewport space and push later columns off-screen. This is - // O(columns) — we never iterate cell rows here. See issue #5072. - int reservedForRemaining = ReserveSpaceForRemainingColumns (nonHiddenColumns, columnIndex + 1); + // column does not consume all viewport space and push later columns off-screen. + int reservedForRemaining = reservedFromIndex [columnIndex + 1]; int borderWidth = Style.ShowVerticalHeaderLines || Style.ShowVerticalCellLines ? 1 : 0; int availableForThisCol = Viewport.Width - contentSize.Width - reservedForRemaining - borderWidth - 1; // -1 for this column's separator // Don't shrink below this column's own minimum (header width or configured minimum) - int thisColMin = MinimumWidthFor (colIdx, colStyle); + int thisColMin = minWidths [columnIndex]; if (colWidth > availableForThisCol && availableForThisCol >= thisColMin) { @@ -331,27 +348,4 @@ private int MinimumWidthFor (int colIdx, ColumnStyle? colStyle) return min; } - - /// - /// Returns the total horizontal space (including inter-column separators) that should be reserved for the - /// visible columns starting at in . - /// - private int ReserveSpaceForRemainingColumns (List<(int colIdx, ColumnStyle? colStyle)> nonHiddenColumns, int startIndex) - { - var reserved = 0; - - for (int j = startIndex; j < nonHiddenColumns.Count; j++) - { - (int otherColIdx, ColumnStyle? otherColStyle) = nonHiddenColumns [j]; - reserved += MinimumWidthFor (otherColIdx, otherColStyle); - - // Separator between this reserved column and the next reserved column - if (j < nonHiddenColumns.Count - 1) - { - reserved += 1; - } - } - - return reserved; - } } From 7a0932df104449aba96d90c4fce59555016aaf03 Mon Sep 17 00:00:00 2001 From: Kevin Harder Date: Mon, 27 Apr 2026 12:32:35 -0500 Subject: [PATCH 5/5] Fixed tests and updated comment wording based on copilot pr feedback --- Terminal.Gui/Views/TableView/TableView.Content.cs | 3 ++- .../UnitTestsParallelizable/Views/TableViewTests.cs | 12 ++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Terminal.Gui/Views/TableView/TableView.Content.cs b/Terminal.Gui/Views/TableView/TableView.Content.cs index cf0965ff33..a725c0b110 100644 --- a/Terminal.Gui/Views/TableView/TableView.Content.cs +++ b/Terminal.Gui/Views/TableView/TableView.Content.cs @@ -182,7 +182,8 @@ public void EnsureValidScrollOffsets () int lastColIdx = nonHiddenColumns.Any () ? nonHiddenColumns.Last ().colIdx : -1; // Precompute per-column minimum widths and a suffix sum so that "space reserved for remaining - // columns" is O(1) per column. The whole layout pass stays O(columns) + // columns" is O(1) per column during reservation/min-width bookkeeping. Later width calculations + // may still inspect row data. int columnCount = nonHiddenColumns.Count; int [] minWidths = new int [columnCount]; int [] reservedFromIndex = new int [columnCount + 1]; diff --git a/Tests/UnitTestsParallelizable/Views/TableViewTests.cs b/Tests/UnitTestsParallelizable/Views/TableViewTests.cs index 821c3ecf7b..72e65925f0 100644 --- a/Tests/UnitTestsParallelizable/Views/TableViewTests.cs +++ b/Tests/UnitTestsParallelizable/Views/TableViewTests.cs @@ -550,7 +550,7 @@ public void Test_CalculateMaxCellWidth_UsesGraphemeWidth () }'"); } - // Claude - Opus 4.5 + // Copilot // Verifies fix for #5072: a column with very wide content must not consume all viewport space // and push later columns off-screen. Each subsequent visible column should be reserved at least // its header width. @@ -563,7 +563,7 @@ public void Calculate_WideColumn_DoesNotStarveLaterColumns () dt.Columns.Add ("Owner"); dt.Rows.Add (new string ('x', 200), "ok", "me"); - TableView tableView = new () + using TableView tableView = new () { Table = new DataTableSource (dt), Viewport = new Rectangle (0, 0, 40, 5) @@ -598,7 +598,7 @@ public void Calculate_WideColumn_DoesNotStarveLaterColumns () Assert.True (owner.Width - 1 >= "Owner".Length, $"Owner got width {owner.Width - 1}"); } - // Claude - Opus 4.5 + // Copilot // When the viewport is too small to fit even minimum widths for every column, layout falls back // to the prior left-to-right packing (columns may extend past the viewport, accessible via // horizontal scrolling). @@ -611,7 +611,7 @@ public void Calculate_NarrowViewport_StillProducesLayout () dt.Columns.Add ("Owner"); dt.Rows.Add (new string ('x', 50), "ok", "me"); - TableView tableView = new () + using TableView tableView = new () { Table = new DataTableSource (dt), Viewport = new Rectangle (0, 0, 10, 5) @@ -628,7 +628,7 @@ public void Calculate_NarrowViewport_StillProducesLayout () Assert.All (columns, c => Assert.True (c.Width > 0, $"Column {c.Column} got non-positive width {c.Width}")); } - // Claude - Opus 4.5 + // Copilot // Single-column tables should still expand to fill the viewport when ExpandLastColumn is true. [Fact] public void Calculate_SingleColumn_StillExpandsLastColumn () @@ -637,7 +637,7 @@ public void Calculate_SingleColumn_StillExpandsLastColumn () dt.Columns.Add ("Only"); dt.Rows.Add ("hi"); - TableView tableView = new () + using TableView tableView = new () { Table = new DataTableSource (dt), Viewport = new Rectangle (0, 0, 30, 5)