1
0
Fork 0
mirror of https://github.com/alacritty/alacritty.git synced 2025-08-07 22:12:25 -04:00

Fix hint highlight invalidation

This fixes a couple issues with hint highlight invalidation, which would
cause hints to lose their underline highlight despite the terminal
itself not having changed since the highlight started.

Closes #8270.
This commit is contained in:
Christian Duerr 2024-10-29 04:02:42 +00:00 committed by GitHub
parent c2782ad619
commit 0542d9f4f5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 33 additions and 11 deletions

View file

@ -10,6 +10,10 @@ Notable changes to the `alacritty_terminal` crate are documented in its
## 0.15.0-dev ## 0.15.0-dev
### Fixed
- Mouse/Vi cursor hint highlighting broken on the terminal cursor line
## 0.14.0 ## 0.14.0
### Packaging ### Packaging

View file

@ -193,9 +193,11 @@ impl FrameDamage {
/// Check if a range is damaged. /// Check if a range is damaged.
#[inline] #[inline]
pub fn intersects(&self, start: Point<usize>, end: Point<usize>) -> bool { pub fn intersects(&self, start: Point<usize>, end: Point<usize>) -> bool {
let start_line = &self.lines[start.line];
let end_line = &self.lines[end.line];
self.full self.full
|| self.lines[start.line].left <= start.column || (start_line.left..=start_line.right).contains(&start.column)
|| self.lines[end.line].right >= end.column || (end_line.left..=end_line.right).contains(&end.column)
|| (start.line + 1..end.line).any(|line| self.lines[line].is_damaged()) || (start.line + 1..end.line).any(|line| self.lines[line].is_damaged())
} }
} }

View file

@ -342,9 +342,13 @@ pub struct Display {
/// Hint highlighted by the mouse. /// Hint highlighted by the mouse.
pub highlighted_hint: Option<HintMatch>, pub highlighted_hint: Option<HintMatch>,
/// Frames since hint highlight was created.
highlighted_hint_age: usize,
/// Hint highlighted by the vi mode cursor. /// Hint highlighted by the vi mode cursor.
pub vi_highlighted_hint: Option<HintMatch>, pub vi_highlighted_hint: Option<HintMatch>,
/// Frames since hint highlight was created.
vi_highlighted_hint_age: usize,
pub raw_window_handle: RawWindowHandle, pub raw_window_handle: RawWindowHandle,
@ -516,6 +520,8 @@ impl Display {
font_size, font_size,
window, window,
pending_renderer_update: Default::default(), pending_renderer_update: Default::default(),
vi_highlighted_hint_age: Default::default(),
highlighted_hint_age: Default::default(),
vi_highlighted_hint: Default::default(), vi_highlighted_hint: Default::default(),
highlighted_hint: Default::default(), highlighted_hint: Default::default(),
hint_mouse_point: Default::default(), hint_mouse_point: Default::default(),
@ -759,7 +765,7 @@ impl Display {
drop(terminal); drop(terminal);
// Invalidate highlighted hints if grid has changed. // 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. // 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; let mut dirty = vi_highlighted_hint != self.vi_highlighted_hint;
self.vi_highlighted_hint = 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. // 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(); self.damage_tracker.frame().mark_fully_damaged();
} }
@ -1055,9 +1062,10 @@ impl Display {
let mouse_highlight_dirty = self.highlighted_hint != highlighted_hint; let mouse_highlight_dirty = self.highlighted_hint != highlighted_hint;
dirty |= mouse_highlight_dirty; dirty |= mouse_highlight_dirty;
self.highlighted_hint = highlighted_hint; self.highlighted_hint = highlighted_hint;
self.highlighted_hint_age = 0;
// Force full redraw if the mouse cursor highlight was cleared. // Force full redraw if the mouse cursor highlight was changed.
if mouse_highlight_dirty && self.highlighted_hint.is_none() { if mouse_highlight_dirty {
self.damage_tracker.frame().mark_fully_damaged(); self.damage_tracker.frame().mark_fully_damaged();
} }
@ -1331,16 +1339,24 @@ impl Display {
} }
/// Check whether a hint highlight needs to be cleared. /// 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(); let frame = self.damage_tracker.frame();
for (hint, reset_mouse) in let hints = [
[(&mut self.highlighted_hint, true), (&mut self.vi_highlighted_hint, false)] (&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 { let (start, end) = match hint {
Some(hint) => (*hint.bounds().start(), *hint.bounds().end()), 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. // Convert hint bounds to viewport coordinates.
let start = term::point_to_viewport(display_offset, start).unwrap_or_default(); let start = term::point_to_viewport(display_offset, start).unwrap_or_default();
let end = term::point_to_viewport(display_offset, end).unwrap_or_else(|| { let end = term::point_to_viewport(display_offset, end).unwrap_or_else(|| {