Files
improvise/web
Edward Langley 9aef855d5f fix: the viewport reserves the real frame, and a fallback width counts cells
Copilot's two "previously missed" findings, both correct.

**`extent()` reserved one header row and one header column.** That was right
until this PR: the column header is now one line per level plus an optional
group line, and the row header is `row_levels` columns wide. Announcing a
viewport the page cannot show matters because `#grid` has `overflow: auto` —
the DOM would take a scroll position of its own while the client's cursor
offsets were computed from the larger window, putting the selected cell off
screen. The cost is measured off the painted model and re-announced when it
changes.

Inline group *rows* are deliberately **not** counted, although they occupy
space: they depend on how many rows the window asked for, so counting them
would be a feedback loop — a smaller window crosses fewer groups and asks
for a larger one. The three facts that are counted depend only on the axes.
The residue is a little over-fetch, the direction `ROW_PX` already errs in.

**`fit_to_labels` measured its fallback width in Unicode scalars.** It is
documented as the width a column is drawn at while `ColWidths` catches up,
and the authoritative widths are in display cells, so `日本` came out two
cells wide where it needs four. Now measured with `UnicodeWidthStr`, like
`header_widths` and like the TUI.
`a_column_without_its_width_yet_is_measured_in_display_cells` pins it, and
restoring `chars().count()` fails it with `[2]` against `[4]`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-19 23:22:30 -07:00
..