From ecd5fe1aa13cd8c53f5c0a85dc7ae33be4370253 Mon Sep 17 00:00:00 2001 From: Anand Dyavanapalli Date: Wed, 11 Mar 2026 15:16:24 -0400 Subject: [PATCH] fix: disable mouse tracking before restoring cooked mode in finalizeDestroy When the renderer is destroyed, setRawMode(false) was called before mouse tracking was disabled. Any mouse movement in that window generates SGR escape sequences that the terminal echoes as garbage text (e.g. '35;80;40M') on the user's shell prompt. Call disableMouse() before setRawMode(false), matching the ordering already used in suspend(). --- packages/core/src/renderer.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/core/src/renderer.ts b/packages/core/src/renderer.ts index d0ca2841c5..036b868c72 100644 --- a/packages/core/src/renderer.ts +++ b/packages/core/src/renderer.ts @@ -1930,7 +1930,14 @@ export class CliRenderer extends EventEmitter implements RenderContext { console.error("Error destroying root renderable:", e instanceof Error ? e.stack : String(e)) } - // Remove listener before destroying parser + // Disable mouse tracking while still in raw mode so the terminal stops + // generating SGR mouse events before we restore cooked mode. Without this, + // any mouse movement between setRawMode(false) and destroyRenderer() leaks + // partial escape sequences (e.g. "35;80;40M") onto the user's shell prompt. + if (this._useMouse) { + this.disableMouse() + } + this.stdin.removeListener("data", this.stdinListener) if (this.stdin.setRawMode) { this.stdin.setRawMode(false)