1
0
Fork 0
mirror of https://github.com/alacritty/alacritty.git synced 2024-11-18 13:55:23 -05: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
### Fixed
- Mouse/Vi cursor hint highlighting broken on the terminal cursor line
## 0.14.0
### Packaging

View file

@ -193,9 +193,11 @@ impl FrameDamage {
/// Check if a range is damaged.
#[inline]
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.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())
}
}

View file

@ -342,9 +342,13 @@ pub struct Display {
/// Hint highlighted by the mouse.
pub highlighted_hint: Option<HintMatch>,
/// Frames since hint highlight was created.
highlighted_hint_age: usize,
/// Hint highlighted by the vi mode cursor.
pub vi_highlighted_hint: Option<HintMatch>,
/// 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(|| {