Skip to content

fix(terminal): write PTY output live and de-overlap reattach restores#1527

Open
Jinwoo-H wants to merge 1 commit intomainfrom
Jinwoo-H/terminal-output-issue
Open

fix(terminal): write PTY output live and de-overlap reattach restores#1527
Jinwoo-H wants to merge 1 commit intomainfrom
Jinwoo-H/terminal-output-issue

Conversation

@Jinwoo-H
Copy link
Copy Markdown
Contributor

@Jinwoo-H Jinwoo-H commented May 7, 2026

Eliminates the duplicated-TUI-output and broken-wide-char glyph artifacts that appeared when switching to a worktree after leaving it for a while.

RC build

Pre-built artifacts for testing this PR: v1.3.38-rc.1

Two structural fixes

1. Single-source restore on reattach

handleReattachResult now enforces strict precedence (snapshot > replay > coldRestore) and paints exactly one source per reattach. Painting both daemon snapshot and relay replay doubled the same lines because their tails overlap. Snapshot/replay still ack any superseded coldRestore so the daemon does not redeliver.

2. Always-live xterm writes

PTY output now flows straight into xterm regardless of pane visibility. The visibility-gated buffer (pendingWritesRef + chunked drain + fit-epoch dedup) was the source of the cursor-on-strange-line and broken-glyph bugs: bytes accumulated while hidden then flushed into xterm at stale cols on resume, before fitAllPanes() could correct the dimensions. The visibility prop now only controls WebGL suspend/resume (GPU resource management).

Unicode-11 ordering

Adds an inline comment at openTerminal() pinning Unicode 11 activation before any caller-driven write — wide-char widths bake into the buffer at the active unicode version, so writing into a v6-default xterm corrupts CJK/emoji/ZWJ layouts.

New regression tests

  • snapshot wins over replay when both present
  • replay wins over coldRestore (and still acks)
  • Unicode-11 ordering: open → loadAddon:unicode11 → activeVersion=11 → write
  • live writes regardless of visibility prop

Made with Orca 🐋

Eliminates the duplicated-TUI-output and broken-wide-char glyph artifacts
that appeared when switching to a worktree after leaving it for a while.

Two structural fixes:

1. Single-source restore on reattach. handleReattachResult now enforces
   strict precedence (snapshot > replay > coldRestore) and paints exactly
   one source per reattach. Painting both daemon snapshot and relay replay
   doubled the same lines because their tails overlap. Snapshot/replay
   still ack any superseded coldRestore so the daemon does not redeliver.

2. Always-live xterm writes. PTY output now flows straight into xterm
   regardless of pane visibility. The visibility-gated buffer
   (pendingWritesRef + chunked drain + fit-epoch dedup) was the source
   of the cursor-on-strange-line and broken-glyph bugs: bytes accumulated
   while hidden then flushed into xterm at stale cols on resume, before
   fitAllPanes() could correct the dimensions. The visibility prop now
   only controls WebGL suspend/resume (GPU resource management).

Also adds an inline comment at openTerminal() pinning Unicode 11
activation before any caller-driven write — wide-char widths bake into
the buffer at the active unicode version, so writing into a v6-default
xterm corrupts CJK/emoji/ZWJ layouts.

New regression tests:
- snapshot wins over replay when both present
- replay wins over coldRestore (and still acks)
- Unicode-11 ordering: open → loadAddon:unicode11 → activeVersion=11 → write
- live writes regardless of visibility prop

Co-authored-by: Orca <help@stably.ai>
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