1
0
Fork 0
mirror of https://github.com/alacritty/alacritty.git synced 2024-11-25 14:05:41 -05:00

Fix selection rotation on the last line

This fixes an issue with terminal resizes when the selection is on the
last line. Alacritty would fail to rotate lines and keep the selection
in the same line index whenever the terminal line count was grown or
shrunk.

This issue occurred due to the range passed to the selection's rotate
function still being based on the old terminal size, which caused the
initial or target state of the rotation to be outside of the terminal
bounds.

Closes #6698.
This commit is contained in:
Christian Duerr 2023-03-25 00:07:20 +01:00 committed by Kirill Chibisov
parent 16e18f2fff
commit d9131c59e0
6 changed files with 24 additions and 22 deletions

View file

@ -5,6 +5,13 @@ The sections should follow the order `Packaging`, `Added`, `Changed`, `Fixed` an
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## 0.13.0-dev
### Fixed
- Character `;` inside the `URI` in `OSC 8` sequence breaking the URI
- Selection on last line not updating correctly on resize
## 0.12.0 ## 0.12.0
### Added ### Added
@ -50,7 +57,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- EOT (`\x03`) escaping bracketed paste mode - EOT (`\x03`) escaping bracketed paste mode
- Drag & Drop not working for the search bar - Drag & Drop not working for the search bar
- Simple-fullscreened window not resized when moving between monitors on macOS - Simple-fullscreened window not resized when moving between monitors on macOS
- Character `;` inside the `URI` in `OSC 8` sequence breaking the URI
### Removed ### Removed

View file

@ -199,7 +199,7 @@ pub struct RenderableCellExtra {
} }
impl RenderableCell { impl RenderableCell {
fn new<'a>(content: &mut RenderableContent<'a>, cell: Indexed<&Cell>) -> Self { fn new(content: &mut RenderableContent<'_>, cell: Indexed<&Cell>) -> Self {
// Lookup RGB values. // Lookup RGB values.
let mut fg = Self::compute_fg_rgb(content, cell.fg, cell.flags); let mut fg = Self::compute_fg_rgb(content, cell.fg, cell.flags);
let mut bg = Self::compute_bg_rgb(content, cell.bg); let mut bg = Self::compute_bg_rgb(content, cell.bg);

View file

@ -588,11 +588,10 @@ impl Display {
}); });
} }
// XXX: this function must not call to any `OpenGL` related tasks. Renderer updates are
// performed in [`Self::process_renderer_update`] right befor drawing.
//
/// Process update events. /// Process update events.
///
/// XXX: this function must not call to any `OpenGL` related tasks. Only logical update
/// of the state is being performed here. Rendering update takes part right before the
/// actual rendering.
pub fn handle_update<T>( pub fn handle_update<T>(
&mut self, &mut self,
terminal: &mut Term<T>, terminal: &mut Term<T>,
@ -666,14 +665,11 @@ impl Display {
self.size_info = new_size; self.size_info = new_size;
} }
// NOTE: Renderer updates are split off, since platforms like Wayland require resize and other
// OpenGL operations to be performed right before rendering. Otherwise they could lock the
// back buffer and render with the previous state. This also solves flickering during resizes.
//
/// Update the state of the renderer. /// Update the state of the renderer.
///
/// NOTE: The update to the renderer is split from the display update on purpose, since
/// on some platforms, like Wayland, resize and other OpenGL operations must be performed
/// right before rendering, otherwise they could lock the back buffer resulting in
/// rendering with the buffer of old size.
///
/// This also resolves any flickering, since the resize is now synced with frame callbacks.
pub fn process_renderer_update(&mut self) { pub fn process_renderer_update(&mut self) {
let renderer_update = match self.pending_renderer_update.take() { let renderer_update = match self.pending_renderer_update.take() {
Some(renderer_update) => renderer_update, Some(renderer_update) => renderer_update,

View file

@ -796,7 +796,7 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon
// We remove `\x1b` to ensure it's impossible for the pasted text to write the bracketed // We remove `\x1b` to ensure it's impossible for the pasted text to write the bracketed
// paste end escape `\x1b[201~` and `\x03` since some shells incorrectly terminate // paste end escape `\x1b[201~` and `\x03` since some shells incorrectly terminate
// bracketed paste on its receival. // bracketed paste on its receival.
let filtered = text.replace('\x1b', "").replace('\x03', ""); let filtered = text.replace(['\x1b', '\x03'], "");
self.write_to_pty(filtered.into_bytes()); self.write_to_pty(filtered.into_bytes());
self.write_to_pty(&b"\x1b[201~"[..]); self.write_to_pty(&b"\x1b[201~"[..]);

View file

@ -719,9 +719,8 @@ impl Canvas {
let v_line_bounds = (v_line_bounds.0 as usize, v_line_bounds.1 as usize); let v_line_bounds = (v_line_bounds.0 as usize, v_line_bounds.1 as usize);
let max_transparancy = 0.5; let max_transparancy = 0.5;
for (radius_y, radius_x) in (h_line_bounds.0..h_line_bounds.1) for (radius_y, radius_x) in
.into_iter() (h_line_bounds.0..h_line_bounds.1).zip(v_line_bounds.0..v_line_bounds.1)
.zip((v_line_bounds.0..v_line_bounds.1).into_iter())
{ {
let radius_x = radius_x as f32; let radius_x = radius_x as f32;
let radius_y = radius_y as f32; let radius_y = radius_y as f32;

View file

@ -611,6 +611,10 @@ impl<T> Term<T> {
delta = cmp::min(cmp::max(delta, min_delta), history_size as i32); delta = cmp::min(cmp::max(delta, min_delta), history_size as i32);
self.vi_mode_cursor.point.line += delta; self.vi_mode_cursor.point.line += delta;
let is_alt = self.mode.contains(TermMode::ALT_SCREEN);
self.grid.resize(!is_alt, num_lines, num_cols);
self.inactive_grid.resize(is_alt, num_lines, num_cols);
// Invalidate selection and tabs only when necessary. // Invalidate selection and tabs only when necessary.
if old_cols != num_cols { if old_cols != num_cols {
self.selection = None; self.selection = None;
@ -618,14 +622,11 @@ impl<T> Term<T> {
// Recreate tabs list. // Recreate tabs list.
self.tabs.resize(num_cols); self.tabs.resize(num_cols);
} else if let Some(selection) = self.selection.take() { } else if let Some(selection) = self.selection.take() {
let range = Line(0)..Line(num_lines as i32); let max_lines = cmp::max(num_lines, old_lines) as i32;
let range = Line(0)..Line(max_lines);
self.selection = selection.rotate(self, &range, -delta); self.selection = selection.rotate(self, &range, -delta);
} }
let is_alt = self.mode.contains(TermMode::ALT_SCREEN);
self.grid.resize(!is_alt, num_lines, num_cols);
self.inactive_grid.resize(is_alt, num_lines, num_cols);
// Clamp vi cursor to viewport. // Clamp vi cursor to viewport.
let vi_point = self.vi_mode_cursor.point; let vi_point = self.vi_mode_cursor.point;
let viewport_top = Line(-(self.grid.display_offset() as i32)); let viewport_top = Line(-(self.grid.display_offset() as i32));