From 21fd121a63db53ff44b947bbe38c47bbf35e632c Mon Sep 17 00:00:00 2001 From: JJ Liebig Date: Wed, 23 Sep 2026 20:39:01 +0200 Subject: fix: prevent cursor flicker on status redraw (#4554) * fix: prevent cursor flicker on status redraw * fix: avoid stale cursor during resize --- src/pane/terminal.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'src/pane/terminal.rs') diff --git a/src/pane/terminal.rs b/src/pane/terminal.rs index e2005a8f..66c23c26 100644 --- a/src/pane/terminal.rs +++ b/src/pane/terminal.rs @@ -4414,6 +4414,36 @@ mod tests { ); } + #[test] + #[cfg(windows)] + fn cursor_state_holds_brief_pty_hide_and_schedules_sustained_hide() { + let (tx, _rx) = mpsc::channel(4); + let terminal = crate::ghostty::Terminal::new(80, 24, 0).unwrap(); + let pane = GhosttyPaneTerminal::new(terminal, tx.clone()).unwrap(); + let pane_id = PaneId::from_raw(1); + pane.process_pty_bytes(pane_id, 0, b"\x1b[15;4H", &tx); + { + let mut core = pane.core.lock().unwrap(); + let current = current_cursor_state(&mut core); + core.cursor_settle_state = CursorPositionSettleState::default(); + core.cursor_settle_state.observe(current, Instant::now()); + } + + let result = pane.process_pty_bytes(pane_id, 0, b"\x1b[?25l", &tx); + assert!(result.request_render); + assert_eq!(result.render_delay, Some(Duration::from_millis(100))); + assert!(pane.cursor_state().is_some_and(|cursor| cursor.visible)); + let mut core = pane.core.lock().unwrap(); + let current = current_cursor_state(&mut core); + assert!( + !core + .cursor_settle_state + .reported_cursor(current, Instant::now() + result.render_delay.unwrap()) + .unwrap() + .visible + ); + } + #[test] #[cfg(windows)] fn cursor_settle_ignores_intermediate_synchronized_frame_positions() { -- cgit v1.2.3