From b2f93a172b012bf52b25fb5f2acb62c2041f4f22 Mon Sep 17 00:00:00 2001 From: Jaap-Jan de Wit | DodoTech Date: Fri, 21 Aug 2026 14:01:45 +0200 Subject: [PATCH] Give the file listings' columns their content back MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The columns in both panes were fixed pixel widths, and measuring them against what they actually draw found them wrong at both ends of the range this screen gets. ◆ MODIFIED WAS TRUNCATED AT EVERY WIDTH THE APPLICATION HAS EVER BEEN DRAWN AT. It prints a sixteen-character timestamp, which needs 116 pixels, and it had 52. On a maximised window that read "2026-08" beside a NAME column with four hundred empty pixels in it. PERMS needs 60 for a ten-character mode and had 48; SIZE needs 58 for "999.9 GB" and had 56. ◆ AND AT THE SESSION SHELL'S OWN NARROWEST, NAME MEASURED ZERO PIXELS. Twenty for the glyph plus 56+52+48 for the numbers is 176 of the 180 a row has, so the remote pane drew sizes, timestamps and modes for rows whose names were not on screen at all. That is the same fault as the one above rather than a second one: the numbers were picked for the narrow budget, could not have fitted their own content there, and never grew anywhere else. Star columns with a MaxWidth answer both, because the cap is what makes "share the width" mean the right thing at each end. Wide, the three numeric columns stop growing at what their text needs and NAME keeps every remaining pixel. Narrow, nothing carries a MinWidth to overflow with, so all four give ground together and NAME — weighted heaviest — is the last to run out. MODIFIED takes the extra weight so it reaches its cap first, being the widest content and the column most often actually read; the local pane's NAME carries the remote's PERMS weight folded into it, which is what makes SIZE and MODIFIED come out the same width on both sides of the arrow column. Timestamps.Format already argued that both panes write a time the same way so the two can be read against each other, and two different widths would have made that argument for nothing. ◆ THE HEADINGS RAN TOGETHER, and that was visible as one word: SIZE ended on the pixel MODIFIED began at, so the row read "SIZEMODIFIED". They are right-aligned in their own columns, so the gap has to come from a left margin on each — which does not move the label and does stop the column before it reaching this one. The three now carry one, and ellipsize rather than clip where even the label has no room. ◆ TWO PLACEHOLDERS WERE CUT OFF MID-WORD, which reads as a rendering fault rather than as a hint. MKDIR's box drew "new directo" — 101 pixels of text in 74 pixels of room — and says "directory" now, since the button beside it carries the "new" half already. The pane header's path box drew a path ending mid-segment at the narrow budget and says "path": the only time that placeholder shows is on a pane with nothing connected, where the box is disabled and the invitation below is doing the explaining, and what the box is for is in its tooltip where there is room for it. FOUR COPIES OF THE COLUMN DEFINITIONS, one heading row and one row template per pane. Avalonia cannot share a ColumnDefinitions instance between two Grids — each mutates its own computed sizes — and SharedSizeGroup only applies to Auto columns, so what catches a copy that drifts is measurement rather than discipline: every cell is held against the width its own text needs when unconstrained, the headings against each other, and NAME against zero at the narrowest budget. Nothing asserts a number this file also wrote down, which is the failure mode a test of a layout most easily has. The roomy end is measured at the width a maximised 1843-pixel window leaves, which is where this was reported from; LayoutHarness.SessionScreenWidth cannot express it because that constant is pinned to the window's minimum, so the arithmetic is spelled out beside the test that uses it. --- .../Views/TransfersScreen.axaml | 106 +++++++- .../ScreenLayoutTests.cs | 257 ++++++++++++++++++ 2 files changed, 350 insertions(+), 13 deletions(-) diff --git a/src/DodoSSH.Client.App/Views/TransfersScreen.axaml b/src/DodoSSH.Client.App/Views/TransfersScreen.axaml index 6b86b65..f003f5c 100644 --- a/src/DodoSSH.Client.App/Views/TransfersScreen.axaml +++ b/src/DodoSSH.Client.App/Views/TransfersScreen.axaml @@ -33,6 +33,43 @@ layer has not got. See docs/design-import-gaps.md. --> + + - + + + + + + + - - + + @@ -584,10 +641,16 @@ is showing, 140 plus MKDIR plus the spacing between them ran past the pane's own edge. Still wide enough for a real directory name to be typed and read back, which is what this box is for; a name that outgrows it scrolls inside the box the way every TextBox already does. + + ◆ The placeholder says "directory" rather than "new directory", which is what it said until it + was measured: the longer text needs 101 pixels inside a box that has 74, so it drew as "new + directo" — a placeholder cut off mid-word, which reads as a rendering fault rather than as a + hint. MKDIR is right beside it and carries the "new" half already. The path box in the header + above lost the same argument and for the same reason; see its own PlaceholderText. --> - +