Skip to content

Web UI: render a wider-than-viewport PTY without wrapping#291

Merged
edwin-zvs merged 2 commits into
mainfrom
webui-terminal-pty-width
May 31, 2026
Merged

Web UI: render a wider-than-viewport PTY without wrapping#291
edwin-zvs merged 2 commits into
mainfrom
webui-terminal-pty-width

Conversation

@edwin-zvs

Copy link
Copy Markdown
Contributor

When the TUI and web UI view the same session and the PTY width is owned by the TUI (wider than the web viewport), the web terminal wrapped the too-wide output. This renders the passive web viewer at the PTY's real column count and scrolls horizontally instead — like the TUI's pinned-tile rendering, but scroll rather than scale (per design: wrapping-only, rows untouched).

Why it needs a daemon change

The live Pty event carries only bytes — no size — and pty_resize didn't broadcast, so a passive web client never learned the owning client's width.

Changes

Daemon

  • New transient SessionEvent::PtyResize { cols, rows }, broadcast (not persisted) from SessionManager::pty_resize on an actual size change.
  • The no-op match arms a new SessionEvent variant requires (daemon summary classifier; TUI render/classify in cli).

Web UI

  • Track PTY size per session (initial from pty_replay, live from PtyResize).
  • When this terminal does not own geometry (!webPtyRecentlyEngaged()) and the PTY is wider than our fit, size xterm to the PTY cols and scroll horizontally (.terminal-host.pty-wideoverflow-x:auto) instead of wrapping; snap back to our own fit when we take over (click/type → claim). Rows left to the local fit.

⚠️ Testing — needs a daemon rebuild

Unlike the prior webui PRs, this isn't fully hot-reload-testable: the PtyResize broadcast is daemon code, so the daemon must be rebuilt + restarted. To verify:

  1. cargo build + restart the daemon; re-point webui_hot_reload at this worktree's assets.
  2. Open the same PTY session in the TUI and the web UI.
  3. In the TUI, make the terminal wider than the web viewport → the web terminal should show the full width with a horizontal scrollbar, not wrapped text.
  4. Click/type in the web terminal → it claims geometry and snaps back to its own fit.

The xterm horizontal-overflow rendering + touch pan-x are the parts to verify live (esp. on mobile). CI builds + tests the whole workspace.

🤖 Generated with Claude Code

edwin-zvs and others added 2 commits May 30, 2026 18:20
When the TUI and web UI view the same session and the PTY width is owned by
the TUI (wider than the web viewport), the web terminal wrapped the output.
Now the passive web viewer renders at the PTY's real column count and scrolls
horizontally instead.

Daemon:
- add transient SessionEvent::PtyResize { cols, rows }, broadcast (not
  persisted) from SessionManager::pty_resize on an actual size change, so
  attached clients learn the live geometry. The Pty stream carried no size,
  so a passive web client never knew the owning client's width.
- add the no-op match arms a new SessionEvent variant requires (daemon
  summary classifier, TUI render/classify paths).

Web UI:
- track PTY size per session (initial from pty_replay, live from PtyResize);
  when this terminal does NOT own geometry and the PTY is wider than our fit,
  size xterm to the PTY cols and scroll horizontally (.pty-wide / overflow-x)
  instead of wrapping; snap back to our own fit when we take over. Rows are
  left to the local fit (wrapping-only, per design).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Capture the cross-client decision behind this PR: a viewer whose viewport is
narrower than the owning client's PTY geometry renders the terminal at the
session's true column count and scrolls horizontally, rather than reflowing
the output to its own width — and learns live geometry from a broadcast
resize signal, not just at attach.
@edwin-zvs
edwin-zvs merged commit a438329 into main May 31, 2026
1 check passed
@edwin-zvs
edwin-zvs deleted the webui-terminal-pty-width branch May 31, 2026 01:50
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.

1 participant