fix(terminal): resolve blank terminals after project switch#1836
fix(terminal): resolve blank terminals after project switch#1836
Conversation
Force SIGWINCH on same-dimension resize and skip stale buffer replay for Claude-mode terminals during project switch remount. Two compounding issues caused blank terminals when switching projects: 1. On macOS/Linux, ioctl(TIOCSWINSZ) only sends SIGWINCH when dimensions actually change. After project switch, PTY persists with old dimensions and the terminal remounts at the same size, so TUI apps never get SIGWINCH and never redraw. Fix: resize to (cols-1, rows) first, then to (cols, rows) to force the signal. 2. Buffer replay concatenated serialized xterm state with raw PTY output accumulated during the unmount period, producing garbled display. Fix: skip buffer replay for Claude-mode terminals on project switch remount (the forced SIGWINCH makes Claude Code redraw its full TUI). Initial restore still replays the buffer as a loading preview. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary of ChangesHello @AndyMik90, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request resolves critical issues where terminals, especially those running Claude Code, appeared blank or displayed garbled content after switching projects. The changes ensure that terminal applications correctly redraw by forcing a Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
📝 WalkthroughWalkthroughThese changes address terminal behavior issues: forcing SIGWINCH signals when PTY resize dimensions remain unchanged, and conditionally skipping buffered output replay when terminals operate in Claude mode (excluding initial restore scenarios). Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
No actionable comments were generated in the recent review. 🎉 Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request effectively addresses a significant issue causing blank terminals after a project switch. The solution is well-thought-out, employing a two-part fix: forcing a SIGWINCH signal to trigger a redraw in TUI applications, and intelligently skipping stale buffer replays in Claude-mode terminals to prevent garbled displays. The code is clear and the accompanying comments are very helpful. I have one minor suggestion to enhance code robustness.
| // For initial restore (isRestored=true), we DO replay to show the saved state | ||
| // as a loading preview while claude --continue starts. | ||
| const terminal = useTerminalStore.getState().terminals.find(t => t.id === terminalId); | ||
| const isClaudeActive = terminal?.isClaudeMode || terminal?.pendingClaudeResume; |
There was a problem hiding this comment.
While the current logic works due to JavaScript's truthiness rules, explicitly converting the result to a boolean with !! would make the code more robust and the intent clearer. This ensures isClaudeActive is always a boolean and doesn't rely on the falsiness of undefined if terminal.isClaudeMode is false and terminal.pendingClaudeResume is undefined.
| const isClaudeActive = terminal?.isClaudeMode || terminal?.pendingClaudeResume; | |
| const isClaudeActive = !!(terminal?.isClaudeMode || terminal?.pendingClaudeResume); |
AndyMik90
left a comment
There was a problem hiding this comment.
✅ Auto Claude Review - APPROVED
Status: Ready to Merge
Summary: ### Merge Verdict: ✅ READY TO MERGE
✅ Ready to merge - All checks passing, no blocking issues found.
No blocking issues found
Risk Assessment
| Factor | Level | Notes |
|---|---|---|
| Complexity | Low | Based on lines changed |
| Security Impact | None | Based on security findings |
| Scope Coherence | Good | Based on structural review |
Generated by Auto Claude PR Review
This automated review found no blocking issues. The PR can be safely merged.
Generated by Auto Claude
Summary
claude --continuestartsProblem
When switching between projects, terminals appeared completely blank (black screen) even though Claude Code was running in the background. Two compounding root causes:
No SIGWINCH on same-dimension resize: On macOS/Linux,
ioctl(TIOCSWINSZ)only sends SIGWINCH when dimensions actually change. After project switch, the PTY persists with old dimensions and the terminal remounts at the same size, so TUI apps never receive SIGWINCH and never redraw.Stale buffer replay: The serialized xterm buffer was concatenated with raw PTY output accumulated during the unmount period, producing garbled display instead of a clean terminal.
Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit