Web UI: render a wider-than-viewport PTY without wrapping#291
Merged
Conversation
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.
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.
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
Ptyevent carries only bytes — no size — andpty_resizedidn't broadcast, so a passive web client never learned the owning client's width.Changes
Daemon
SessionEvent::PtyResize { cols, rows }, broadcast (not persisted) fromSessionManager::pty_resizeon an actual size change.matcharms a newSessionEventvariant requires (daemon summary classifier; TUI render/classify incli).Web UI
pty_replay, live fromPtyResize).!webPtyRecentlyEngaged()) and the PTY is wider than our fit, size xterm to the PTY cols and scroll horizontally (.terminal-host.pty-wide→overflow-x:auto) instead of wrapping; snap back to our own fit when we take over (click/type → claim). Rows left to the local fit.Unlike the prior webui PRs, this isn't fully hot-reload-testable: the
PtyResizebroadcast is daemon code, so the daemon must be rebuilt + restarted. To verify:cargo build+ restart the daemon; re-pointwebui_hot_reloadat this worktree's assets.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