Skip to content

fix(frontend): stop fit loop committing transient cell-box mis-measurements (#313)#316

Merged
harshitsinghbhandari merged 1 commit into
mainfrom
fix/codex-orchestrator-clipped-313
Jun 18, 2026
Merged

fix(frontend): stop fit loop committing transient cell-box mis-measurements (#313)#316
harshitsinghbhandari merged 1 commit into
mainfrom
fix/codex-orchestrator-clipped-313

Conversation

@harshitsinghbhandari

Copy link
Copy Markdown
Collaborator

What

Fixes the badly-clipped Codex orchestrator terminal reported in #313: the grid renders at roughly half width and a fraction of the pane height, with a ghosted/duplicated composer.

Why

#312 added an onRender convergence loop to XtermTerminal that recovered the under-counted rows from #280. But comparing the screenshots:

FitAddon.proposeDimensions() derives the grid by dividing the host box by the renderer's measured css.cell box (verified in the installed addon source). During the WebGL atlas warm-up that cell box can emit a one-frame transient — on a HiDPI display (the report is DPR 2) a briefly-doubled box halves the proposed cols/rows. The convergence loop committed that single frame's proposal, resized the grid to half, then detached after a few "stable" frames. With the loop detached and the grid stuck, nothing re-fired the PTY resize that makes zellij repaint, so the half-size grid froze and the stale composer was never cleared.

How

  • Two-frame confirmation: a differing proposal must repeat identically across two consecutive renders before it is applied. A one-frame transient now only updates a pending value and is never committed.
  • Late settle backstop: added 600ms/1200ms fits alongside the existing 50/250ms. By then the atlas and font metrics are unambiguously warm, so even if the loop detached at a briefly-stable wrong measurement, a late re-measure corrects the grid and fires the resize zellij needs to repaint cleanly. fit() is idempotent, so a correctly-sized terminal never reflows.

Testing

  • npm run typecheck — clean
  • npm test — 140 passed (15 files)

Backend untouched, so the Go gate was skipped.

Fixes #313

🤖 Generated with Claude Code

…ements (#313)

The onRender convergence loop added in #312 recovered the under-counted
rows from #280, but on a HiDPI display it could lock the Codex
orchestrator terminal at half size with a ghosted composer (#313).

FitAddon derives the grid by dividing the pane box by the renderer's
measured css cell box. During the WebGL atlas warm-up that cell box can
emit a one-frame transient (a doubled box on a 2x display), which halves
the proposed cols/rows. The loop committed that single frame's proposal,
resized the grid to half, then detached after a few "stable" frames — so
nothing re-fired the PTY resize that makes zellij repaint, leaving the
grid stuck at half width and the stale composer un-cleared.

Require a differing proposal to repeat identically across two consecutive
renders before applying it, so a one-frame transient only updates the
pending value and is never committed. Add 600ms/1200ms settle fits as a
session-bounded backstop: by then the atlas and font metrics are warm, so
even if the loop detached at a briefly-stable wrong measurement, a late
re-measure corrects the grid and fires the resize zellij needs to repaint
cleanly. fit() is idempotent, so a correct terminal never reflows.

Fixes #313

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@harshitsinghbhandari harshitsinghbhandari merged commit 93123ed into main Jun 18, 2026
3 checks passed
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.

Codex orchestrator is very badly cclipped

1 participant