Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Audit and simplifying of dirty fields #6208

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions alacritty/src/display/content.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use alacritty_terminal::ansi::{Color, CursorShape, NamedColor};
use alacritty_terminal::event::EventListener;
use alacritty_terminal::grid::Indexed;
use alacritty_terminal::index::{Column, Line, Point};
use alacritty_terminal::selection::SelectionRange;
use alacritty_terminal::term::cell::{Cell, Flags, Hyperlink};
use alacritty_terminal::term::color::{CellRgb, Rgb};
use alacritty_terminal::term::search::{Match, RegexSearch};
Expand Down Expand Up @@ -102,10 +101,6 @@ impl<'a> RenderableContent<'a> {
self.terminal_content.colors[color].unwrap_or(self.colors[color])
}

pub fn selection_range(&self) -> Option<SelectionRange> {
self.terminal_content.selection
}

/// Assemble the information required to render the terminal cursor.
fn renderable_cursor(&mut self, cell: &RenderableCell) -> RenderableCursor {
// Cursor colors.
Expand Down
68 changes: 30 additions & 38 deletions alacritty/src/display/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use alacritty_terminal::config::MAX_SCROLLBACK_LINES;
use alacritty_terminal::event::{EventListener, OnResize, WindowSize};
use alacritty_terminal::grid::Dimensions as TermDimensions;
use alacritty_terminal::index::{Column, Direction, Line, Point};
use alacritty_terminal::selection::{Selection, SelectionRange};
use alacritty_terminal::selection::Selection;
use alacritty_terminal::term::cell::Flags;
use alacritty_terminal::term::color::Rgb;
use alacritty_terminal::term::{self, Term, TermDamage, TermMode, MIN_COLUMNS, MIN_SCREEN_LINES};
Expand Down Expand Up @@ -686,37 +686,34 @@ impl Display {
info!("Width: {}, Height: {}", self.size_info.width(), self.size_info.height());

// Damage the entire screen after processing update.
self.fully_damage();
self.damage_rects.push(self.full_damage_rect());
}

/// Damage the entire window.
fn fully_damage(&mut self) {
let screen_rect = DamageRect {
/// Returns a DamageRect spanning the entire window.
fn full_damage_rect(&self) -> DamageRect {
DamageRect {
x: 0,
y: 0,
width: self.size_info.width() as u32,
height: self.size_info.height() as u32,
};

self.damage_rects.push(screen_rect);
}
}

fn update_damage<T: EventListener>(
&mut self,
terminal: &mut MutexGuard<'_, Term<T>>,
selection_range: Option<SelectionRange>,
search_state: &SearchState,
) {
let requires_full_damage = self.visual_bell.intensity() != 0.
|| self.hint_state.active()
|| search_state.regex().is_some();
if requires_full_damage {
terminal.mark_fully_damaged();
self.next_frame_damage_rects.push(self.full_damage_rect());
}

self.damage_highlighted_hints(terminal);
match terminal.damage(selection_range) {
TermDamage::Full => self.fully_damage(),
match terminal.damage() {
TermDamage::Full => self.damage_rects.push(self.full_damage_rect()),
TermDamage::Partial(damaged_lines) => {
let damaged_rects = RenderDamageIterator::new(damaged_lines, self.size_info.into());
for damaged_rect in damaged_rects {
Expand All @@ -725,14 +722,6 @@ impl Display {
},
}
terminal.reset_damage();

// Ensure that the content requiring full damage is cleaned up again on the next frame.
if requires_full_damage {
terminal.mark_fully_damaged();
}

// Damage highlighted hints for the next frame as well, so we'll clear them.
self.damage_highlighted_hints(terminal);
}

/// Draw the screen.
Expand All @@ -753,7 +742,6 @@ impl Display {
for cell in &mut content {
grid_cells.push(cell);
}
let selection_range = content.selection_range();
let background_color = content.color(NamedColor::Background as usize);
let display_offset = content.display_offset();
let cursor = content.cursor();
Expand All @@ -767,7 +755,7 @@ impl Display {
let vi_cursor_point = if vi_mode { Some(terminal.vi_mode_cursor.point) } else { None };

if self.collect_damage() {
self.update_damage(&mut terminal, selection_range, search_state);
self.update_damage(&mut terminal, search_state);
}

// Drop terminal as early as possible to free lock.
Expand Down Expand Up @@ -966,15 +954,13 @@ impl Display {
}

/// Update the mouse/vi mode cursor hint highlighting.
///
/// This will return whether the highlighted hints changed.
pub fn update_highlighted_hints<T>(
&mut self,
term: &Term<T>,
term: &mut Term<T>,
config: &UiConfig,
mouse: &Mouse,
modifiers: ModifiersState,
) -> bool {
) {
// Update vi mode cursor hint.
let vi_highlighted_hint = if term.mode().contains(TermMode::VI) {
let mods = ModifiersState::all();
Expand All @@ -983,14 +969,17 @@ impl Display {
} else {
None
};
let mut dirty = vi_highlighted_hint != self.vi_highlighted_hint;
self.vi_highlighted_hint = vi_highlighted_hint;
if vi_highlighted_hint != self.vi_highlighted_hint {
Self::damage_highlighted_hint(term, &vi_highlighted_hint);
Self::damage_highlighted_hint(term, &self.vi_highlighted_hint);
self.vi_highlighted_hint = vi_highlighted_hint;
}

// Abort if mouse highlighting conditions are not met.
if !mouse.inside_text_area || !term.selection.as_ref().map_or(true, Selection::is_empty) {
dirty |= self.highlighted_hint.is_some();
Self::damage_highlighted_hint(term, &self.highlighted_hint);
self.highlighted_hint = None;
return dirty;
return;
}

// Find highlighted hint at mouse position.
Expand All @@ -1001,7 +990,9 @@ impl Display {
if highlighted_hint.is_some() {
// If mouse changed the line, we should update the hyperlink preview, since the
// highlighted hint could be disrupted by the old preview.
dirty = self.hint_mouse_point.map(|p| p.line != point.line).unwrap_or(false);
if self.hint_mouse_point.map(|p| p.line != point.line).unwrap_or(false) {
term.mark_fully_damaged();
}
self.hint_mouse_point = Some(point);
self.window.set_mouse_cursor(CursorIcon::Hand);
} else if self.highlighted_hint.is_some() {
Expand All @@ -1013,10 +1004,11 @@ impl Display {
}
}

dirty |= self.highlighted_hint != highlighted_hint;
self.highlighted_hint = highlighted_hint;

dirty
if highlighted_hint != self.highlighted_hint {
Self::damage_highlighted_hint(term, &highlighted_hint);
Self::damage_highlighted_hint(term, &self.highlighted_hint);
self.highlighted_hint = highlighted_hint;
}
}

/// Format search regex to account for the cursor and fullwidth characters.
Expand Down Expand Up @@ -1212,12 +1204,12 @@ impl Display {
DamageRect { x, y, width, height: size_info.cell_height() }
}

/// Damage currently highlighted `Display` hints.
/// Damage a highlighted hint.
#[inline]
fn damage_highlighted_hints<T: EventListener>(&self, terminal: &mut Term<T>) {
fn damage_highlighted_hint<T>(terminal: &mut Term<T>, hint: &Option<HintMatch>) {
let display_offset = terminal.grid().display_offset();
let last_visible_line = terminal.screen_lines() - 1;
for hint in self.highlighted_hint.iter().chain(&self.vi_highlighted_hint) {
if let Some(hint) = hint {
for point in
(hint.bounds().start().line.0..=hint.bounds().end().line.0).flat_map(|line| {
term::point_to_viewport(display_offset, Point::new(Line(line), Column(0)))
Expand Down
50 changes: 25 additions & 25 deletions alacritty/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,9 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon

self.terminal.scroll_display(scroll);

// The cursor might have moved onto a hint.
self.mouse_mut().hint_highlight_dirty = true;

// Keep track of manual display offset changes during search.
if self.search_active() {
let display_offset = self.terminal.grid().display_offset();
Expand All @@ -235,8 +238,6 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon
let point = self.mouse.point(&self.size_info(), display_offset);
self.update_selection(point, self.mouse.cell_side);
}

*self.dirty = true;
}

// Copy text selection.
Expand All @@ -259,7 +260,6 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon

fn clear_selection(&mut self) {
self.terminal.selection = None;
*self.dirty = true;
}

fn update_selection(&mut self, mut point: Point, side: Side) {
Expand All @@ -281,12 +281,10 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon
}

self.terminal.selection = Some(selection);
*self.dirty = true;
}

fn start_selection(&mut self, ty: SelectionType, point: Point, side: Side) {
self.terminal.selection = Some(Selection::new(ty, point, side));
*self.dirty = true;

self.copy_selection(ClipboardType::Selection);
}
Expand All @@ -298,7 +296,6 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon
},
Some(selection) if !selection.is_empty() => {
selection.ty = ty;
*self.dirty = true;

self.copy_selection(ClipboardType::Selection);
},
Expand Down Expand Up @@ -648,15 +645,7 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon
#[inline]
fn on_typing_start(&mut self) {
// Disable cursor blinking.
let timer_id = TimerId::new(Topic::BlinkCursor, self.display.window.id());
if self.scheduler.unschedule(timer_id).is_some() {
self.schedule_blinking();
self.display.cursor_hidden = false;
} else if *self.cursor_blink_timed_out {
self.update_cursor_blinking();
}

*self.dirty = true;
self.update_cursor_blinking();

// Hide mouse cursor.
if self.config.mouse.hide_when_typing {
Expand All @@ -670,7 +659,6 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon
self.mouse.block_hint_launcher = false;
self.trigger_hint(&hint);
}
*self.dirty = true;
}

/// Trigger a hint action.
Expand Down Expand Up @@ -714,6 +702,9 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon
}

self.terminal.vi_goto_point(*hint_bounds.start());

// The vi cursor might have moved onto a hint.
self.mouse_mut().hint_highlight_dirty = true;
},
}
}
Expand Down Expand Up @@ -797,7 +788,7 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon

self.terminal.toggle_vi_mode();

*self.dirty = true;
self.mouse_mut().hint_highlight_dirty = true;
}

fn message(&self) -> Option<&Message> {
Expand Down Expand Up @@ -961,7 +952,9 @@ impl<'a, N: Notify + 'a, T: EventListener> ActionContext<'a, N, T> {
if blinking && self.terminal.is_focused {
self.schedule_blinking();
self.schedule_blinking_timeout();
} else {
}

if self.display.cursor_hidden {
self.display.cursor_hidden = false;
*self.dirty = true;
}
Expand Down Expand Up @@ -1072,6 +1065,8 @@ impl input::Processor<EventProxy, ActionContext<'_, Notifier, EventProxy>> {
display_update_pending.set_dimensions(PhysicalSize::new(width, height));

self.ctx.window().scale_factor = scale_factor;
// Possible layout change so the hint highlight must be updated.
self.ctx.mouse_mut().hint_highlight_dirty = true;
*self.ctx.dirty = true;
},
EventType::SearchNext => self.ctx.goto_match(None),
Expand All @@ -1084,14 +1079,18 @@ impl input::Processor<EventProxy, ActionContext<'_, Notifier, EventProxy>> {
// Disable blinking after timeout reached.
let timer_id = TimerId::new(Topic::BlinkCursor, self.ctx.display.window.id());
self.ctx.scheduler.unschedule(timer_id);
self.ctx.display.cursor_hidden = false;
*self.ctx.cursor_blink_timed_out = true;
*self.ctx.dirty = true;
if self.ctx.display.cursor_hidden {
self.ctx.display.cursor_hidden = false;
*self.ctx.dirty = true;
}
},
EventType::Message(message) => {
self.ctx.message_buffer.push(message);
self.ctx.display.pending_update.dirty = true;
*self.ctx.dirty = true;
// Possible layout change so the hint highlight must be updated.
self.ctx.mouse_mut().hint_highlight_dirty = true;
},
EventType::Terminal(event) => match event {
TerminalEvent::Title(title) => {
Expand Down Expand Up @@ -1163,6 +1162,8 @@ impl input::Processor<EventProxy, ActionContext<'_, Notifier, EventProxy>> {

self.ctx.display.pending_update.set_dimensions(size);
*self.ctx.dirty = true;
// Possible layout change so the hint highlight must be updated.
self.ctx.mouse_mut().hint_highlight_dirty = true;
},
WindowEvent::KeyboardInput { input, is_synthetic: false, .. } => {
self.key_input(input);
Expand All @@ -1172,7 +1173,6 @@ impl input::Processor<EventProxy, ActionContext<'_, Notifier, EventProxy>> {
WindowEvent::MouseInput { state, button, .. } => {
self.ctx.window().set_mouse_visible(true);
self.mouse_input(state, button);
*self.ctx.dirty = true;
},
WindowEvent::CursorMoved { position, .. } => {
self.ctx.window().set_mouse_visible(true);
Expand All @@ -1184,6 +1184,9 @@ impl input::Processor<EventProxy, ActionContext<'_, Notifier, EventProxy>> {
},
WindowEvent::Focused(is_focused) => {
self.ctx.terminal.is_focused = is_focused;

// The cursor shape can change with the focus state, see
// RenderableContent::new.
*self.ctx.dirty = true;

if is_focused {
Expand All @@ -1201,10 +1204,7 @@ impl input::Processor<EventProxy, ActionContext<'_, Notifier, EventProxy>> {
},
WindowEvent::CursorLeft { .. } => {
self.ctx.mouse.inside_text_area = false;

if self.ctx.display().highlighted_hint.is_some() {
*self.ctx.dirty = true;
}
self.ctx.mouse.hint_highlight_dirty = true;
},
WindowEvent::KeyboardInput { is_synthetic: true, .. }
| WindowEvent::TouchpadPressure { .. }
Expand Down
Loading