From f1853a031d52f6964bbf368d2975767449fc4814 Mon Sep 17 00:00:00 2001 From: Christian Duerr Date: Wed, 14 Feb 2024 01:59:56 +0100 Subject: Fix regional scrolling leaking into history This fixes an issue where a scrolling region that does not start at the top of the screen would still rotate lines into history when scrolling the content "upwards". --- alacritty_terminal/src/grid/mod.rs | 52 ++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 22 deletions(-) (limited to 'alacritty_terminal/src') diff --git a/alacritty_terminal/src/grid/mod.rs b/alacritty_terminal/src/grid/mod.rs index 8fdde0a4..59769883 100644 --- a/alacritty_terminal/src/grid/mod.rs +++ b/alacritty_terminal/src/grid/mod.rs @@ -268,33 +268,41 @@ impl Grid { self.display_offset = min(self.display_offset + positions, self.max_scroll_limit); } - // Create scrollback for the new lines. - self.increase_scroll_limit(positions); + // Only rotate the entire history if the active region starts at the top. + if region.start == 0 { + // Create scrollback for the new lines. + self.increase_scroll_limit(positions); - // Swap the lines fixed at the top to their target positions after rotation. - // - // Since we've made sure that the rotation will never rotate away the entire region, we - // know that the position of the fixed lines before the rotation must already be - // visible. - // - // We need to start from the bottom, to make sure the fixed lines aren't swapped with each - // other. - for i in (0..region.start.0).rev().map(Line::from) { - self.raw.swap(i, i + positions); - } + // Swap the lines fixed at the top to their target positions after rotation. + // + // Since we've made sure that the rotation will never rotate away the entire region, we + // know that the position of the fixed lines before the rotation must already be + // visible. + // + // We need to start from the bottom, to make sure the fixed lines aren't swapped with + // each other. + for i in (0..region.start.0).rev().map(Line::from) { + self.raw.swap(i, i + positions); + } - // Rotate the entire line buffer upward. - self.raw.rotate(-(positions as isize)); + // Rotate the entire line buffer upward. + self.raw.rotate(-(positions as isize)); - // Ensure all new lines are fully cleared. - let screen_lines = self.screen_lines(); - for i in ((screen_lines - positions)..screen_lines).map(Line::from) { - self.raw[i].reset(&self.cursor.template); + // Swap the fixed lines at the bottom back into position. + let screen_lines = self.screen_lines() as i32; + for i in (region.end.0..screen_lines).rev().map(Line::from) { + self.raw.swap(i, i - positions); + } + } else { + // Rotate lines without moving anything into history. + for i in (region.start.0..region.end.0 - positions as i32).map(Line::from) { + self.raw.swap(i, i + positions); + } } - // Swap the fixed lines at the bottom back into position. - for i in (region.end.0..(screen_lines as i32)).rev().map(Line::from) { - self.raw.swap(i, i - positions); + // Ensure all new lines are fully cleared. + for i in (region.end.0 - positions as i32..region.end.0).map(Line::from) { + self.raw[i].reset(&self.cursor.template); } } -- cgit