aboutsummaryrefslogtreecommitdiff
path: root/alacritty/src/display/content.rs
diff options
context:
space:
mode:
authorKirill Chibisov <contact@kchibisov.com>2022-02-02 00:12:58 +0300
committerGitHub <noreply@github.com>2022-02-02 00:12:58 +0300
commit8f1abe13e6b80da181ee856e6d5a19c7731dbedc (patch)
treeafab9579c3fb1019cdda9fb7d006a51ebcd929d6 /alacritty/src/display/content.rs
parentd58dff18effc204d7fc9f05dac9d0b25be26ee1a (diff)
downloadr-alacritty-8f1abe13e6b80da181ee856e6d5a19c7731dbedc.tar.gz
r-alacritty-8f1abe13e6b80da181ee856e6d5a19c7731dbedc.tar.bz2
r-alacritty-8f1abe13e6b80da181ee856e6d5a19c7731dbedc.zip
Add damage tracking and reporting to compatible compositors
This allows compositors to only process damaged (that is, updated) regions of our window buffer, which for larger window sizes (think 4k) should significantly reduce compositing workload under compositors that support/honor it, which is good for performance, battery life and lower latency over remote connections like VNC. On Wayland, clients are expected to always report correct damage, so this makes us a good citizen there. It can also aid remote desktop (waypipe, rdp, vnc, ...) and other types of screencopy by having damage bubble up correctly. Fixes #3186.
Diffstat (limited to 'alacritty/src/display/content.rs')
-rw-r--r--alacritty/src/display/content.rs53
1 files changed, 31 insertions, 22 deletions
diff --git a/alacritty/src/display/content.rs b/alacritty/src/display/content.rs
index 72d79f7e..3b549992 100644
--- a/alacritty/src/display/content.rs
+++ b/alacritty/src/display/content.rs
@@ -7,6 +7,7 @@ use alacritty_terminal::ansi::{Color, CursorShape, NamedColor};
use alacritty_terminal::event::EventListener;
use alacritty_terminal::grid::{Dimensions, Indexed};
use alacritty_terminal::index::{Column, Direction, Line, Point};
+use alacritty_terminal::selection::SelectionRange;
use alacritty_terminal::term::cell::{Cell, Flags};
use alacritty_terminal::term::color::{CellRgb, Rgb};
use alacritty_terminal::term::search::{Match, RegexIter, RegexSearch};
@@ -26,7 +27,7 @@ pub const MIN_CURSOR_CONTRAST: f64 = 1.5;
/// This provides the terminal cursor and an iterator over all non-empty cells.
pub struct RenderableContent<'a> {
terminal_content: TerminalContent<'a>,
- cursor: Option<RenderableCursor>,
+ cursor: RenderableCursor,
cursor_shape: CursorShape,
cursor_point: Point<usize>,
search: Option<Regex<'a>>,
@@ -73,7 +74,7 @@ impl<'a> RenderableContent<'a> {
Self {
colors: &display.colors,
- cursor: None,
+ cursor: RenderableCursor::new_hidden(),
terminal_content,
focused_match,
cursor_shape,
@@ -90,7 +91,7 @@ impl<'a> RenderableContent<'a> {
}
/// Get the terminal cursor.
- pub fn cursor(mut self) -> Option<RenderableCursor> {
+ pub fn cursor(mut self) -> RenderableCursor {
// Assure this function is only called after the iterator has been drained.
debug_assert!(self.next().is_none());
@@ -102,14 +103,14 @@ 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.
///
/// This will return `None` when there is no cursor visible.
- fn renderable_cursor(&mut self, cell: &RenderableCell) -> Option<RenderableCursor> {
- if self.cursor_shape == CursorShape::Hidden {
- return None;
- }
-
+ fn renderable_cursor(&mut self, cell: &RenderableCell) -> RenderableCursor {
// Cursor colors.
let color = if self.terminal_content.mode.contains(TermMode::VI) {
self.config.colors.vi_mode_cursor
@@ -134,13 +135,13 @@ impl<'a> RenderableContent<'a> {
text_color = self.config.colors.primary.background;
}
- Some(RenderableCursor {
+ RenderableCursor {
is_wide: cell.flags.contains(Flags::WIDE_CHAR),
shape: self.cursor_shape,
point: self.cursor_point,
cursor_color,
text_color,
- })
+ }
}
}
@@ -159,18 +160,15 @@ impl<'a> Iterator for RenderableContent<'a> {
if self.cursor_point == cell.point {
// Store the cursor which should be rendered.
- self.cursor = self.renderable_cursor(&cell).map(|cursor| {
- if cursor.shape == CursorShape::Block {
- cell.fg = cursor.text_color;
- cell.bg = cursor.cursor_color;
-
- // Since we draw Block cursor by drawing cell below it with a proper color,
- // we must adjust alpha to make it visible.
- cell.bg_alpha = 1.;
- }
-
- cursor
- });
+ self.cursor = self.renderable_cursor(&cell);
+ if self.cursor.shape == CursorShape::Block {
+ cell.fg = self.cursor.text_color;
+ cell.bg = self.cursor.cursor_color;
+
+ // Since we draw Block cursor by drawing cell below it with a proper color,
+ // we must adjust alpha to make it visible.
+ cell.bg_alpha = 1.;
+ }
return Some(cell);
} else if !cell.is_empty() && !cell.flags.contains(Flags::WIDE_CHAR_SPACER) {
@@ -372,6 +370,17 @@ pub struct RenderableCursor {
}
impl RenderableCursor {
+ fn new_hidden() -> Self {
+ let shape = CursorShape::Hidden;
+ let cursor_color = Rgb::default();
+ let text_color = Rgb::default();
+ let is_wide = false;
+ let point = Point::default();
+ Self { shape, cursor_color, text_color, is_wide, point }
+ }
+}
+
+impl RenderableCursor {
pub fn color(&self) -> Rgb {
self.cursor_color
}