Draw the terminal at the size of the pane it is in - #81
Merged
Conversation
A viewer never changes how many columns and rows a session has: the relay picks the grid and the CLI opens the PTY at it. What it chooses is how large to draw them, and that was one knob — the font size, scaled until the grid fitted in whichever direction ran out first. A pane is almost never the shape of a 120x36 grid, so on a wide one the columns stopped growing as soon as the rows reached the bottom: about a third of the pane stayed empty and the text was a third smaller than there was room for. The font now comes from the width, where the columns are, and the rows are spread down the full height with the leading that is left over, between the font's own line box and the leading the surface asked for. Neither axis may overflow: the size is derived from what the browser says a character measures, then checked against what the emulator will actually lay out, at the device pixel ratio it will round to. On a 1440x900 window a 120x36 session goes from 11.5px filling 77% of its pane to 14.75px filling 98%, and what the fit cannot use is now split between both sides rather than left down one of them. The measurements move into terminal-metrics.ts beside the fit, vendored into the app the same way, so both surfaces measure a character identically. Doing it directly also retires FitAddon in the viewer, whose proposeDimensions was the only thing it was used for. Also: keep the open session tabs across a reload, and take the box off the columns of the session board. A reload closed every terminal that was open. The ids of the open tabs and the one in front are now remembered per account, and put back from the first session list the page receives — rebuilt from that list rather than from what was stored, so a restored tab is never a stale copy, and a session that has since ended does not return. Nothing is written to the browser that the list would not hand over anyway. Each board column drew a border and a wash around cards that already carry both, so three short columns read as three mostly empty containers.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The terminal did not fill its pane
A viewer never changes how many columns and rows a session has — the relay picks the grid, the CLI opens the PTY at it. What a viewer chooses is how large to draw them, and that was a single knob: the font size, scaled until the grid fitted in whichever direction ran out first.
A pane is almost never the shape of a 120x36 grid, so on a wide one the columns stopped growing the moment the rows reached the bottom. Measured in a real layout at four window sizes, the grid used only 68–77% of the pane's width, and the text was a third smaller than there was room for.
What changed
fittedTerminalreplacesfittedTerminalFontSizeand returns two things instead of one:Neither axis may overflow. The size is derived from what the browser says a character measures, then checked against what the emulator will actually lay out — columns rounded to whole CSS pixels, rows to whole device pixels at the ratio the screen will round to — and stepped down if it would not fit. A test sweeps 126 box/ratio combinations and asserts the drawn grid never exceeds the box.
All of it is client-side: no session, no relay and no PTY sees any of this.
Supporting changes:
web/terminal-metrics.ts, vendored into the app beside the fit and covered bynpm run check:protocol, holds the two browser measurements — what a character occupies (the way xterm measures it, so the chosen size is the size that lands) and how much room the pane has, minus a scrollbar only where the platform actually takes one.FitAddonin the viewer, whereproposeDimensionswas the only thing it was used for. The app still ships it for the sign-in page's animated preview, which genuinely wants a grid that fills its box.Also in here
The open tabs survive a reload. Refreshing put you back at the list with every terminal closed. The ids of the open tabs and the one in front are now remembered per account, and put back from the first session list the page receives — rebuilt from that list rather than from what was stored, so a restored tab is never a stale copy of a session, and one that has since ended does not come back. Nothing is written to the browser that the session list would not hand over anyway.
The board columns lose their box. Each column drew a border and a wash around cards that already carry both, so three short columns read as three mostly empty containers.
Checks
npm run typecheck,npx vitest run(20 files) andnpm run build:webat the root;npm run typecheck,npm test(616 tests) andcheck:protocolinapp/. The app'snpm run buildstops atcheck-bundleon this machine for want of Firebase values in.env.local, which is unrelated to the diff.