Fix terminal restoration and TUI redraws#336
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 834150428f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const terminal = this.terminals.get(panelId); | ||
| if (!terminal) return null; | ||
|
|
||
| await terminal.screenEmulator?.waitForIdle(); |
There was a problem hiding this comment.
Bound terminal-state idle waits
When a live panel is running high-volume or continuous output, this unbounded waitForIdle() can stay pending because each PTY chunk increments the emulator's pending-write count and the promise only resolves after it reaches zero. This path backs terminal:getState during renderer remount/activation and is also used by runpane panels screen/wait, so commands like yes, a long build, or a log tail can leave the terminal refresh/loading path and local-control commands hanging until output stops. Consider taking the best current snapshot after a short timeout instead of waiting indefinitely.
Useful? React with 👍 / 👎.
Summary
Fixes #324.
Why
Pane disposes renderer-side xterm/WebGL resources when a top-level session unmounts while keeping its PTY alive. Reconstructing only from normal scrollback restored the wrong buffer for full-screen and cursor-addressed applications. Even after restoring the correct cells, Claude's TUI could retain a frame computed for the previous renderer geometry until a real window resize delivered a resize notification.
The main process now owns an xterm-compatible screen model. Renderer activation restores that authoritative state, then performs a real PTY size transition and return so the foreground application redraws at the settled dimensions.
runpane panels screenreads the same model and no longer sees the launch command in place of the agent screen.Testing
pnpm lint(passes; existing warning baseline only)pnpm typecheckpnpm --filter main test -- --run(41 files, 339 tests)pnpm --filter frontend test(8 files, 93 tests)pnpm build:frontendpnpm build:mainpnpm --filter runpane buildPANE_DIR; switching panes and tabs now restores and redraws correctly without a physical window resizeDependency Notes
@xterm/headlessand@xterm/addon-serializeto the main processNOTICES