fix(terminal): sync PTY dimensions after restore to prevent autocomplete issues#909
Conversation
📝 WalkthroughWalkthroughThis change adds an Changes
Sequence Diagram(s)sequenceDiagram
participant Terminal as Terminal Component
participant Hook as useTerminalRestore
participant Xterm as xterm (fit)
participant Resizer as resizeRef / PTY
Terminal->>Hook: initiate restore
Hook->>Xterm: call fit()
Xterm-->>Hook: updated cols, rows
Hook->>Terminal: invoke onResize(cols, rows)
Terminal->>Resizer: resizeRef.current({ paneId, cols, rows })
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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 |
54028b5 to
b3ca1ce
Compare
…ete issues
When a terminal is attached/restored, createOrAttach was called with
dimensions from an initial fitAddon.fit() that ran before the container
was fully laid out by CSS. This caused a ~140ms window where the PTY had
incorrect dimensions, leading to:
- zsh autocomplete overwriting lines
- Weird positioning when reattaching terminals
The fix sends a resize to the PTY immediately after fit() completes in
scheduleFitAndScroll, ensuring dimensions are synced before any user
interaction.
Also fixes scroll-to-bottom timing by ensuring all pending xterm writes
are processed before scrolling. xterm.write() is async and buffers writes,
so scrollToBottom() called immediately might not see all content.
Also fixes unexpected scroll-to-bottom when switching tabs - now only
scrolls to bottom for new sessions, not reattached ones, preserving the
user's scroll position.
- Add onResize callback to useTerminalRestore hook
- Call onResize after fitAddon.fit() in scheduleFitAndScroll
- Use xterm.write('', callback) to flush writes before scrolling
- Only scroll to bottom for new sessions (result.isNew)
b3ca1ce to
2cf84a1
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In
`@apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/hooks/useTerminalRestore.ts`:
- Around line 24-25: The onResize callback currently uses positional parameters
(cols: number, rows: number); change its signature to accept a single params
object { cols: number; rows: number } and update all call sites accordingly:
update the type/definition in useTerminalRestore.ts (onResize), change the
invocation inside useTerminalRestore (where onResize(...) is called) to pass an
object { cols, rows }, update the provider callback prop passed from
Terminal.tsx (where you supply onResize) to accept and forward an object, and
update the helper in helpers.ts (both its function signature and any internal
calls) to use and propagate { cols, rows } instead of positional args so all
usages conform to the object-params guideline.
| /** Callback to send resize to PTY after fit() - ensures PTY dimensions match xterm */ | ||
| onResize: (cols: number, rows: number) => void; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, verify the file exists and examine its content
cat -n apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/hooks/useTerminalRestore.tsRepository: superset-sh/superset
Length of output: 10639
🏁 Script executed:
# Search for all onResize usages across the codebase
rg -n 'onResize' --type ts --type tsx -B 2 -A 2Repository: superset-sh/superset
Length of output: 91
🏁 Script executed:
# Search for all onResize usages with corrected rg syntax
rg 'onResize' --type ts -B 2 -A 2Repository: superset-sh/superset
Length of output: 10561
🏁 Script executed:
# Search for useTerminalRestore usage to find where onResize callback is provided
rg 'useTerminalRestore' --type ts -B 2 -A 5Repository: superset-sh/superset
Length of output: 4728
🏁 Script executed:
# Get context around Terminal.tsx onResize usage to see full implementation
rg -n 'onResize:' apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx -B 5 -A 1Repository: superset-sh/superset
Length of output: 436
🏁 Script executed:
# Get helpers.ts function signature for onResize to understand full context
cat apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts | head -50Repository: superset-sh/superset
Length of output: 2235
Use a params object for onResize to follow the object-params guideline.
The callback uses positional parameters (cols: number, rows: number) which conflicts with the coding guideline requiring object parameters for functions with 2+ parameters. Refactor to use { cols, rows } for clarity and consistency.
This requires coordinated updates across the Terminal module:
- Interface definition in
useTerminalRestore.ts(line 25) - Invocation in
useTerminalRestore.ts(line 130) - Provider callback in
Terminal.tsx(line 192) - Function signature and call site in
helpers.ts
♻️ Proposed refactor
- onResize: (cols: number, rows: number) => void;
+ onResize: (params: { cols: number; rows: number }) => void;- onResizeRef.current(xterm.cols, xterm.rows);
+ onResizeRef.current({ cols: xterm.cols, rows: xterm.rows });📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| /** Callback to send resize to PTY after fit() - ensures PTY dimensions match xterm */ | |
| onResize: (cols: number, rows: number) => void; | |
| /** Callback to send resize to PTY after fit() - ensures PTY dimensions match xterm */ | |
| onResize: (params: { cols: number; rows: number }) => void; |
🤖 Prompt for AI Agents
In
`@apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/hooks/useTerminalRestore.ts`
around lines 24 - 25, The onResize callback currently uses positional parameters
(cols: number, rows: number); change its signature to accept a single params
object { cols: number; rows: number } and update all call sites accordingly:
update the type/definition in useTerminalRestore.ts (onResize), change the
invocation inside useTerminalRestore (where onResize(...) is called) to pass an
object { cols, rows }, update the provider callback prop passed from
Terminal.tsx (where you supply onResize) to accept and forward an object, and
update the helper in helpers.ts (both its function signature and any internal
calls) to use and propagate { cols, rows } instead of positional args so all
usages conform to the object-params guideline.
🧹 Preview Cleanup CompleteThe following preview resources have been cleaned up:
Thank you for your contribution! 🎉 |
Problem
Terminal autocomplete from zsh was overwriting lines and there were positioning issues when reattaching terminals.
Root Cause
When a terminal was attached/restored,
createOrAttachwas called with dimensions from an initialfitAddon.fit()that ran before the container was fully laid out by CSS. This resulted in wrong dimensions (e.g., 70 cols) being sent to the PTY.After the terminal rendered, the ResizeObserver would eventually send the correct dimensions (e.g., 74 cols), but there was a ~140ms window where the PTY had incorrect dimensions. During this window, shell operations (prompts, autocomplete) would use wrong column counts, causing line wrapping issues.
Fix
Added an immediate resize call in
scheduleFitAndScroll(inuseTerminalRestore.ts) that sends the correct dimensions to the PTY right afterfitAddon.fit()completes during restore. This ensures the PTY dimensions are synced with xterm.js dimensions before any user interaction can occur.Changes
onResizecallback parameter to theuseTerminalRestorehookonResizeafterfitAddon.fit()inscheduleFitAndScrollSummary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.