aboutsummaryrefslogtreecommitdiff
path: root/alacritty/src/display/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty/src/display/mod.rs')
-rw-r--r--alacritty/src/display/mod.rs171
1 files changed, 165 insertions, 6 deletions
diff --git a/alacritty/src/display/mod.rs b/alacritty/src/display/mod.rs
index 1fdc5ac1..5bd0a097 100644
--- a/alacritty/src/display/mod.rs
+++ b/alacritty/src/display/mod.rs
@@ -16,6 +16,7 @@ use glutin::window::CursorIcon;
use glutin::Rect as DamageRect;
use log::{debug, info};
use parking_lot::MutexGuard;
+use serde::{Deserialize, Serialize};
use unicode_width::UnicodeWidthChar;
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
use wayland_client::EventQueue;
@@ -24,15 +25,13 @@ use crossfont::{self, Rasterize, Rasterizer};
use alacritty_terminal::ansi::NamedColor;
use alacritty_terminal::config::MAX_SCROLLBACK_LINES;
-use alacritty_terminal::event::{EventListener, OnResize};
-use alacritty_terminal::grid::Dimensions as _;
+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::term::cell::Flags;
use alacritty_terminal::term::color::Rgb;
-use alacritty_terminal::term::{
- SizeInfo, Term, TermDamage, TermMode, MIN_COLUMNS, MIN_SCREEN_LINES,
-};
+use alacritty_terminal::term::{Term, TermDamage, TermMode, MIN_COLUMNS, MIN_SCREEN_LINES};
use crate::config::font::Font;
#[cfg(not(windows))]
@@ -135,6 +134,166 @@ impl From<glutin::ContextError> for Error {
}
}
+/// Terminal size info.
+#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq)]
+pub struct SizeInfo<T = f32> {
+ /// Terminal window width.
+ width: T,
+
+ /// Terminal window height.
+ height: T,
+
+ /// Width of individual cell.
+ cell_width: T,
+
+ /// Height of individual cell.
+ cell_height: T,
+
+ /// Horizontal window padding.
+ padding_x: T,
+
+ /// Vertical window padding.
+ padding_y: T,
+
+ /// Number of lines in the viewport.
+ screen_lines: usize,
+
+ /// Number of columns in the viewport.
+ columns: usize,
+}
+
+impl From<SizeInfo<f32>> for SizeInfo<u32> {
+ fn from(size_info: SizeInfo<f32>) -> Self {
+ Self {
+ width: size_info.width as u32,
+ height: size_info.height as u32,
+ cell_width: size_info.cell_width as u32,
+ cell_height: size_info.cell_height as u32,
+ padding_x: size_info.padding_x as u32,
+ padding_y: size_info.padding_y as u32,
+ screen_lines: size_info.screen_lines,
+ columns: size_info.screen_lines,
+ }
+ }
+}
+
+impl From<SizeInfo<f32>> for WindowSize {
+ fn from(size_info: SizeInfo<f32>) -> Self {
+ Self {
+ num_cols: size_info.columns() as u16,
+ num_lines: size_info.screen_lines() as u16,
+ cell_width: size_info.cell_width() as u16,
+ cell_height: size_info.cell_width() as u16,
+ }
+ }
+}
+
+impl<T: Clone + Copy> SizeInfo<T> {
+ #[inline]
+ pub fn width(&self) -> T {
+ self.width
+ }
+
+ #[inline]
+ pub fn height(&self) -> T {
+ self.height
+ }
+
+ #[inline]
+ pub fn cell_width(&self) -> T {
+ self.cell_width
+ }
+
+ #[inline]
+ pub fn cell_height(&self) -> T {
+ self.cell_height
+ }
+
+ #[inline]
+ pub fn padding_x(&self) -> T {
+ self.padding_x
+ }
+
+ #[inline]
+ pub fn padding_y(&self) -> T {
+ self.padding_y
+ }
+}
+
+impl SizeInfo<f32> {
+ #[allow(clippy::too_many_arguments)]
+ pub fn new(
+ width: f32,
+ height: f32,
+ cell_width: f32,
+ cell_height: f32,
+ mut padding_x: f32,
+ mut padding_y: f32,
+ dynamic_padding: bool,
+ ) -> SizeInfo {
+ if dynamic_padding {
+ padding_x = Self::dynamic_padding(padding_x.floor(), width, cell_width);
+ padding_y = Self::dynamic_padding(padding_y.floor(), height, cell_height);
+ }
+
+ let lines = (height - 2. * padding_y) / cell_height;
+ let screen_lines = cmp::max(lines as usize, MIN_SCREEN_LINES);
+
+ let columns = (width - 2. * padding_x) / cell_width;
+ let columns = cmp::max(columns as usize, MIN_COLUMNS);
+
+ SizeInfo {
+ width,
+ height,
+ cell_width,
+ cell_height,
+ padding_x: padding_x.floor(),
+ padding_y: padding_y.floor(),
+ screen_lines,
+ columns,
+ }
+ }
+
+ #[inline]
+ pub fn reserve_lines(&mut self, count: usize) {
+ self.screen_lines = cmp::max(self.screen_lines.saturating_sub(count), MIN_SCREEN_LINES);
+ }
+
+ /// Check if coordinates are inside the terminal grid.
+ ///
+ /// The padding, message bar or search are not counted as part of the grid.
+ #[inline]
+ pub fn contains_point(&self, x: usize, y: usize) -> bool {
+ x <= (self.padding_x + self.columns as f32 * self.cell_width) as usize
+ && x > self.padding_x as usize
+ && y <= (self.padding_y + self.screen_lines as f32 * self.cell_height) as usize
+ && y > self.padding_y as usize
+ }
+
+ /// Calculate padding to spread it evenly around the terminal content.
+ #[inline]
+ fn dynamic_padding(padding: f32, dimension: f32, cell_dimension: f32) -> f32 {
+ padding + ((dimension - 2. * padding) % cell_dimension) / 2.
+ }
+}
+
+impl TermDimensions for SizeInfo {
+ #[inline]
+ fn columns(&self) -> usize {
+ self.columns
+ }
+
+ #[inline]
+ fn screen_lines(&self) -> usize {
+ self.screen_lines
+ }
+
+ #[inline]
+ fn total_lines(&self) -> usize {
+ self.screen_lines()
+ }
+}
+
#[derive(Default, Clone, Debug, PartialEq)]
pub struct DisplayUpdate {
pub dirty: bool,
@@ -456,7 +615,7 @@ impl Display {
self.size_info.reserve_lines(message_bar_lines + search_lines);
// Resize PTY.
- pty_resize_handle.on_resize(&self.size_info);
+ pty_resize_handle.on_resize(self.size_info.into());
// Resize terminal.
terminal.resize(self.size_info);