aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Linford <tlinford@users.noreply.github.com>2022-02-02 12:56:21 +0100
committerGitHub <noreply@github.com>2022-02-02 12:56:21 +0100
commit143bbfb0bbf5e5dcedf49d8ecef3ecf3536586b3 (patch)
tree76c709b086fe35259612b754682f760b90d5dd8b
parentdocs(changelog): add focus attribute in layout (diff)
downloadsl0ppij-143bbfb0bbf5e5dcedf49d8ecef3ecf3536586b3.tar.gz
sl0ppij-143bbfb0bbf5e5dcedf49d8ecef3ecf3536586b3.tar.xz
sl0ppij-143bbfb0bbf5e5dcedf49d8ecef3ecf3536586b3.zip
fix(compatibility): do not set scroll buffer in alternate screen (#1032)
avoid moving lines to lines_above when in alternate screen. adjust resizing when in alternate screen: * remove extra lines instead of sending to lines_above * truncate excess characters
-rw-r--r--src/tests/fixtures/alternate_screen_change_size21
-rw-r--r--zellij-server/src/panes/grid.rs120
-rw-r--r--zellij-server/src/panes/unit/grid_tests.rs16
-rw-r--r--zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__alternate_screen_change_size.snap16
4 files changed, 117 insertions, 56 deletions
diff --git a/src/tests/fixtures/alternate_screen_change_size b/src/tests/fixtures/alternate_screen_change_size
new file mode 100644
index 00000000..3be19903
--- /dev/null
+++ b/src/tests/fixtures/alternate_screen_change_size
@@ -0,0 +1,21 @@
+[?1049hline1aaaaaaaaaaaaaaa
+line2aaaaaaaaaaaaaaa
+line3aaaaaaaaaaaaaaa
+line4aaaaaaaaaaaaaaa
+line5aaaaaaaaaaaaaaa
+line6aaaaaaaaaaaaaaa
+line7aaaaaaaaaaaaaaa
+line8aaaaaaaaaaaaaaa
+line9aaaaaaaaaaaaaaa
+line10aaaaaaaaaaaaaa
+line11aaaaaaaaaaaaaa
+line12aaaaaaaaaaaaaa
+line13aaaaaaaaaaaaaa
+line14aaaaaaaaaaaaaa
+line15aaaaaaaaaaaaaa
+line16aaaaaaaaaaaaaa
+line17aaaaaaaaaaaaaa
+line18aaaaaaaaaaaaaa
+line19a🦀aaaaaaaaaaa
+line20a🦀🦀aaaaaaaaa
+line21🦀🦀🦀🦀🦀🦀🦀 \ No newline at end of file
diff --git a/zellij-server/src/panes/grid.rs b/zellij-server/src/panes/grid.rs
index bd898aa6..8669cfe6 100644
--- a/zellij-server/src/panes/grid.rs
+++ b/zellij-server/src/panes/grid.rs
@@ -374,7 +374,7 @@ pub struct Grid {
viewport: Vec<Row>,
lines_below: Vec<Row>,
horizontal_tabstops: BTreeSet<usize>,
- alternative_lines_above_viewport_and_cursor: Option<(VecDeque<Row>, Vec<Row>, Cursor)>,
+ alternate_lines_above_viewport_and_cursor: Option<(VecDeque<Row>, Vec<Row>, Cursor)>,
cursor: Cursor,
saved_cursor_position: Option<Cursor>,
// FIXME: change scroll_region to be (usize, usize) - where the top line is always the first
@@ -442,7 +442,7 @@ impl Grid {
erasure_mode: false,
insert_mode: false,
disable_linewrap: false,
- alternative_lines_above_viewport_and_cursor: None,
+ alternate_lines_above_viewport_and_cursor: None,
clear_viewport_before_rendering: false,
active_charset: Default::default(),
pending_messages_to_pty: vec![],
@@ -673,7 +673,7 @@ impl Grid {
return;
}
self.selection.reset();
- if new_columns != self.width {
+ if new_columns != self.width && self.alternate_lines_above_viewport_and_cursor.is_none() {
self.horizontal_tabstops = create_horizontal_tabstops(new_columns);
let mut cursor_canonical_line_index = self.cursor_canonical_line_index();
let cursor_index_in_canonical_line = self.cursor_index_in_canonical_line();
@@ -786,6 +786,16 @@ impl Grid {
}
self.cursor.y = new_cursor_y;
self.cursor.x = new_cursor_x;
+ } else if new_columns != self.width
+ && self.alternate_lines_above_viewport_and_cursor.is_some()
+ {
+ // in alternate screen just truncate exceeding width
+ for row in &mut self.viewport {
+ if row.width() >= new_columns {
+ let truncate_at = row.position_accounting_for_widechars(new_columns);
+ row.columns.truncate(truncate_at);
+ }
+ }
}
if new_rows != self.height {
let current_viewport_row_count = self.viewport.len();
@@ -808,12 +818,17 @@ impl Grid {
} else {
self.cursor.y -= row_count_to_transfer;
}
- transfer_rows_from_viewport_to_lines_above(
- &mut self.viewport,
- &mut self.lines_above,
- row_count_to_transfer,
- new_columns,
- );
+ if self.alternate_lines_above_viewport_and_cursor.is_none() {
+ transfer_rows_from_viewport_to_lines_above(
+ &mut self.viewport,
+ &mut self.lines_above,
+ row_count_to_transfer,
+ new_columns,
+ );
+ } else {
+ // in alternate screen, no scroll buffer, so just remove lines
+ self.viewport.drain(0..row_count_to_transfer);
+ }
}
Ordering::Equal => {}
}
@@ -916,16 +931,11 @@ impl Grid {
}
}
pub fn fill_viewport(&mut self, character: TerminalCharacter) {
- let row_count_to_transfer = self.viewport.len();
- let transferred_rows_count = transfer_rows_from_viewport_to_lines_above(
- &mut self.viewport,
- &mut self.lines_above,
- row_count_to_transfer,
- self.width,
- );
-
- self.scrollback_buffer_lines =
- subtract_isize_from_usize(self.scrollback_buffer_lines, transferred_rows_count);
+ if self.alternate_lines_above_viewport_and_cursor.is_some() {
+ self.viewport.clear();
+ } else {
+ self.transfer_rows_to_lines_above(self.viewport.len())
+ };
for _ in 0..self.height {
let columns = VecDeque::from(vec![character; self.width]);
@@ -947,17 +957,12 @@ impl Grid {
return;
}
if scroll_region_bottom == self.height - 1 && scroll_region_top == 0 {
- let row_count_to_transfer = 1;
- let transferred_rows_count = transfer_rows_from_viewport_to_lines_above(
- &mut self.viewport,
- &mut self.lines_above,
- row_count_to_transfer,
- self.width,
- );
- self.scrollback_buffer_lines = subtract_isize_from_usize(
- self.scrollback_buffer_lines,
- transferred_rows_count,
- );
+ if self.alternate_lines_above_viewport_and_cursor.is_none() {
+ self.transfer_rows_to_lines_above(1);
+ } else {
+ self.viewport.remove(0);
+ }
+
let columns = VecDeque::from(vec![EMPTY_TERMINAL_CHARACTER; self.width]);
self.viewport.push(Row::from_columns(columns).canonical());
self.selection.move_up(1);
@@ -984,15 +989,11 @@ impl Grid {
}
if self.cursor.y == self.height - 1 {
if self.scroll_region.is_none() {
- let row_count_to_transfer = 1;
- let transferred_rows_count = transfer_rows_from_viewport_to_lines_above(
- &mut self.viewport,
- &mut self.lines_above,
- row_count_to_transfer,
- self.width,
- );
- self.scrollback_buffer_lines =
- subtract_isize_from_usize(self.scrollback_buffer_lines, transferred_rows_count);
+ if self.alternate_lines_above_viewport_and_cursor.is_none() {
+ self.transfer_rows_to_lines_above(1);
+ } else {
+ self.viewport.remove(0);
+ }
self.selection.move_up(1);
}
@@ -1062,15 +1063,11 @@ impl Grid {
// line wrap
self.cursor.x = 0;
if self.cursor.y == self.height - 1 {
- let row_count_to_transfer = 1;
- let transferred_rows_count = transfer_rows_from_viewport_to_lines_above(
- &mut self.viewport,
- &mut self.lines_above,
- row_count_to_transfer,
- self.width,
- );
- self.scrollback_buffer_lines =
- subtract_isize_from_usize(self.scrollback_buffer_lines, transferred_rows_count);
+ if self.alternate_lines_above_viewport_and_cursor.is_none() {
+ self.transfer_rows_to_lines_above(1);
+ } else {
+ self.viewport.remove(0);
+ }
let wrapped_row = Row::new(self.width);
self.viewport.push(wrapped_row);
self.selection.move_up(1);
@@ -1365,7 +1362,7 @@ impl Grid {
self.lines_above = VecDeque::with_capacity(*SCROLL_BUFFER_SIZE.get().unwrap());
self.lines_below = vec![];
self.viewport = vec![Row::new(self.width).canonical()];
- self.alternative_lines_above_viewport_and_cursor = None;
+ self.alternate_lines_above_viewport_and_cursor = None;
self.cursor_key_mode = false;
self.scroll_region = None;
self.clear_viewport_before_rendering = true;
@@ -1501,6 +1498,17 @@ impl Grid {
self.title = Some(popped_title);
}
}
+ fn transfer_rows_to_lines_above(&mut self, count: usize) {
+ let transferred_rows_count = transfer_rows_from_viewport_to_lines_above(
+ &mut self.viewport,
+ &mut self.lines_above,
+ count,
+ self.width,
+ );
+
+ self.scrollback_buffer_lines =
+ subtract_isize_from_usize(self.scrollback_buffer_lines, transferred_rows_count);
+ }
}
impl Perform for Grid {
@@ -1805,17 +1813,18 @@ impl Perform for Grid {
self.bracketed_paste_mode = false;
}
Some(1049) => {
+ // leave alternate buffer
if let Some((
alternative_lines_above,
alternative_viewport,
alternative_cursor,
- )) = &mut self.alternative_lines_above_viewport_and_cursor
+ )) = &mut self.alternate_lines_above_viewport_and_cursor
{
std::mem::swap(&mut self.lines_above, alternative_lines_above);
std::mem::swap(&mut self.viewport, alternative_viewport);
std::mem::swap(&mut self.cursor, alternative_cursor);
}
- self.alternative_lines_above_viewport_and_cursor = None;
+ self.alternate_lines_above_viewport_and_cursor = None;
self.clear_viewport_before_rendering = true;
self.force_change_size(self.height, self.width); // the alternative_viewport might have been of a different size...
self.mark_for_rerender();
@@ -1861,18 +1870,17 @@ impl Perform for Grid {
self.bracketed_paste_mode = true;
}
Some(1049) => {
+ // enter alternate buffer
let current_lines_above = std::mem::replace(
&mut self.lines_above,
VecDeque::with_capacity(*SCROLL_BUFFER_SIZE.get().unwrap()),
);
- let current_viewport = std::mem::replace(
- &mut self.viewport,
- vec![Row::new(self.width).canonical()],
- );
+ let current_viewport = std::mem::take(&mut self.viewport);
let current_cursor = std::mem::replace(&mut self.cursor, Cursor::new(0, 0));
- self.alternative_lines_above_viewport_and_cursor =
+ self.alternate_lines_above_viewport_and_cursor =
Some((current_lines_above, current_viewport, current_cursor));
self.clear_viewport_before_rendering = true;
+ self.scrollback_buffer_lines = self.recalculate_scrollback_buffer_count();
}
Some(1) => {
self.cursor_key_mode = true;
diff --git a/zellij-server/src/panes/unit/grid_tests.rs b/zellij-server/src/panes/unit/grid_tests.rs
index 45fdb776..7fbfd119 100644
--- a/zellij-server/src/panes/unit/grid_tests.rs
+++ b/zellij-server/src/panes/unit/grid_tests.rs
@@ -1090,3 +1090,19 @@ pub fn ring_bell() {
}
assert!(grid.ring_bell);
}
+
+#[test]
+pub fn alternate_screen_change_size() {
+ let mut vte_parser = vte::Parser::new();
+ let mut grid = Grid::new(20, 20, Palette::default());
+ let fixture_name = "alternate_screen_change_size";
+ let content = read_fixture(fixture_name);
+ for byte in content {
+ vte_parser.advance(&mut grid, byte);
+ }
+ // no scrollback in alternate screen
+ assert_eq!(grid.scrollback_position_and_length(), (0, 0));
+ grid.change_size(10, 10);
+ assert_snapshot!(format!("{:?}", grid));
+ assert_eq!(grid.scrollback_position_and_length(), (0, 0))
+}
diff --git a/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__alternate_screen_change_size.snap b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__alternate_screen_change_size.snap
new file mode 100644
index 00000000..df16b28c
--- /dev/null
+++ b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__alternate_screen_change_size.snap
@@ -0,0 +1,16 @@
+---
+source: zellij-server/src/panes/./unit/grid_tests.rs
+expression: "format!(\"{:?}\", grid)"
+
+---
+00 (C): line12aaaa
+01 (C): line13aaaa
+02 (C): line14aaaa
+03 (C): line15aaaa
+04 (C): line16aaaa
+05 (C): line17aaaa
+06 (C): line18aaaa
+07 (C): line19a🦀a
+08 (C): line20a🦀
+09 (C): line21🦀🦀
+