diff --git a/CHANGELOG.md b/CHANGELOG.md index 75f164d0..095d5fd7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ Notable changes to the `alacritty_terminal` crate are documented in its ## 0.15.0-dev +### Fixed + +- Mouse/Vi cursor hint highlighting broken on the terminal cursor line + ## 0.14.0 ### Packaging diff --git a/alacritty/src/display/damage.rs b/alacritty/src/display/damage.rs index 8efe0133..fc6aef39 100644 --- a/alacritty/src/display/damage.rs +++ b/alacritty/src/display/damage.rs @@ -193,9 +193,11 @@ impl FrameDamage { /// Check if a range is damaged. #[inline] pub fn intersects(&self, start: Point, end: Point) -> bool { + let start_line = &self.lines[start.line]; + let end_line = &self.lines[end.line]; self.full - || self.lines[start.line].left <= start.column - || self.lines[end.line].right >= end.column + || (start_line.left..=start_line.right).contains(&start.column) + || (end_line.left..=end_line.right).contains(&end.column) || (start.line + 1..end.line).any(|line| self.lines[line].is_damaged()) } } diff --git a/alacritty/src/display/mod.rs b/alacritty/src/display/mod.rs index d0044f8b..d358a7c5 100644 --- a/alacritty/src/display/mod.rs +++ b/alacritty/src/display/mod.rs @@ -342,9 +342,13 @@ pub struct Display { /// Hint highlighted by the mouse. pub highlighted_hint: Option, + /// Frames since hint highlight was created. + highlighted_hint_age: usize, /// Hint highlighted by the vi mode cursor. pub vi_highlighted_hint: Option, + /// Frames since hint highlight was created. + vi_highlighted_hint_age: usize, pub raw_window_handle: RawWindowHandle, @@ -516,6 +520,8 @@ impl Display { font_size, window, pending_renderer_update: Default::default(), + vi_highlighted_hint_age: Default::default(), + highlighted_hint_age: Default::default(), vi_highlighted_hint: Default::default(), highlighted_hint: Default::default(), hint_mouse_point: Default::default(), @@ -759,7 +765,7 @@ impl Display { drop(terminal); // Invalidate highlighted hints if grid has changed. - self.validate_hints(display_offset); + self.validate_hint_highlights(display_offset); // Add damage from alacritty's UI elements overlapping terminal. @@ -1017,9 +1023,10 @@ impl Display { }; let mut dirty = vi_highlighted_hint != self.vi_highlighted_hint; self.vi_highlighted_hint = vi_highlighted_hint; + self.vi_highlighted_hint_age = 0; // Force full redraw if the vi mode highlight was cleared. - if dirty && self.vi_highlighted_hint.is_none() { + if dirty { self.damage_tracker.frame().mark_fully_damaged(); } @@ -1055,9 +1062,10 @@ impl Display { let mouse_highlight_dirty = self.highlighted_hint != highlighted_hint; dirty |= mouse_highlight_dirty; self.highlighted_hint = highlighted_hint; + self.highlighted_hint_age = 0; - // Force full redraw if the mouse cursor highlight was cleared. - if mouse_highlight_dirty && self.highlighted_hint.is_none() { + // Force full redraw if the mouse cursor highlight was changed. + if mouse_highlight_dirty { self.damage_tracker.frame().mark_fully_damaged(); } @@ -1331,16 +1339,24 @@ impl Display { } /// Check whether a hint highlight needs to be cleared. - fn validate_hints(&mut self, display_offset: usize) { + fn validate_hint_highlights(&mut self, display_offset: usize) { let frame = self.damage_tracker.frame(); - for (hint, reset_mouse) in - [(&mut self.highlighted_hint, true), (&mut self.vi_highlighted_hint, false)] - { + let hints = [ + (&mut self.highlighted_hint, &mut self.highlighted_hint_age, true), + (&mut self.vi_highlighted_hint, &mut self.vi_highlighted_hint_age, false), + ]; + for (hint, hint_age, reset_mouse) in hints { let (start, end) = match hint { Some(hint) => (*hint.bounds().start(), *hint.bounds().end()), - None => return, + None => continue, }; + // Ignore hints that were created this frame. + *hint_age += 1; + if *hint_age == 1 { + continue; + } + // Convert hint bounds to viewport coordinates. let start = term::point_to_viewport(display_offset, start).unwrap_or_default(); let end = term::point_to_viewport(display_offset, end).unwrap_or_else(|| {