Files
DodoSSH/tests/DodoSSH.Client.App.Layout.Tests
jaap-jan b2f93a172b
ci / build and test (pull_request) Successful in 2m32s
ci / desktop nightly (pull_request) Skipped
ci / android head (pull_request) Successful in 3m7s
ci / api image (pull_request) Successful in 4s
Give the file listings' columns their content back
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.
2026-08-21 14:01:45 +02:00
..