Fix selection scrolling with message bar visible

This resolves an issue with selection scrolling which would cause the
selection to wrap to the top of the screen once the cursor enters the
padding below the message bar.

Fixes #4120.
This commit is contained in:
Christian Duerr 2020-08-14 07:26:42 +00:00 committed by GitHub
parent 0a1683e84d
commit 0003f6683f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 33 deletions

View File

@ -34,6 +34,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Slow rendering performance with HiDPI displays, especially on macOS
- Keys swallowed during search when pressing them right before releasing backspace
- Crash when a wrapped line is rotated into the last line
- Selection wrapping to the top when selecting below the error/warning bar
## 0.5.0

View File

@ -170,9 +170,7 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon
} else if self.mouse().left_button_state == ElementState::Pressed
|| self.mouse().right_button_state == ElementState::Pressed
{
let (x, y) = (self.mouse().x, self.mouse().y);
let size_info = self.size_info();
let point = size_info.pixels_to_coords(x, y);
let point = self.size_info().pixels_to_coords(self.mouse().x, self.mouse().y);
let cell_side = self.mouse().cell_side;
self.update_selection(Point { line: point.line, col: point.col }, cell_side);
}
@ -195,20 +193,27 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon
self.terminal.dirty = true;
}
fn update_selection(&mut self, point: Point, side: Side) {
let point = self.terminal.visible_to_buffer(point);
fn update_selection(&mut self, mut point: Point, side: Side) {
let mut selection = match self.terminal.selection.take() {
Some(selection) => selection,
None => return,
};
// Update selection if one exists.
let vi_mode = self.terminal.mode().contains(TermMode::VI);
if let Some(selection) = &mut self.terminal.selection {
selection.update(point, side);
// Treat motion over message bar like motion over the last line.
point.line = min(point.line, self.terminal.screen_lines() - 1);
if vi_mode {
selection.include_all();
}
// Update selection.
let absolute_point = self.terminal.visible_to_buffer(point);
selection.update(absolute_point, side);
self.terminal.dirty = true;
// Move vi cursor and expand selection.
if self.terminal.mode().contains(TermMode::VI) {
self.terminal.vi_mode_cursor.point = point;
selection.include_all();
}
self.terminal.selection = Some(selection);
self.terminal.dirty = true;
}
fn start_selection(&mut self, ty: SelectionType, point: Point, side: Side) {
@ -646,7 +651,7 @@ pub struct Mouse {
pub cell_side: Side,
pub lines_scrolled: f32,
pub block_url_launcher: bool,
pub inside_grid: bool,
pub inside_text_area: bool,
}
impl Default for Mouse {
@ -666,7 +671,7 @@ impl Default for Mouse {
cell_side: Side::Left,
lines_scrolled: 0.,
block_url_launcher: false,
inside_grid: false,
inside_text_area: false,
}
}
}
@ -985,7 +990,7 @@ impl<N: Notify + OnResize> Processor<N> {
processor.ctx.write_to_pty((path + " ").into_bytes());
},
WindowEvent::CursorLeft { .. } => {
processor.ctx.mouse.inside_grid = false;
processor.ctx.mouse.inside_text_area = false;
if processor.highlighted_url.is_some() {
processor.ctx.terminal.dirty = true;

View File

@ -377,7 +377,7 @@ impl<'a, T: EventListener, A: ActionContext<T>> Processor<'a, T, A> {
self.ctx.mouse_mut().x = x;
self.ctx.mouse_mut().y = y;
let inside_grid = size_info.contains_point(x, y);
let inside_text_area = size_info.contains_point(x, y);
let point = size_info.pixels_to_coords(x, y);
let cell_side = self.get_mouse_side();
@ -387,12 +387,12 @@ impl<'a, T: EventListener, A: ActionContext<T>> Processor<'a, T, A> {
// If the mouse hasn't changed cells, do nothing.
if !cell_changed
&& self.ctx.mouse().cell_side == cell_side
&& self.ctx.mouse().inside_grid == inside_grid
&& self.ctx.mouse().inside_text_area == inside_text_area
{
return;
}
self.ctx.mouse_mut().inside_grid = inside_grid;
self.ctx.mouse_mut().inside_text_area = inside_text_area;
self.ctx.mouse_mut().cell_side = cell_side;
self.ctx.mouse_mut().line = point.line;
self.ctx.mouse_mut().column = point.col;
@ -405,23 +405,14 @@ impl<'a, T: EventListener, A: ActionContext<T>> Processor<'a, T, A> {
self.update_url_state(&mouse_state);
self.ctx.window_mut().set_mouse_cursor(mouse_state.into());
let last_term_line = self.ctx.terminal().grid().screen_lines() - 1;
if (lmb_pressed || rmb_pressed)
&& (self.ctx.modifiers().shift() || !self.ctx.mouse_mode())
&& !search_active
{
// Treat motion over message bar like motion over the last line.
let line = min(point.line, last_term_line);
// Move vi mode cursor to mouse cursor position.
if self.ctx.terminal().mode().contains(TermMode::VI) {
self.ctx.terminal_mut().vi_mode_cursor.point = point;
}
self.ctx.update_selection(Point { line, col: point.col }, cell_side);
} else if inside_grid
self.ctx.update_selection(point, cell_side);
} else if inside_text_area
&& cell_changed
&& point.line <= last_term_line
&& point.line < self.ctx.terminal().screen_lines()
&& self.ctx.terminal().mode().intersects(TermMode::MOUSE_MOTION | TermMode::MOUSE_DRAG)
{
if lmb_pressed {
@ -997,7 +988,7 @@ impl<'a, T: EventListener, A: ActionContext<T>> Processor<'a, T, A> {
// Since search is above the message bar, the button is offset by search's height.
let search_height = if self.ctx.search_active() { 1 } else { 0 };
mouse.inside_grid
mouse.inside_text_area
&& mouse.column + message_bar::CLOSE_BUTTON_TEXT.len() >= self.ctx.size_info().cols()
&& mouse.line == self.ctx.terminal().grid().screen_lines() + search_height
}

View File

@ -163,7 +163,7 @@ impl Urls {
// Make sure all prerequisites for highlighting are met.
if selection
|| !mouse.inside_grid
|| !mouse.inside_text_area
|| config.ui_config.mouse.url.launcher.is_none()
|| required_mods != mods
|| mouse.left_button_state == ElementState::Pressed