Skip to content

feat(client): tighter fit, configurable padding, and edge extension - #42

Merged
jesse23 merged 2 commits into
mainfrom
feat/client-padding
Sep 21, 2026
Merged

jesse23 merged 2 commits into
mainfrom
feat/client-padding

Conversation

@jesse23

@jesse23 jesse23 commented Sep 21, 2026

Copy link
Copy Markdown
Owner

Summary

Removes the visible strip around the terminal canvas and adds a way to ask for padding.

  • Tighter fit (ADR 033). The client no longer uses ghostty-web's FitAddon, which always reserves a fixed 15px for a scrollbar even though ghostty-web draws its scrollbar as an overlay inside the canvas. A small computeGrid() (src/client/fit.ts) sizes the grid from the full container, so the strip at the edges shrinks from ~16px to under one cell. This is the local version of the upstream fix already documented in ADR 022.
  • Configurable padding (ADR 034). New top-level padding (px, default 0). The top and left gaps are exactly padding; the sub-cell leftover goes to the right and bottom, like most terminal emulators. New optional theme.padding colours the space padding adds (defaults to theme.background, not sent to the terminal).
  • Edge extension (ADR 035). The leftover strip takes the edge cells' own background, by repainting the canvas' last pixel row and column across it (like Ghostty's window-padding-color = extend). Always on, no setting. Stretching rows to fill the height was rejected because fractional row heights give seams and blur.

Existing configs render as before, apart from a slightly larger grid (up to one column wider, since the reserve is gone).

Why

Full-screen TUIs that paint their own edge cells, such as a multiplexer with a darker sidebar, showed a band of the default background between the browser chrome and the app. Only theme.background was available to colour it, and it is also the terminal's default cell colour.

Notes

  • New pure helpers with unit tests: computeGrid, computeInsets (fit.ts) and computeEdgeRects (edge.ts). The DOM part of edge extension has no unit test.
  • padding is added to the /api/config whitelist and to the config parser (negative or non-numeric values fall back to 0).
  • Docs: ADRs 033 to 035, client and config SPECs, and a note in ADR 022.

Test plan

  • bun run lint clean
  • bun test: 419 pass, 0 fail
  • Manual, in Chrome with a full-screen multiplexer (herdr): left, top and bottom edges are flush or invisible after the change; measured on window captures
  • Try "padding": 8 in ~/.config/webtty/config.json and confirm 8px gaps on the top and left

🤖 Generated with Claude Code

…tension

The client no longer uses FitAddon, which always reserved a fixed 15px for a
scrollbar and left a visible strip at the edges. The grid is now sized from the
full container (ADR 033).

- New top-level `padding` config (px, default 0): the gap at the top and left
  is exactly `padding`; the sub-cell leftover goes to the right and bottom
  (ADR 034).
- New optional `theme.padding` colour for the space `padding` adds; defaults to
  `theme.background` and is not sent to the terminal.
- The leftover strip takes the edge cells' own background, by repainting the
  canvas' last pixel row and column across it, like Ghostty's
  `window-padding-color = extend` (ADR 035).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Font remeasurement can leave edge-strip geometry stale, and some documentation still describes superseded padding behavior.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 1 Medium severity · 2 Low severity

Open (3)
What changed in this PR

Replaces FitAddon with full-container grid sizing, adds configurable padding, and extends terminal edge colours into leftover space.

Changes:

  • Adds validated padding configuration and API exposure.
  • Introduces grid/inset calculations and edge-extension rendering.
  • Adds unit tests, specifications, and ADRs.
File Description
src/​server/​routes.ts Exposes padding to clients.
src/​server/​routes.test.ts Tests padding API output.
src/​config.ts Defines and parses padding settings.
src/​config.test.ts Tests padding and theme parsing.
src/​client/​index.ts Integrates fitting, padding, and edge extension.
src/​client/​fit.ts Calculates grid dimensions and insets.
src/​client/​fit.test.ts Tests fitting calculations.
src/​client/​edge.ts Implements edge-colour extension.
src/​client/​edge.test.ts Tests edge-strip geometry.
docs/​specs/​config.md Documents padding configuration.
docs/​specs/​client.md Updates client behavior specification.
docs/​adrs/​035.client.edge-extend.md Records edge-extension decision.
docs/​adrs/​034.client.padding-config.md Records padding configuration decision.
docs/​adrs/​033.client.padding-fit.md Records custom fitting decision.
docs/​adrs/​022.client.canvas-fill.md Links the superseding fit ADR.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/client/index.ts
Comment thread docs/adrs/034.client.padding-config.md Outdated
Comment thread docs/specs/client.md Outdated
…with edge extension

- document.fonts.ready remeasures the font, which changes the cell size, but
  the grid and the edge strips were only recomputed on resize. Schedule a fit
  after remeasuring so both follow the new metrics.
- ADR 034 and the client SPEC still described theme.padding colouring the
  sub-cell leftover; since ADR 035 the leftover is filled from the edge cells
  and theme.padding colours only the space `padding` adds.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@jesse23
jesse23 merged commit bab4d1e into main Sep 21, 2026
3 checks passed
@jesse23
jesse23 deleted the feat/client-padding branch September 21, 2026 13:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants