From 1f918cd3002a5a3ed188d3933c2cc46e73010ace Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sun, 29 Mar 2026 22:21:40 +0200 Subject: [PATCH] fix: hide cursor during streaming output for all tools --- src/terminal/panel.rs | 5 +++++ src/terminal/pty.rs | 21 ++++++++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/terminal/panel.rs b/src/terminal/panel.rs index 898061e..8290a44 100644 --- a/src/terminal/panel.rs +++ b/src/terminal/panel.rs @@ -608,6 +608,11 @@ impl TerminalPanel { .pty .as_ref() .is_some_and(|pty| pty.should_hide_cursor_for_streaming_output()); + if hide_cursor_for_output { + // Schedule repaint so cursor reappears promptly when streaming stops + ui.ctx() + .request_repaint_after(std::time::Duration::from_millis(150)); + } if let Some(pty) = &self.pty { // Check pending mode reset: if Ctrl+C was sent while in ALT_SCREEN diff --git a/src/terminal/pty.rs b/src/terminal/pty.rs index 5a87811..5085aca 100644 --- a/src/terminal/pty.rs +++ b/src/terminal/pty.rs @@ -271,9 +271,24 @@ impl PtyHandle { } pub fn should_hide_cursor_for_streaming_output(&self) -> bool { - // Cursor is always visible — hiding it during output caused - // the cursor to flicker/disappear while the user was typing. - false + let last_input = self + .last_input_at + .lock() + .map(|t| t.elapsed()) + .unwrap_or(Duration::from_secs(999)); + let last_output = self + .last_output_at + .lock() + .map(|t| t.elapsed()) + .unwrap_or(Duration::from_secs(999)); + + // Hide cursor when output is actively streaming and the user isn't typing. + // This keeps the cursor clean during AI tool output (Codex, Claude, etc.) + // while ensuring it stays visible when the user is interacting. + let streaming = last_output < Duration::from_millis(100); + let user_idle = last_input > Duration::from_millis(150); + + streaming && user_idle } }