From cbbdccc285d78974b55079112c1cfbc52215bea5 Mon Sep 17 00:00:00 2001 From: Aram Drevekenin Date: Thu, 14 Jul 2022 11:55:07 +0200 Subject: [PATCH] fix(terminal): persist cursor hide/show through alternate screen (#1586) * fix(terminal): persist cursor hide/show through alternate screen * style(fmt): rustfmt * style(clippy): make clippy happy --- zellij-server/src/panes/grid.rs | 8 +-- zellij-server/src/panes/terminal_character.rs | 2 - zellij-server/src/panes/unit/grid_tests.rs | 51 +++++++++++++++++++ 3 files changed, 56 insertions(+), 5 deletions(-) diff --git a/zellij-server/src/panes/grid.rs b/zellij-server/src/panes/grid.rs index 8c6e3e09..aef67f98 100644 --- a/zellij-server/src/panes/grid.rs +++ b/zellij-server/src/panes/grid.rs @@ -305,6 +305,7 @@ pub struct Grid { horizontal_tabstops: BTreeSet, alternate_screen_state: Option, cursor: Cursor, + cursor_is_hidden: bool, saved_cursor_position: Option, // FIXME: change scroll_region to be (usize, usize) - where the top line is always the first // line of the viewport and the bottom line the last unless it's changed with CSI r and friends @@ -408,6 +409,7 @@ impl Grid { lines_below: vec![], horizontal_tabstops: create_horizontal_tabstops(columns), cursor: Cursor::new(0, 0), + cursor_is_hidden: false, saved_cursor_position: None, scroll_region: None, preceding_char: None, @@ -898,7 +900,7 @@ impl Grid { (changed_character_chunks, changed_sixel_image_chunks) } pub fn cursor_coordinates(&self) -> Option<(usize, usize)> { - if self.cursor.is_hidden { + if self.cursor_is_hidden { None } else { Some((self.cursor.x, self.cursor.y)) @@ -1309,10 +1311,10 @@ impl Grid { } } pub fn hide_cursor(&mut self) { - self.cursor.is_hidden = true; + self.cursor_is_hidden = true; } pub fn show_cursor(&mut self) { - self.cursor.is_hidden = false; + self.cursor_is_hidden = false; } pub fn set_scroll_region(&mut self, top_line_index: usize, bottom_line_index: Option) { let bottom_line_index = bottom_line_index.unwrap_or(self.height); diff --git a/zellij-server/src/panes/terminal_character.rs b/zellij-server/src/panes/terminal_character.rs index 2e4b4e35..3d18df55 100644 --- a/zellij-server/src/panes/terminal_character.rs +++ b/zellij-server/src/panes/terminal_character.rs @@ -672,7 +672,6 @@ pub enum CursorShape { pub struct Cursor { pub x: usize, pub y: usize, - pub is_hidden: bool, pub pending_styles: CharacterStyles, pub charsets: Charsets, shape: CursorShape, @@ -683,7 +682,6 @@ impl Cursor { Cursor { x, y, - is_hidden: false, pending_styles: RESET_STYLES, charsets: Default::default(), shape: CursorShape::Initial, diff --git a/zellij-server/src/panes/unit/grid_tests.rs b/zellij-server/src/panes/unit/grid_tests.rs index 42e7ff36..66f0773f 100644 --- a/zellij-server/src/panes/unit/grid_tests.rs +++ b/zellij-server/src/panes/unit/grid_tests.rs @@ -2513,3 +2513,54 @@ pub fn xtsmgraphics_pixel_graphics_geometry() { }); assert_eq!(message_string, "\u{1b}[?2;0;776;1071S"); } + +#[test] +pub fn cursor_hide_persists_through_alternate_screen() { + let mut vte_parser = vte::Parser::new(); + let sixel_image_store = Rc::new(RefCell::new(SixelImageStore::default())); + let terminal_emulator_color_codes = Rc::new(RefCell::new(HashMap::new())); + let character_cell_size = Rc::new(RefCell::new(Some(SizeInPixels { + width: 8, + height: 21, + }))); + let mut grid = Grid::new( + 30, + 112, + Rc::new(RefCell::new(Palette::default())), + terminal_emulator_color_codes, + Rc::new(RefCell::new(LinkHandler::new())), + character_cell_size, + sixel_image_store, + ); + + let hide_cursor = "\u{1b}[?25l"; + for byte in hide_cursor.as_bytes() { + vte_parser.advance(&mut grid, *byte); + } + assert_eq!(grid.cursor_coordinates(), None, "Cursor hidden properly"); + + let move_to_alternate_screen = "\u{1b}[?1049h"; + for byte in move_to_alternate_screen.as_bytes() { + vte_parser.advance(&mut grid, *byte); + } + assert_eq!( + grid.cursor_coordinates(), + None, + "Cursor still hidden in alternate screen" + ); + + let show_cursor = "\u{1b}[?25h"; + for byte in show_cursor.as_bytes() { + vte_parser.advance(&mut grid, *byte); + } + assert!(grid.cursor_coordinates().is_some(), "Cursor shown"); + + let move_away_from_alternate_screen = "\u{1b}[?1049l"; + for byte in move_away_from_alternate_screen.as_bytes() { + vte_parser.advance(&mut grid, *byte); + } + assert!( + grid.cursor_coordinates().is_some(), + "Cursor still shown away from alternate screen" + ); +}