Skip to content

fix: prevent tmux flicker on restart by matching existing window size#80

Merged
Ark0N merged 1 commit into
Ark0N:masterfrom
aakhter:fix/tmux-size-match
May 11, 2026
Merged

fix: prevent tmux flicker on restart by matching existing window size#80
Ark0N merged 1 commit into
Ark0N:masterfrom
aakhter:fix/tmux-size-match

Conversation

@aakhter
Copy link
Copy Markdown
Contributor

@aakhter aakhter commented May 11, 2026

Summary

When a PTY client re-attaches to an existing tmux session, the PTY size is hardcoded to 120x40, so tmux resizes the window to match the smaller dimensions. The xterm.js client then immediately resizes back to its actual viewport on the next render tick — every restart causes a visible flicker and loses one repaint of scrollback content.

Two small changes fix this:

  • src/session.ts — query the existing tmux window size via tmux display -t <muxName> -p '#{window_width} #{window_height}' before pty.spawn, fall back to 120x40 only if the call fails.
  • src/tmux-manager.ts — drop the hardcoded -x 120 -y 40 from tmux new-session so the initial size matches the first attaching client.

execFileSync is used (not execSync) so the muxName isn't shell-interpolated.

Test plan

  • Start a session, wait for buffer to fill (>40 rows of output).
  • Hard-reload the page (Ctrl+Shift+R).
  • Observe: no flicker, no buffer truncation.
  • Restart with a non-default xterm size (e.g. wide window): on attach the PTY/tmux are sized to match.
  • Kill tmux mid-attach (corner case): falls back to 120x40 gracefully (catch block in the try { execFileSync … }).

🤖 Generated with Claude Code

When a PTY client re-attaches to an existing tmux session, it currently
hardcodes the PTY size to 120x40 and tmux resizes the window to match.
The xterm.js client then resizes back to its actual viewport on the
next render tick, so every restart causes a visible flicker and loses
one repaint of buffer content.

Also remove the hardcoded `-x 120 -y 40` from `tmux new-session` so
initial size adapts to the first client.

Changes:
- session.ts: query existing window size via `tmux display -p
  #{window_width} #{window_height}` before pty.spawn, fall back to
  120x40 only if tmux is unreachable.
- tmux-manager.ts: drop -x/-y from new-session args.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Ark0N Ark0N merged commit eecf74c into Ark0N:master May 11, 2026
1 check passed
@Ark0N
Copy link
Copy Markdown
Owner

Ark0N commented May 11, 2026

Thanks for the fix! Querying the existing tmux size before attach is exactly the right shape, and the execFileSync + bounded fallback is a nice touch. Merged.

Ark0N added a commit that referenced this pull request May 12, 2026
Backfill the two regression gaps flagged on master after the recent
hostname-title and tmux-flicker fixes shipped without server-side
assertions.

* test/server-index-title.test.ts (8 tests) — exercises WebServer's
  index.html templating path: default os.hostname(), --title-hostname
  override, HTML-escape against `<script>`-style breakout, ampersand
  non-double-encoding, exact-once substitution, and byte-identical
  template-tail invariance.

* test/tmux-window-size-query.test.ts (15 tests) — mocks
  child_process.execFileSync and walks the helper through the
  browser-resize-between-attaches happy path, query-then-die race,
  zero/negative/empty/non-numeric output, plus argv-form/timeout
  assertions to lock down the no-shell-interpolation guarantee.

* src/session.ts — extracts the inline 14-line tmux size query into
  a named `queryTmuxWindowSize()` export so the test surface is a
  pure function. Behavior unchanged.

* src/web/public/notification-manager.js — Browser Notification API
  (layer 3) now uses `${this.originalTitle}: ${title}` so OS-level
  desktop pop-ups carry the same `codeman:<host>` prefix that the
  tab title and Web Push payloads already do, finishing the
  hostname plumb-through started in #82.

* CLAUDE.md, README.md — document the dual-CLI env-prefix discipline
  (CLAUDE_CODE_* vs OPENCODE_*), expand the xterm-zerolag-input
  duplication gotcha to mention the published-package side-effect,
  and note that the hostname prefix now applies uniformly to tab
  title, tab-flash, and OS notifications.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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