From 3e36d714fec8139a1e506036a394b343bd1a8bb4 Mon Sep 17 00:00:00 2001 From: Christian Duerr Date: Sun, 24 Mar 2019 17:37:30 +0000 Subject: Fix URL highlight crash The URL highlight stores the state of the last URL highlight with the position of the URL start position. However when resizing, it's possible that the indices of this point change which will cause a crash if the old positions are not within the grid anymore. This has been resolved by resetting the URL highlight state whenever the terminal is resized. The original PR incorrectly required the shift modifier to be required when the user was in the alternate screen buffer. However the correct behavior is to require it when the mouse mode is enabled. This has been resolved and URLs are now highlighted in the alt screen even if no shift modifier is pressed. This fixes #2194. --- src/input.rs | 34 ++++++++-------------------------- 1 file changed, 8 insertions(+), 26 deletions(-) (limited to 'src/input.rs') diff --git a/src/input.rs b/src/input.rs index abb98c44..466161a7 100644 --- a/src/input.rs +++ b/src/input.rs @@ -31,9 +31,9 @@ use glutin::{ use crate::config::{self, Key}; use crate::grid::Scroll; -use crate::event::{ClickState, Mouse, UrlHoverSaveState}; +use crate::event::{ClickState, Mouse}; use crate::index::{Line, Column, Side, Point}; -use crate::term::{Term, SizeInfo, Search}; +use crate::term::{Term, SizeInfo, Search, UrlHoverSaveState}; use crate::term::mode::TermMode; use crate::term::cell::Flags; use crate::util::fmt::Red; @@ -440,7 +440,7 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> { // Only show URLs as launchable when all required modifiers are pressed let url = if self.mouse_config.url.modifiers.relaxed_eq(modifiers) - && (!self.ctx.terminal().mode().contains(TermMode::ALT_SCREEN) || modifiers.shift) + && (!self.ctx.terminal().mode().intersects(mouse_mode) || modifiers.shift) { self.ctx.terminal().url_search(point.into()) } else { @@ -463,14 +463,12 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> { let start = Point::new(line, Column(col)); // Update URLs only on change, so they don't all get marked as underlined - if self.ctx.mouse().url_hover_save.as_ref().map(|hs| hs.start) == Some(start) { + if self.ctx.terminal().url_highlight_start() == Some(start) { return; } // Since the URL changed without reset, we need to clear the previous underline - if let Some(hover_save) = self.ctx.mouse_mut().url_hover_save.take() { - self.reset_underline(&hover_save); - } + self.ctx.terminal_mut().reset_url_highlight(); // Underline all cells and store their current underline state let mut underlined = Vec::with_capacity(len); @@ -482,7 +480,7 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> { } // Save the higlight state for restoring it again - self.ctx.mouse_mut().url_hover_save = Some(UrlHoverSaveState { + self.ctx.terminal_mut().set_url_highlight(UrlHoverSaveState { mouse_cursor, underlined, start, @@ -490,24 +488,8 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> { self.ctx.terminal_mut().set_mouse_cursor(MouseCursor::Hand); self.ctx.terminal_mut().dirty = true; - } else if let Some(hover_save) = self.ctx.mouse_mut().url_hover_save.take() { - self.ctx.terminal_mut().set_mouse_cursor(hover_save.mouse_cursor); - self.ctx.terminal_mut().dirty = true; - self.reset_underline(&hover_save); - } - } - - /// Reset the underline state after unhovering a URL. - fn reset_underline(&mut self, hover_save: &UrlHoverSaveState) { - let last_col = self.ctx.size_info().cols() - 1; - let last_line = self.ctx.size_info().lines().0 - 1; - - let mut iter = once(hover_save.start).chain(hover_save.start.iter(last_col, last_line)); - for underlined in &hover_save.underlined { - if let (Some(point), false) = (iter.next(), underlined) { - let cell = &mut self.ctx.terminal_mut().grid_mut()[point.line][point.col]; - cell.flags.remove(Flags::UNDERLINE); - } + } else { + self.ctx.terminal_mut().reset_url_highlight(); } } -- cgit