Description
When initializing a Terminal instance, a ghost cursor is rendered at the top-left corner (coordinates 0,0) in addition to the actual cursor position. This cursor persists and doesn't disappear even when the terminal receives content.
Steps to Reproduce
- Create a new Terminal instance with cursor enabled
- Call
terminal.open(container)
- Observe that a cursor appears at the top-left corner (0,0)
- The ghost cursor remains even after terminal content is rendered
Expected Behavior
Only one cursor should be visible at the actual cursor position, not at (0,0).
Actual Behavior
Two cursors are visible:
- The correct cursor at the actual position
- A ghost cursor at the top-left corner (0,0)
Root Cause Analysis
After investigating the minified source code, the issue appears to be in CanvasRenderer:
- Initialization:
lastCursorPosition is initialized to { x: 0, y: 0 } (around line 1337)
- Rendering: The cursor rendering logic at line 1561-1578 checks
g === 0 && I.visible && this.cursorVisible && this.renderCursor(I.x, I.y)
- Problem: When the cursor moves to a new position, the old position (0,0) is not properly cleared, leaving a ghost cursor
Workaround
TBD
Environment
- ghostty-web version: 0.4.0
- Browser: Chrome (tested)
- OS: macOS
Suggested Fix
The CanvasRenderer should either:
- Not render the cursor until a valid position is set
- Properly clear the initial (0,0) position when the cursor moves
- Initialize
lastCursorPosition to a sentinel value that prevents initial rendering
Description
When initializing a Terminal instance, a ghost cursor is rendered at the top-left corner (coordinates 0,0) in addition to the actual cursor position. This cursor persists and doesn't disappear even when the terminal receives content.
Steps to Reproduce
terminal.open(container)Expected Behavior
Only one cursor should be visible at the actual cursor position, not at (0,0).
Actual Behavior
Two cursors are visible:
Root Cause Analysis
After investigating the minified source code, the issue appears to be in
CanvasRenderer:lastCursorPositionis initialized to{ x: 0, y: 0 }(around line 1337)g === 0 && I.visible && this.cursorVisible && this.renderCursor(I.x, I.y)Workaround
TBD
Environment
Suggested Fix
The
CanvasRenderershould either:lastCursorPositionto a sentinel value that prevents initial rendering