diff options
59 files changed, 484 insertions, 597 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 0688a7cf..a7f130a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Configuration file option for sourcing other files (`import`) - CLI parameter `--option`/`-o` to override any configuration field - Escape sequences to report text area size in pixels (`CSI 14 t`) and in characters (`CSI 18 t`) +- Support for single line terminals dimensions ### Changed @@ -45,6 +46,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Crash due to fd leak on Wayland - IME window position with fullwidth characters in the search bar - Selection expanding over 2 characters when scrolled in history with fullwidth characters in use +- Selection scrolling not starting when mouse is over the message bar ## 0.5.0 diff --git a/alacritty.yml b/alacritty.yml index ac4477fc..fd13c2b9 100644 --- a/alacritty.yml +++ b/alacritty.yml @@ -23,8 +23,9 @@ #window: # Window dimensions (changes require restart) # - # Specified in number of columns/lines, not pixels. - # If both are `0`, this setting is ignored. + # Number of lines/columns (not pixels) in the terminal. The number of columns + # must be at least `2`, while using a value of `0` for columns and lines will + # fall back to the window manager's recommended size. #dimensions: # columns: 0 # lines: 0 diff --git a/alacritty/src/cli.rs b/alacritty/src/cli.rs index 047c8d2e..6303d081 100644 --- a/alacritty/src/cli.rs +++ b/alacritty/src/cli.rs @@ -205,10 +205,10 @@ impl Options { } if let Some(mut dimensions) = matches.values_of("dimensions") { - let width = dimensions.next().map(|w| w.parse().map(Column)); - let height = dimensions.next().map(|h| h.parse().map(Line)); - if let (Some(Ok(width)), Some(Ok(height))) = (width, height) { - options.dimensions = Some(Dimensions::new(width, height)); + let columns = dimensions.next().map(|columns| columns.parse().map(Column)); + let lines = dimensions.next().map(|lines| lines.parse().map(Line)); + if let (Some(Ok(columns)), Some(Ok(lines))) = (columns, lines) { + options.dimensions = Some(Dimensions { columns, lines }); } } @@ -309,7 +309,10 @@ impl Options { let dynamic_title = config.ui_config.dynamic_title() && self.title.is_none(); config.ui_config.set_dynamic_title(dynamic_title); - replace_if_some(&mut config.ui_config.window.dimensions, self.dimensions); + if let Some(dimensions) = self.dimensions { + config.ui_config.window.set_dimensions(dimensions); + } + replace_if_some(&mut config.ui_config.window.title, self.title.clone()); replace_if_some(&mut config.ui_config.window.class.instance, self.class_instance.clone()); replace_if_some(&mut config.ui_config.window.class.general, self.class_general.clone()); diff --git a/alacritty/src/config/window.rs b/alacritty/src/config/window.rs index f866e180..d2e5da68 100644 --- a/alacritty/src/config/window.rs +++ b/alacritty/src/config/window.rs @@ -15,26 +15,14 @@ pub const DEFAULT_NAME: &str = "Alacritty"; #[serde(default)] #[derive(Deserialize, Debug, Clone, PartialEq, Eq)] pub struct WindowConfig { - /// Initial dimensions. - #[serde(deserialize_with = "failure_default")] - pub dimensions: Dimensions, - /// Initial position. #[serde(deserialize_with = "failure_default")] pub position: Option<Delta<i32>>, - /// Pixel padding. - #[serde(deserialize_with = "failure_default")] - pub padding: Delta<u8>, - /// Draw the window with title bar / borders. #[serde(deserialize_with = "failure_default")] pub decorations: Decorations, - /// Spread out additional padding evenly. - #[serde(deserialize_with = "failure_default")] - pub dynamic_padding: bool, - /// Startup mode. #[serde(deserialize_with = "failure_default")] pub startup_mode: StartupMode, @@ -55,9 +43,21 @@ pub struct WindowConfig { #[serde(deserialize_with = "option_explicit_none")] pub gtk_theme_variant: Option<String>, + /// Spread out additional padding evenly. + #[serde(deserialize_with = "failure_default")] + pub dynamic_padding: bool, + + /// Pixel padding. + #[serde(deserialize_with = "failure_default")] + padding: Delta<u8>, + /// Use dynamic title. #[serde(default, deserialize_with = "failure_default")] dynamic_title: DefaultTrueBool, + + /// Initial dimensions. + #[serde(deserialize_with = "failure_default")] + dimensions: Dimensions, } pub fn default_title() -> String { @@ -74,6 +74,30 @@ impl WindowConfig { pub fn set_dynamic_title(&mut self, dynamic_title: bool) { self.dynamic_title.0 = dynamic_title; } + + #[inline] + pub fn set_dimensions(&mut self, dimensions: Dimensions) { + self.dimensions = dimensions; + } + + #[inline] + pub fn dimensions(&self) -> Option<Dimensions> { + if self.dimensions.columns.0 != 0 + && self.dimensions.lines.0 != 0 + && self.startup_mode != StartupMode::Maximized + { + Some(self.dimensions) + } else { + None + } + } + + #[inline] + pub fn padding(&self, dpr: f64) -> (f32, f32) { + let padding_x = (f32::from(self.padding.x) * dpr as f32).floor(); + let padding_y = (f32::from(self.padding.y) * dpr as f32).floor(); + (padding_x, padding_y) + } } impl Default for WindowConfig { @@ -137,29 +161,11 @@ impl Default for Decorations { pub struct Dimensions { /// Window width in character columns. #[serde(deserialize_with = "failure_default")] - columns: Column, + pub columns: Column, /// Window Height in character lines. #[serde(deserialize_with = "failure_default")] - lines: Line, -} - -impl Dimensions { - pub fn new(columns: Column, lines: Line) -> Self { - Dimensions { columns, lines } - } - - /// Get lines. - #[inline] - pub fn lines_u32(&self) -> u32 { - self.lines.0 as u32 - } - - /// Get columns. - #[inline] - pub fn columns_u32(&self) -> u32 { - self.columns.0 as u32 - } + pub lines: Line, } /// Window class hint. diff --git a/alacritty/src/display.rs b/alacritty/src/display.rs index ca5bfe34..0b493936 100644 --- a/alacritty/src/display.rs +++ b/alacritty/src/display.rs @@ -25,12 +25,13 @@ use crossfont::set_font_smoothing; use crossfont::{self, Rasterize, Rasterizer}; use alacritty_terminal::event::{EventListener, OnResize}; -use alacritty_terminal::index::{Column, Direction, Line, Point}; +use alacritty_terminal::index::{Column, Direction, Point}; use alacritty_terminal::selection::Selection; use alacritty_terminal::term::{RenderableCell, SizeInfo, Term, TermMode}; +use alacritty_terminal::term::{MIN_COLS, MIN_SCREEN_LINES}; use crate::config::font::Font; -use crate::config::window::StartupMode; +use crate::config::window::{Dimensions, StartupMode}; use crate::config::Config; use crate::event::{Mouse, SearchState}; use crate::message_bar::{MessageBuffer, MessageType}; @@ -109,8 +110,8 @@ pub struct DisplayUpdate { pub dirty: bool, dimensions: Option<PhysicalSize<u32>>, - font: Option<Font>, cursor_dirty: bool, + font: Option<Font>, } impl DisplayUpdate { @@ -171,16 +172,15 @@ impl Display { let metrics = GlyphCache::static_metrics(config.ui_config.font.clone(), estimated_dpr)?; let (cell_width, cell_height) = compute_cell_size(config, &metrics); - let dimensions = GlyphCache::calculate_dimensions( - &config.ui_config.window, - estimated_dpr, - cell_width, - cell_height, - ); + // Guess the target window size if the user has specified the number of lines/columns. + let dimensions = config.ui_config.window.dimensions(); + let estimated_size = dimensions.map(|dimensions| { + window_size(config, dimensions, cell_width, cell_height, estimated_dpr) + }); debug!("Estimated DPR: {}", estimated_dpr); - debug!("Estimated Cell Size: {} x {}", cell_width, cell_height); - debug!("Estimated Dimensions: {:?}", dimensions); + debug!("Estimated window size: {:?}", estimated_size); + debug!("Estimated cell size: {} x {}", cell_width, cell_height); #[cfg(not(any(target_os = "macos", windows)))] let mut wayland_event_queue = None; @@ -192,20 +192,16 @@ impl Display { wayland_event_queue = Some(display.create_event_queue()); } - // Create the window where Alacritty will be displayed. - let size = dimensions.map(|(width, height)| PhysicalSize::new(width, height)); - - // Spawn window. + // Spawn the Alacritty window. let mut window = Window::new( event_loop, &config, - size, + estimated_size, #[cfg(not(any(target_os = "macos", windows)))] wayland_event_queue.as_ref(), )?; - let dpr = window.scale_factor(); - info!("Device pixel ratio: {}", dpr); + info!("Device pixel ratio: {}", window.dpr); // get window properties for initializing the other subsystems. let viewport_size = window.inner_size(); @@ -214,43 +210,33 @@ impl Display { let mut renderer = QuadRenderer::new()?; let (glyph_cache, cell_width, cell_height) = - Self::new_glyph_cache(dpr, &mut renderer, config)?; - - let padding = config.ui_config.window.padding; - let mut padding_x = f32::from(padding.x) * dpr as f32; - let mut padding_y = f32::from(padding.y) * dpr as f32; + Self::new_glyph_cache(window.dpr, &mut renderer, config)?; - if let Some((width, height)) = - GlyphCache::calculate_dimensions(&config.ui_config.window, dpr, cell_width, cell_height) - { - let PhysicalSize { width: w, height: h } = window.inner_size(); - if w == width && h == height { + if let Some(dimensions) = dimensions { + if (estimated_dpr - window.dpr).abs() < f64::EPSILON { info!("Estimated DPR correctly, skipping resize"); } else { - window.set_inner_size(PhysicalSize::new(width, height)); + // Resize the window again if the DPR was not estimated correctly. + let size = window_size(config, dimensions, cell_width, cell_height, window.dpr); + window.set_inner_size(size); } - } else if config.ui_config.window.dynamic_padding { - // Make sure additional padding is spread evenly. - padding_x = dynamic_padding(padding_x, viewport_size.width as f32, cell_width); - padding_y = dynamic_padding(padding_y, viewport_size.height as f32, cell_height); } - padding_x = padding_x.floor(); - padding_y = padding_y.floor(); - - info!("Cell Size: {} x {}", cell_width, cell_height); - info!("Padding: {} x {}", padding_x, padding_y); + let padding = config.ui_config.window.padding(window.dpr); // Create new size with at least one column and row. - let size_info = SizeInfo { - dpr, - width: (viewport_size.width as f32).max(cell_width + 2. * padding_x), - height: (viewport_size.height as f32).max(cell_height + 2. * padding_y), + let size_info = SizeInfo::new( + viewport_size.width as f32, + viewport_size.height as f32, cell_width, cell_height, - padding_x, - padding_y, - }; + padding.0, + padding.1, + config.ui_config.window.dynamic_padding && dimensions.is_none(), + ); + + info!("Cell size: {} x {}", cell_width, cell_height); + info!("Padding: {} x {}", size_info.padding_x(), size_info.padding_y()); // Update OpenGL projection. renderer.resize(&size_info); @@ -345,20 +331,18 @@ impl Display { } /// Update font size and cell dimensions. - fn update_glyph_cache(&mut self, config: &Config, font: &Font) { - let size_info = &mut self.size_info; + /// + /// This will return a tuple of the cell width and height. + fn update_glyph_cache(&mut self, config: &Config, font: &Font) -> (f32, f32) { let cache = &mut self.glyph_cache; + let dpr = self.window.dpr; self.renderer.with_loader(|mut api| { - let _ = cache.update_font_size(font, size_info.dpr, &mut api); + let _ = cache.update_font_size(font, dpr, &mut api); }); - // Update cell size. - let (cell_width, cell_height) = compute_cell_size(config, &self.glyph_cache.font_metrics()); - size_info.cell_width = cell_width; - size_info.cell_height = cell_height; - - info!("Cell Size: {} x {}", cell_width, cell_height); + // Compute new cell sizes. + compute_cell_size(config, &self.glyph_cache.font_metrics()) } /// Clear glyph cache. @@ -381,63 +365,58 @@ impl Display { ) where T: EventListener, { + let (mut cell_width, mut cell_height) = + (self.size_info.cell_width(), self.size_info.cell_height()); + // Update font size and cell dimensions. if let Some(font) = update_pending.font() { - self.update_glyph_cache(config, font); + let cell_dimensions = self.update_glyph_cache(config, font); + cell_width = cell_dimensions.0; + cell_height = cell_dimensions.1; + + info!("Cell size: {} x {}", cell_width, cell_height); } else if update_pending.cursor_dirty() { self.clear_glyph_cache(); } - let cell_width = self.size_info.cell_width; - let cell_height = self.size_info.cell_height; - - // Recalculate padding. - let padding = config.ui_config.window.padding; - let mut padding_x = f32::from(padding.x) * self.size_info.dpr as f32; - let mut padding_y = f32::from(padding.y) * self.size_info.dpr as f32; - - // Update the window dimensions. - if let Some(size) = update_pending.dimensions() { - // Ensure we have at least one column and row. - self.size_info.width = (size.width as f32).max(cell_width + 2. * padding_x); - self.size_info.height = (size.height as f32).max(cell_height + 2. * padding_y); + let (mut width, mut height) = (self.size_info.width(), self.size_info.height()); + if let Some(dimensions) = update_pending.dimensions() { + width = dimensions.width as f32; + height = dimensions.height as f32; } - // Distribute excess padding equally on all sides. - if config.ui_config.window.dynamic_padding { - padding_x = dynamic_padding(padding_x, self.size_info.width, cell_width); - padding_y = dynamic_padding(padding_y, self.size_info.height, cell_height); - } + let padding = config.ui_config.window.padding(self.window.dpr); - self.size_info.padding_x = padding_x.floor() as f32; - self.size_info.padding_y = padding_y.floor() as f32; - - let mut pty_size = self.size_info; - - // Subtract message bar lines from pty size. - if let Some(message) = message_buffer.message() { - let lines = message.text(&self.size_info).len(); - pty_size.height -= pty_size.cell_height * lines as f32; - } + self.size_info = SizeInfo::new( + width, + height, + cell_width, + cell_height, + padding.0, + padding.1, + config.ui_config.window.dynamic_padding, + ); - // Add an extra line for the current search regex. - if search_active { - pty_size.height -= pty_size.cell_height; - } + // Update number of column/lines in the viewport. + let message_bar_lines = + message_buffer.message().map(|m| m.text(&self.size_info).len()).unwrap_or(0); + let search_lines = if search_active { 1 } else { 0 }; + self.size_info.reserve_lines(message_bar_lines + search_lines); // Resize PTY. - pty_resize_handle.on_resize(&pty_size); + pty_resize_handle.on_resize(&self.size_info); // Resize terminal. - terminal.resize(pty_size); + terminal.resize(self.size_info); // Resize renderer. - let physical = PhysicalSize::new(self.size_info.width as u32, self.size_info.height as u32); + let physical = + PhysicalSize::new(self.size_info.width() as u32, self.size_info.height() as u32); self.window.resize(physical); self.renderer.resize(&self.size_info); - info!("Padding: {} x {}", self.size_info.padding_x, self.size_info.padding_y); - info!("Width: {}, Height: {}", self.size_info.width, self.size_info.height); + info!("Padding: {} x {}", self.size_info.padding_x(), self.size_info.padding_y()); + info!("Width: {}, Height: {}", self.size_info.width(), self.size_info.height()); } /// Draw the screen. @@ -533,22 +512,21 @@ impl Display { let visual_bell_rect = RenderRect::new( 0., 0., - size_info.width, - size_info.height, + size_info.width(), + size_info.height(), config.bell().color, visual_bell_intensity as f32, ); rects.push(visual_bell_rect); } - let mut message_bar_lines = 0; if let Some(message) = message_buffer.message() { + let search_offset = if search_state.regex().is_some() { 1 } else { 0 }; let text = message.text(&size_info); - message_bar_lines = text.len(); // Create a new rectangle for the background. - let start_line = size_info.lines().0 - message_bar_lines; - let y = size_info.cell_height.mul_add(start_line as f32, size_info.padding_y); + let start_line = size_info.screen_lines() + search_offset; + let y = size_info.cell_height().mul_add(start_line.0 as f32, size_info.padding_y()); let color = match message.ty() { MessageType::Error => config.colors.normal().red, @@ -556,7 +534,7 @@ impl Display { }; let message_bar_rect = - RenderRect::new(0., y, size_info.width, size_info.height - y, color, 1.); + RenderRect::new(0., y, size_info.width(), size_info.height() - y, color, 1.); // Push message_bar in the end, so it'll be above all other content. rects.push(message_bar_rect); @@ -566,15 +544,9 @@ impl Display { // Relay messages to the user. let fg = config.colors.primary.background; - for (i, message_text) in text.iter().rev().enumerate() { + for (i, message_text) in text.iter().enumerate() { self.renderer.with_api(&config.ui_config, config.cursor, &size_info, |mut api| { - api.render_string( - glyph_cache, - Line(size_info.lines().saturating_sub(i + 1)), - &message_text, - fg, - None, - ); + api.render_string(glyph_cache, start_line + i, &message_text, fg, None); }); } } else { @@ -595,10 +567,10 @@ impl Display { let search_text = Self::format_search(&size_info, regex, search_label); // Render the search bar. - self.draw_search(config, &size_info, message_bar_lines, &search_text); + self.draw_search(config, &size_info, &search_text); // Compute IME position. - Point::new(size_info.lines() - 1, Column(search_text.chars().count() - 1)) + Point::new(size_info.screen_lines() + 1, Column(search_text.chars().count() - 1)) }, None => cursor_point, }; @@ -656,13 +628,7 @@ impl Display { } /// Draw current search regex. - fn draw_search( - &mut self, - config: &Config, - size_info: &SizeInfo, - message_bar_lines: usize, - text: &str, - ) { + fn draw_search(&mut self, config: &Config, size_info: &SizeInfo, text: &str) { let glyph_cache = &mut self.glyph_cache; let num_cols = size_info.cols().0; @@ -671,9 +637,8 @@ impl Display { let fg = config.colors.search_bar_foreground(); let bg = config.colors.search_bar_background(); - let line = size_info.lines() - message_bar_lines - 1; self.renderer.with_api(&config.ui_config, config.cursor, &size_info, |mut api| { - api.render_string(glyph_cache, line, &text, fg, Some(bg)); + api.render_string(glyph_cache, size_info.screen_lines(), &text, fg, Some(bg)); }); } @@ -689,7 +654,7 @@ impl Display { let bg = config.colors.normal().red; self.renderer.with_api(&config.ui_config, config.cursor, &size_info, |mut api| { - api.render_string(glyph_cache, size_info.lines() - 2, &timing[..], fg, Some(bg)); + api.render_string(glyph_cache, size_info.screen_lines() - 2, &timing[..], fg, Some(bg)); }); } @@ -714,13 +679,9 @@ impl Display { } } -/// 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. -} - /// Calculate the cell dimensions based on font metrics. +/// +/// This will return a tuple of the cell width and height. #[inline] fn compute_cell_size(config: &Config, metrics: &crossfont::Metrics) -> (f32, f32) { let offset_x = f64::from(config.ui_config.font.offset.x); @@ -730,3 +691,22 @@ fn compute_cell_size(config: &Config, metrics: &crossfont::Metrics) -> (f32, f32 ((metrics.line_height + offset_y) as f32).floor().max(1.), ) } + +/// Calculate the size of the window given padding, terminal dimensions and cell size. +fn window_size( + config: &Config, + dimensions: Dimensions, + cell_width: f32, + cell_height: f32, + dpr: f64, +) -> PhysicalSize<u32> { + let padding = config.ui_config.window.padding(dpr); + + let grid_width = cell_width * dimensions.columns.0.max(MIN_COLS) as f32; + let grid_height = cell_height * dimensions.lines.0.max(MIN_SCREEN_LINES) as f32; + + let width = (padding.0).mul_add(2., grid_width).floor(); + let height = (padding.1).mul_add(2., grid_height).floor(); + + PhysicalSize::new(width as u32, height as u32) +} diff --git a/alacritty/src/event.rs b/alacritty/src/event.rs index e81dc0f9..e45795dd 100644 --- a/alacritty/src/event.rs +++ b/alacritty/src/event.rs @@ -410,14 +410,7 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon self.goto_match(None); } - // Move vi cursor down if resize will pull content from history. - if self.terminal.history_size() != 0 && self.terminal.grid().display_offset() == 0 { - self.terminal.vi_mode_cursor.point.line += 1; - } - - self.display_update_pending.dirty = true; - self.search_state.regex = None; - self.terminal.dirty = true; + self.exit_search(); } #[inline] @@ -429,14 +422,7 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon self.search_reset_state(); } - // Move vi cursor down if resize will pull from history. - if self.terminal.history_size() != 0 && self.terminal.grid().display_offset() == 0 { - self.terminal.vi_mode_cursor.point.line += 1; - } - - self.display_update_pending.dirty = true; - self.search_state.regex = None; - self.terminal.dirty = true; + self.exit_search(); } #[inline] @@ -628,6 +614,21 @@ impl<'a, N: Notify + 'a, T: EventListener> ActionContext<'a, N, T> { self.search_state.regex = Some(regex); } + /// Close the search bar. + fn exit_search(&mut self) { + // Move vi cursor down if resize will pull content from history. + if self.terminal.history_size() != 0 + && self.terminal.grid().display_offset() == 0 + && self.terminal.screen_lines() > self.terminal.vi_mode_cursor.point.line + 1 + { + self.terminal.vi_mode_cursor.point.line += 1; + } + + self.display_update_pending.dirty = true; + self.search_state.regex = None; + self.terminal.dirty = true; + } + /// Get the absolute position of the search origin. /// /// This takes the relative motion of the viewport since the start of the search into account. @@ -914,7 +915,7 @@ impl<N: Notify + OnResize> Processor<N> { // Resize to event's dimensions, since no resize event is emitted on Wayland. display_update_pending.set_dimensions(PhysicalSize::new(width, height)); - processor.ctx.size_info.dpr = scale_factor; + processor.ctx.window.dpr = scale_factor; processor.ctx.terminal.dirty = true; }, Event::Message(message) => { @@ -1098,7 +1099,7 @@ impl<N: Notify + OnResize> Processor<N> { // Update display if padding options were changed. let window_config = &processor.ctx.config.ui_config.window; - if window_config.padding != config.ui_config.window.padding + if window_config.padding(1.) != config.ui_config.window.padding(1.) || window_config.dynamic_padding != config.ui_config.window.dynamic_padding { processor.ctx.display_update_pending.dirty = true; diff --git a/alacritty/src/input.rs b/alacritty/src/input.rs index 351e164c..9c75753a 100644 --- a/alacritty/src/input.rs +++ b/alacritty/src/input.rs @@ -371,8 +371,8 @@ impl<'a, T: EventListener, A: ActionContext<T>> Processor<'a, T, A> { self.update_selection_scrolling(y); } - let x = min(max(x, 0), size_info.width as i32 - 1) as usize; - let y = min(max(y, 0), size_info.height as i32 - 1) as usize; + let x = min(max(x, 0), size_info.width() as i32 - 1) as usize; + let y = min(max(y, 0), size_info.height() as i32 - 1) as usize; self.ctx.mouse_mut().x = x; self.ctx.mouse_mut().y = y; @@ -384,6 +384,11 @@ impl<'a, T: EventListener, A: ActionContext<T>> Processor<'a, T, A> { let cell_changed = point.line != self.ctx.mouse().line || point.col != self.ctx.mouse().column; + // Update mouse state and check for URL change. + let mouse_state = self.mouse_state(); + self.update_url_state(&mouse_state); + self.ctx.window_mut().set_mouse_cursor(mouse_state.into()); + // If the mouse hasn't changed cells, do nothing. if !cell_changed && self.ctx.mouse().cell_side == cell_side @@ -400,11 +405,6 @@ impl<'a, T: EventListener, A: ActionContext<T>> Processor<'a, T, A> { // Don't launch URLs if mouse has moved. self.ctx.mouse_mut().block_url_launcher = true; - // Update mouse state and check for URL change. - let mouse_state = self.mouse_state(); - self.update_url_state(&mouse_state); - self.ctx.window_mut().set_mouse_cursor(mouse_state.into()); - if (lmb_pressed || rmb_pressed) && (self.ctx.modifiers().shift() || !self.ctx.mouse_mode()) && !search_active @@ -431,12 +431,13 @@ impl<'a, T: EventListener, A: ActionContext<T>> Processor<'a, T, A> { let size_info = self.ctx.size_info(); let x = self.ctx.mouse().x; - let cell_x = x.saturating_sub(size_info.padding_x as usize) % size_info.cell_width as usize; - let half_cell_width = (size_info.cell_width / 2.0) as usize; + let cell_x = + x.saturating_sub(size_info.padding_x() as usize) % size_info.cell_width() as usize; + let half_cell_width = (size_info.cell_width() / 2.0) as usize; let additional_padding = - (size_info.width - size_info.padding_x * 2.) % size_info.cell_width; - let end_of_grid = size_info.width - size_info.padding_x - additional_padding; + (size_info.width() - size_info.padding_x() * 2.) % size_info.cell_width(); + let end_of_grid = size_info.width() - size_info.padding_x() - additional_padding; if cell_x > half_cell_width // Edge case when mouse leaves the window. @@ -661,7 +662,7 @@ impl<'a, T: EventListener, A: ActionContext<T>> Processor<'a, T, A> { pub fn mouse_wheel_input(&mut self, delta: MouseScrollDelta, phase: TouchPhase) { match delta { MouseScrollDelta::LineDelta(_columns, lines) => { - let new_scroll_px = lines * self.ctx.size_info().cell_height; + let new_scroll_px = lines * self.ctx.size_info().cell_height(); self.scroll_terminal(f64::from(new_scroll_px)); }, MouseScrollDelta::PixelDelta(lpos) => { @@ -680,7 +681,7 @@ impl<'a, T: EventListener, A: ActionContext<T>> Processor<'a, T, A> { } fn scroll_terminal(&mut self, new_scroll_px: f64) { - let height = f64::from(self.ctx.size_info().cell_height); + let height = f64::from(self.ctx.size_info().cell_height()); if self.ctx.mouse_mode() { self.ctx.mouse_mut().scroll_px += new_scroll_px; @@ -764,13 +765,17 @@ impl<'a, T: EventListener, A: ActionContext<T>> Processor<'a, T, A> { } // Skip normal mouse events if the message bar has been clicked. - if self.message_close_at_cursor() && state == ElementState::Pressed { + if self.message_bar_mouse_state() == Some(MouseState::MessageBarButton) + && state == ElementState::Pressed + { + let size = self.ctx.size_info(); + + let current_lines = self.ctx.message().map(|m| m.text(&size).len()).unwrap_or(0); + self.ctx.clear_selection(); self.ctx.pop_message(); // Reset cursor when message bar height changed or all messages are gone. - let size = self.ctx.size_info(); - let current_lines = (size.lines() - self.ctx.terminal().screen_lines()).0; let new_lines = self.ctx.message().map(|m| m.text(&size).len()).unwrap_or(0); let new_icon = match current_lines.cmp(&new_lines) { @@ -976,21 +981,26 @@ impl<'a, T: EventListener, A: ActionContext<T>> Processor<'a, T, A> { } } - /// Check if the cursor is hovering above the message bar. - fn message_at_cursor(&mut self) -> bool { - self.ctx.mouse().line >= self.ctx.terminal().screen_lines() - } - - /// Whether the point is over the message bar's close button. - fn message_close_at_cursor(&self) -> bool { - let mouse = self.ctx.mouse(); - + /// Check mouse state in relation to the message bar. + fn message_bar_mouse_state(&self) -> Option<MouseState> { // Since search is above the message bar, the button is offset by search's height. let search_height = if self.ctx.search_active() { 1 } else { 0 }; - mouse.inside_text_area - && mouse.column + message_bar::CLOSE_BUTTON_TEXT.len() >= self.ctx.size_info().cols() - && mouse.line == self.ctx.terminal().screen_lines() + search_height + // Calculate Y position of the end of the last terminal line. + let size = self.ctx.size_info(); + let terminal_end = size.padding_y() as usize + + size.cell_height() as usize * (size.screen_lines().0 + search_height); + + let mouse = self.ctx.mouse(); + if self.ctx.message().is_none() || (mouse.y <= terminal_end) { + None + } else if mouse.y <= terminal_end + size.cell_height() as usize + && mouse.column + message_bar::CLOSE_BUTTON_TEXT.len() >= size.cols() + { + Some(MouseState::MessageBarButton) + } else { + Some(MouseState::MessageBar) + } } /// Copy text selection. @@ -1016,10 +1026,8 @@ impl<'a, T: EventListener, A: ActionContext<T>> Processor<'a, T, A> { /// Location of the mouse cursor. fn mouse_state(&mut self) -> MouseState { // Check message bar before URL to ignore URLs in the message bar. - if self.message_close_at_cursor() { - return MouseState::MessageBarButton; - } else if self.message_at_cursor() { - return MouseState::MessageBar; + if let Some(mouse_state) = self.message_bar_mouse_state() { + return mouse_state; } let mouse_mode = self.ctx.mouse_mode(); @@ -1048,17 +1056,18 @@ impl<'a, T: EventListener, A: ActionContext<T>> Processor<'a, T, A> { /// Handle automatic scrolling when selecting above/below the window. fn update_selection_scrolling(&mut self, mouse_y: i32) { - let size_info = self.ctx.size_info(); + let dpr = self.ctx.window().dpr; + let size = self.ctx.size_info(); let scheduler = self.ctx.scheduler_mut(); // Scale constants by DPI. - let min_height = (MIN_SELECTION_SCROLLING_HEIGHT * size_info.dpr) as i32; - let step = (SELECTION_SCROLLING_STEP * size_info.dpr) as i32; + let min_height = (MIN_SELECTION_SCROLLING_HEIGHT * dpr) as i32; + let step = (SELECTION_SCROLLING_STEP * dpr) as i32; // Compute the height of the scrolling areas. - let end_top = max(min_height, size_info.padding_y as i32); - let height_bottom = max(min_height, size_info.padding_bottom() as i32); - let start_bottom = size_info.height as i32 - height_bottom; + let end_top = max(min_height, size.padding_y() as i32); + let text_area_bottom = size.padding_y() + size.screen_lines().0 as f32 * size.cell_height(); + let start_bottom = min(size.height() as i32 - min_height, text_area_bottom as i32); // Get distance from closest window boundary. let delta = if mouse_y < end_top { @@ -1283,15 +1292,15 @@ mod tests { url: Default::default(), }; - let size = SizeInfo { - width: 21.0, - height: 51.0, - cell_width: 3.0, - cell_height: 3.0, - padding_x: 0., - padding_y: 0., - dpr: 1.0, - }; + let size = SizeInfo::new( + 21.0, + 51.0, + 3.0, + 3.0, + 0., + 0., + false, + ); let mut clipboard = Clipboard::new_nop(); diff --git a/alacritty/src/main.rs b/alacritty/src/main.rs index efd3e947..09296f60 100644 --- a/alacritty/src/main.rs +++ b/alacritty/src/main.rs @@ -138,7 +138,11 @@ fn run( // The display manages a window and can draw the terminal. let display = Display::new(&config, &window_event_loop)?; - info!("PTY dimensions: {:?} x {:?}", display.size_info.lines(), display.size_info.cols()); + info!( + "PTY dimensions: {:?} x {:?}", + display.size_info.screen_lines(), + display.size_info.cols() + ); // Create the terminal. // diff --git a/alacritty/src/message_bar.rs b/alacritty/src/message_bar.rs index 4c43c3d3..851cb6ee 100644 --- a/alacritty/src/message_bar.rs +++ b/alacritty/src/message_bar.rs @@ -34,7 +34,9 @@ impl Message { /// Formatted message text lines. pub fn text(&self, size_info: &SizeInfo) -> Vec<String> { let num_cols = size_info.cols().0; - let max_lines = size_info.lines().saturating_sub(MIN_FREE_LINES); + let total_lines = + (size_info.height() - 2. * size_info.padding_y()) / size_info.cell_height(); + let max_lines = (total_lines as usize).saturating_sub(MIN_FREE_LINES); let button_len = CLOSE_BUTTON_TEXT.len(); // Split line to fit the screen. @@ -169,7 +171,8 @@ impl MessageBuffer { #[cfg(test)] mod tests { - use super::{Message, MessageBuffer, MessageType, MIN_FREE_LINES}; + use super::*; + use alacritty_terminal::term::SizeInfo; #[test] @@ -177,15 +180,7 @@ mod tests { let input = "a"; let mut message_buffer = MessageBuffer::new(); message_buffer.push(Message::new(input.into(), MessageType::Error)); - let size = SizeInfo { - width: 7., - height: 10., - cell_width: 1., - cell_height: 1., - padding_x: 0., - padding_y: 0., - dpr: 0., - }; + let size = SizeInfo::new(7., 10., 1., 1., 0., 0., false); let lines = message_buffer.message().unwrap().text(&size); @@ -197,15 +192,7 @@ mod tests { let input = "fo\nbar"; let mut message_buffer = MessageBuffer::new(); message_buffer.push(Message::new(input.into(), MessageType::Error)); - let size = SizeInfo { - width: 6., - height: 10., - cell_width: 1., - cell_height: 1., - padding_x: 0., - padding_y: 0., - dpr: 0., - }; + let size = SizeInfo::new(6., 10., 1., 1., 0., 0., false); let lines = message_buffer.message().unwrap().text(&size); @@ -217,15 +204,7 @@ mod tests { let input = "a\nb"; let mut message_buffer = MessageBuffer::new(); message_buffer.push(Message::new(input.into(), MessageType::Error)); - let size = SizeInfo { - width: 6., - height: 10., - cell_width: 1., - cell_height: 1., - padding_x: 0., - padding_y: 0., - dpr: 0., - }; + let size = SizeInfo::new(6., 10., 1., 1., 0., 0., false); let lines = message_buffer.message().unwrap().text(&size); @@ -237,15 +216,7 @@ mod tests { let input = "foobar1"; let mut message_buffer = MessageBuffer::new(); message_buffer.push(Message::new(input.into(), MessageType::Error)); - let size = SizeInfo { - width: 6., - height: 10., - cell_width: 1., - cell_height: 1., - padding_x: 0., - padding_y: 0., - dpr: 0., - }; + let size = SizeInfo::new(6., 10., 1., 1., 0., 0., false); let lines = message_buffer.message().unwrap().text(&size); @@ -257,15 +228,7 @@ mod tests { let input = "foobar"; let mut message_buffer = MessageBuffer::new(); message_buffer.push(Message::new(input.into(), MessageType::Error)); - let size = SizeInfo { - width: 6., - height: 0., - cell_width: 1., - cell_height: 1., - padding_x: 0., - padding_y: 0., - dpr: 0., - }; + let size = SizeInfo::new(6., 0., 1., 1., 0., 0., false); let lines = message_buffer.message().unwrap().text(&size); @@ -277,15 +240,7 @@ mod tests { let input = "hahahahahahahahahahaha truncate this because it's too long for the term"; let mut message_buffer = MessageBuffer::new(); message_buffer.push(Message::new(input.into(), MessageType::Error)); - let size = SizeInfo { - width: 22., - height: (MIN_FREE_LINES + 2) as f32, - cell_width: 1., - cell_height: 1., - padding_x: 0., - padding_y: 0., - dpr: 0., - }; + let size = SizeInfo::new(22., (MIN_FREE_LINES + 2) as f32, 1., 1., 0., 0., false); let lines = message_buffer.message().unwrap().text(&size); @@ -300,15 +255,7 @@ mod tests { let input = "ha"; let mut message_buffer = MessageBuffer::new(); message_buffer.push(Message::new(input.into(), MessageType::Error)); - let size = SizeInfo { - width: 2., - height: 10., - cell_width: 1., - cell_height: 1., - padding_x: 0., - padding_y: 0., - dpr: 0., - }; + let size = SizeInfo::new(2., 10., 1., 1., 0., 0., false); let lines = message_buffer.message().unwrap().text(&size); @@ -320,15 +267,7 @@ mod tests { let input = "hahahahahahahahaha"; let mut message_buffer = MessageBuffer::new(); message_buffer.push(Message::new(input.into(), MessageType::Error)); - let size = SizeInfo { - width: 2., - height: (MIN_FREE_LINES + 2) as f32, - cell_width: 1., - cell_height: 1., - padding_x: 0., - padding_y: 0., - dpr: 0., - }; + let size = SizeInfo::new(2., (MIN_FREE_LINES + 2) as f32, 1., 1., 0., 0., false); let lines = message_buffer.message().unwrap().text(&size); @@ -340,15 +279,7 @@ mod tests { let input = "test"; let mut message_buffer = MessageBuffer::new(); message_buffer.push(Message::new(input.into(), MessageType::Error)); - let size = SizeInfo { - width: 5., - height: 10., - cell_width: 1., - cell_height: 1., - padding_x: 0., - padding_y: 0., - dpr: 0., - }; + let size = SizeInfo::new(5., 10., 1., 1., 0., 0., false); let lines = message_buffer.message().unwrap().text(&size); @@ -398,15 +329,7 @@ mod tests { let input = "a\nbc defg"; let mut message_buffer = MessageBuffer::new(); message_buffer.push(Message::new(input.into(), MessageType::Error)); - let size = SizeInfo { - width: 5., - height: 10., - cell_width: 1., - cell_height: 1., - padding_x: 0., - padding_y: 0., - dpr: 0., - }; + let size = SizeInfo::new(5., 10., 1., 1., 0., 0., false); let lines = message_buffer.message().unwrap().text(&size); diff --git a/alacritty/src/renderer/mod.rs b/alacritty/src/renderer/mod.rs index da5f68a0..e97ac025 100644 --- a/alacritty/src/renderer/mod.rs +++ b/alacritty/src/renderer/mod.rs @@ -26,7 +26,6 @@ use alacritty_terminal::thread; use crate::config::font::{Font, FontDescription}; use crate::config::ui_config::{Delta, UIConfig}; -use crate::config::window::{StartupMode, WindowConfig}; use crate::cursor; use crate::gl; use crate::gl::types::*; @@ -231,7 +230,7 @@ impl GlyphCache { if desc == regular_desc { regular } else { - rasterizer.load_font(&desc, size).unwrap_or_else(|_| regular) + rasterizer.load_font(&desc, size).unwrap_or(regular) } }; @@ -358,34 +357,6 @@ impl GlyphCache { rasterizer.metrics(regular, font.size) } - - pub fn calculate_dimensions( - window_config: &WindowConfig, - dpr: f64, - cell_width: f32, - cell_height: f32, - ) -> Option<(u32, u32)> { - let dimensions = window_config.dimensions; - - if dimensions.columns_u32() == 0 - || dimensions.lines_u32() == 0 - || window_config.startup_mode != StartupMode::Windowed - { - return None; - } - - let padding_x = f64::from(window_config.padding.x) * dpr; - let padding_y = f64::from(window_config.padding.y) * dpr; - - // Calculate new size based on cols/lines specified in config. - let grid_width = cell_width as u32 * dimensions.columns_u32(); - let grid_height = cell_height as u32 * dimensions.lines_u32(); - - let width = padding_x.mul_add(2., f64::from(grid_width)).floor(); - let height = padding_y.mul_add(2., f64::from(grid_height)).floor(); - - Some((width as u32, height as u32)) - } } #[derive(Debug)] @@ -705,7 +676,7 @@ impl QuadRenderer { gl::UseProgram(self.rect_program.id); // Remove padding from viewport. - gl::Viewport(0, 0, props.width as i32, props.height as i32); + gl::Viewport(0, 0, props.width() as i32, props.height() as i32); // Change blending strategy. gl::BlendFuncSeparate(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA, gl::SRC_ALPHA, gl::ONE); @@ -740,10 +711,10 @@ impl QuadRenderer { gl::BindBuffer(gl::ARRAY_BUFFER, 0); gl::BindVertexArray(0); - let padding_x = props.padding_x as i32; - let padding_y = props.padding_y as i32; - let width = props.width as i32; - let height = props.height as i32; + let padding_x = props.padding_x() as i32; + let padding_y = props.padding_y() as i32; + let width = props.width() as i32; + let height = props.height() as i32; gl::Viewport(padding_x, padding_y, width - 2 * padding_x, height - 2 * padding_y); // Disable program. @@ -821,10 +792,10 @@ impl QuadRenderer { unsafe { gl::UseProgram(program.id); program.update_projection( - props.width, - props.height, - props.padding_x, - props.padding_y, + props.width(), + props.height(), + props.padding_x(), + props.padding_y(), ); gl::UseProgram(0); } @@ -847,15 +818,20 @@ impl QuadRenderer { // Viewport. unsafe { gl::Viewport( - size.padding_x as i32, - size.padding_y as i32, - size.width as i32 - 2 * size.padding_x as i32, - size.height as i32 - 2 * size.padding_y as i32, + size.padding_x() as i32, + size.padding_y() as i32, + size.width() as i32 - 2 * size.padding_x() as i32, + size.height() as i32 - 2 * size.padding_y() as i32, ); // Update projection. gl::UseProgram(self.program.id); - self.program.update_projection(size.width, size.height, size.padding_x, size.padding_y); + self.program.update_projection( + size.width(), + size.height(), + size.padding_x(), + size.padding_y(), + ); gl::UseProgram(0); } } @@ -870,8 +846,8 @@ impl QuadRenderer { } // Calculate rectangle position. - let center_x = size.width / 2.; - let center_y = size.height / 2.; + let center_x = size.width() / 2.; + let center_y = size.height() / 2.; let x = (rect.x - center_x) / center_x; let y = -(rect.y - center_y) / center_y; let width = rect.width / center_x; @@ -1226,7 +1202,7 @@ impl TextShaderProgram { fn set_term_uniforms(&self, props: &SizeInfo) { unsafe { - gl::Uniform2f(self.u_cell_dim, props.cell_width, props.cell_height); + gl::Uniform2f(self.u_cell_dim, props.cell_width(), props.cell_height()); } } diff --git a/alacritty/src/renderer/rects.rs b/alacritty/src/renderer/rects.rs index 83b59cb3..ca0bbd1c 100644 --- a/alacritty/src/renderer/rects.rs +++ b/alacritty/src/renderer/rects.rs @@ -99,14 +99,14 @@ impl RenderLine { mut thickness: f32, color: Rgb, ) -> RenderRect { - let start_x = start.col.0 as f32 * size.cell_width; - let end_x = (end.col.0 + 1) as f32 * size.cell_width; + let start_x = start.col.0 as f32 * size.cell_width(); + let end_x = (end.col.0 + 1) as f32 * size.cell_width(); let width = end_x - start_x; // Make sure lines are always visible. thickness = thickness.max(1.); - let line_bottom = (start.line.0 as f32 + 1.) * size.cell_height; + let line_bottom = (start.line.0 as f32 + 1.) * size.cell_height(); let baseline = line_bottom + descent; let mut y = (baseline - position - thickness / 2.).ceil(); @@ -115,7 +115,14 @@ impl RenderLine { y = max_y; } - RenderRect::new(start_x + size.padding_x, y + size.padding_y, width, thickness, color, 1.) + RenderRect::new( + start_x + size.padding_x(), + y + size.padding_y(), + width, + thickness, + color, + 1., + ) } } diff --git a/alacritty/src/window.rs b/alacritty/src/window.rs index 3319dce8..92fedc86 100644 --- a/alacritty/src/window.rs +++ b/alacritty/src/window.rs @@ -137,6 +137,9 @@ pub struct Window { #[cfg(not(any(target_os = "macos", windows)))] pub wayland_surface: Option<Attached<WlSurface>>, + /// Cached DPR for quickly scaling pixel sizes. + pub dpr: f64, + windowed_context: WindowedContext<PossiblyCurrent>, current_mouse_cursor: CursorIcon, mouse_visible: bool, @@ -192,6 +195,8 @@ impl Window { wayland_surface = Some(proxy.attach(wayland_event_queue.as_ref().unwrap().token())); } + let dpr = windowed_context.window().scale_factor(); + Ok(Self { current_mouse_cursor, mouse_visible: true, @@ -200,6 +205,7 @@ impl Window { should_draw: Arc::new(AtomicBool::new(true)), #[cfg(not(any(target_os = "macos", windows)))] wayland_surface, + dpr, }) } @@ -211,10 +217,6 @@ impl Window { self.window().inner_size() } - pub fn scale_factor(&self) -> f64 { - self.window().scale_factor() - } - #[inline] pub fn set_visible(&self, visibility: bool) { self.window().set_visible(visibility); @@ -387,11 +389,9 @@ impl Window { /// Adjust the IME editor position according to the new location of the cursor. #[cfg(not(windows))] - pub fn update_ime_position(&mut self, point: Point, size_info: &SizeInfo) { - let SizeInfo { cell_width, cell_height, padding_x, padding_y, .. } = size_info; - - let nspot_x = f64::from(padding_x + point.col.0 as f32 * cell_width); - let nspot_y = f64::from(padding_y + (point.line.0 + 1) as f32 * cell_height); + pub fn update_ime_position(&mut self, point: Point, size: &SizeInfo) { + let nspot_x = f64::from(size.padding_x() + point.col.0 as f32 * size.cell_width()); + let nspot_y = f64::from(size.padding_y() + (point.line.0 + 1) as f32 * size.cell_height()); self.window().set_ime_position(PhysicalPosition::new(nspot_x, nspot_y)); } diff --git a/alacritty_terminal/src/ansi.rs b/alacritty_terminal/src/ansi.rs index 5038b734..91dd5f77 100644 --- a/alacritty_terminal/src/ansi.rs +++ b/alacritty_terminal/src/ansi.rs @@ -785,7 +785,7 @@ where fn unhandled(params: &[&[u8]]) { let mut buf = String::new(); for items in params { - buf.push_str("["); + buf.push('['); for item in *items { buf.push_str(&format!("{:?},", *item as char)); } diff --git a/alacritty_terminal/src/selection.rs b/alacritty_terminal/src/selection.rs index 450a4633..da44feac 100644 --- a/alacritty_terminal/src/selection.rs +++ b/alacritty_terminal/src/selection.rs @@ -409,15 +409,7 @@ mod tests { } fn term(height: usize, width: usize) -> Term<Mock> { - let size = SizeInfo { - width: width as f32, - height: height as f32, - cell_width: 1.0, - cell_height: 1.0, - padding_x: 0.0, - padding_y: 0.0, - dpr: 1.0, - }; + let size = SizeInfo::new(width as f32, height as f32, 1.0, 1.0, 0.0, 0.0, false); Term::new(&MockConfig::default(), size, Mock) } @@ -432,7 +424,7 @@ mod tests { let mut selection = Selection::new(SelectionType::Simple, location, Side::Left); selection.update(location, Side::Right); - assert_eq!(selection.to_range(&term(1, 1)).unwrap(), SelectionRange { + assert_eq!(selection.to_range(&term(1, 2)).unwrap(), SelectionRange { start: location, end: location, is_block: false @@ -450,7 +442,7 @@ mod tests { let mut selection = Selection::new(SelectionType::Simple, location, Side::Right); selection.update(location, Side::Left); - assert_eq!(selection.to_range(&term(1, 1)).unwrap(), SelectionRange { + assert_eq!(selection.to_range(&term(1, 2)).unwrap(), SelectionRange { start: location, end: location, is_block: false diff --git a/alacritty_terminal/src/term/mod.rs b/alacritty_terminal/src/term/mod.rs index 00726dad..a33ac919 100644 --- a/alacritty_terminal/src/term/mod.rs +++ b/alacritty_terminal/src/term/mod.rs @@ -40,8 +40,13 @@ const MAX_SEARCH_LINES: usize = 100; /// Default tab interval, corresponding to terminfo `it` value. const INITIAL_TABSTOPS: usize = 8; -/// Minimum number of columns and lines. -const MIN_SIZE: usize = 2; +/// Minimum number of columns. +/// +/// A minimum of 2 is necessary to hold fullwidth unicode characters. +pub const MIN_COLS: usize = 2; + +/// Minimum number of visible lines. +pub const MIN_SCREEN_LINES: usize = 1; /// Cursor storing all information relevant for rendering. #[derive(Debug, Eq, PartialEq, Copy, Clone, Deserialize)] @@ -612,69 +617,139 @@ impl From<&BellConfig> for VisualBell { #[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq)] pub struct SizeInfo { /// Terminal window width. - pub width: f32, + width: f32, /// Terminal window height. - pub height: f32, + height: f32, /// Width of individual cell. - pub cell_width: f32, + cell_width: f32, /// Height of individual cell. - pub cell_height: f32, + cell_height: f32, /// Horizontal window padding. - pub padding_x: f32, + padding_x: f32, /// Horizontal window padding. - pub padding_y: f32, + padding_y: f32, - /// DPR of the current window. - #[serde(default)] - pub dpr: f64, + /// Number of lines in the viewport. + screen_lines: Line, + + /// Number of columns in the viewport. + cols: Column, } impl SizeInfo { - #[inline] - pub fn lines(&self) -> Line { - Line(((self.height - 2. * self.padding_y) / self.cell_height) as usize) - } + #[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); + } - #[inline] - pub fn cols(&self) -> Column { - Column(((self.width - 2. * self.padding_x) / self.cell_width) as usize) - } + let lines = (height - 2. * padding_y) / cell_height; + let screen_lines = Line(max(lines as usize, MIN_SCREEN_LINES)); - #[inline] - pub fn padding_right(&self) -> usize { - (self.padding_x + (self.width - 2. * self.padding_x) % self.cell_width) as usize + let cols = (width - 2. * padding_x) / cell_width; + let cols = Column(max(cols as usize, MIN_COLS)); + + SizeInfo { + width, + height, + cell_width, + cell_height, + padding_x: padding_x.floor(), + padding_y: padding_y.floor(), + screen_lines, + cols, + } } #[inline] - pub fn padding_bottom(&self) -> usize { - (self.padding_y + (self.height - 2. * self.padding_y) % self.cell_height) as usize + pub fn reserve_lines(&mut self, count: usize) { + self.screen_lines = Line(max(self.screen_lines.saturating_sub(count), MIN_SCREEN_LINES)); } /// Check if coordinates are inside the terminal grid. /// - /// The padding is not counted as part of the 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.width as usize - self.padding_right()) - && x >= self.padding_x as usize - && y < (self.height as usize - self.padding_bottom()) - && y >= self.padding_y as usize + x <= (self.padding_x + self.cols.0 as f32 * self.cell_width) as usize + && x > self.padding_x as usize + && y <= (self.padding_y + self.screen_lines.0 as f32 * self.cell_height) as usize + && y > self.padding_y as usize } + /// Convert window space pixels to terminal grid coordinates. + /// + /// If the coordinates are outside of the terminal grid, like positions inside the padding, the + /// coordinates will be clamped to the closest grid coordinates. pub fn pixels_to_coords(&self, x: usize, y: usize) -> Point { let col = Column(x.saturating_sub(self.padding_x as usize) / (self.cell_width as usize)); let line = Line(y.saturating_sub(self.padding_y as usize) / (self.cell_height as usize)); Point { - line: min(line, Line(self.lines().saturating_sub(1))), - col: min(col, Column(self.cols().saturating_sub(1))), + line: min(line, Line(self.screen_lines.saturating_sub(1))), + col: min(col, Column(self.cols.saturating_sub(1))), } } + + #[inline] + pub fn width(&self) -> f32 { + self.width + } + + #[inline] + pub fn height(&self) -> f32 { + self.height + } + + #[inline] + pub fn cell_width(&self) -> f32 { + self.cell_width + } + + #[inline] + pub fn cell_height(&self) -> f32 { + self.cell_height + } + + #[inline] + pub fn padding_x(&self) -> f32 { + self.padding_x + } + + #[inline] + pub fn padding_y(&self) -> f32 { + self.padding_y + } + + #[inline] + pub fn screen_lines(&self) -> Line { + self.screen_lines + } + + #[inline] + pub fn cols(&self) -> Column { + self.cols + } + + /// 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. + } } pub struct Term<T> { @@ -751,8 +826,9 @@ pub struct Term<T> { /// Current forward and backward buffer search regexes. regex_search: Option<RegexSearch>, - /// Information about window dimensions. - size: SizeInfo, + /// Information about cell dimensions. + cell_width: usize, + cell_height: usize, } impl<T> Term<T> { @@ -767,8 +843,8 @@ impl<T> Term<T> { } pub fn new<C>(config: &Config<C>, size: SizeInfo, event_proxy: T) -> Term<T> { - let num_cols = size.cols(); - let num_lines = size.lines(); + let num_cols = size.cols; + let num_lines = size.screen_lines; let history_size = config.scrolling.history() as usize; let grid = Grid::new(num_lines, num_cols, history_size, Cell::default()); @@ -803,7 +879,8 @@ impl<T> Term<T> { title_stack: Vec::new(), selection: None, regex_search: None, - size, + cell_width: size.cell_width as usize, + cell_height: size.cell_height as usize, } } @@ -974,12 +1051,14 @@ impl<T> Term<T> { /// Resize terminal to new dimensions. pub fn resize(&mut self, size: SizeInfo) { - self.size = size; + self.cell_width = size.cell_width as usize; + self.cell_height = size.cell_height as usize; let old_cols = self.cols(); let old_lines = self.screen_lines(); - let num_cols = max(size.cols(), Column(MIN_SIZE)); - let num_lines = max(size.lines(), Line(MIN_SIZE)); + + let num_cols = size.cols; + let num_lines = size.screen_lines; if old_cols == num_cols && old_lines == num_lines { debug!("Term::resize dimensions unchanged"); @@ -2233,8 +2312,8 @@ impl<T: EventListener> Handler for Term<T> { #[inline] fn text_area_size_pixels<W: io::Write>(&mut self, writer: &mut W) { - let width = self.size.cell_width as usize * self.cols().0; - let height = self.size.cell_height as usize * self.screen_lines().0; + let width = self.cell_width * self.cols().0; + let height = self.cell_height * self.screen_lines().0; let _ = write!(writer, "\x1b[4;{};{}t", height, width); } @@ -2356,15 +2435,7 @@ pub mod test { .unwrap_or(0); // Create terminal with the appropriate dimensions. - let size = SizeInfo { - width: num_cols as f32, - height: lines.len() as f32, - cell_width: 1., - cell_height: 1., - padding_x: 0., - padding_y: 0., - dpr: 1., - }; + let size = SizeInfo::new(num_cols as f32, lines.len() as f32, 1., 1., 0., 0., false); let mut term = Term::new(&Config::<()>::default(), size, ()); // Fill terminal with content. @@ -2413,15 +2484,7 @@ mod tests { #[test] fn semantic_selection_works() { - let size = SizeInfo { - width: 21.0, - height: 51.0, - cell_width: 3.0, - cell_height: 3.0, - padding_x: 0.0, - padding_y: 0.0, - dpr: 1.0, - }; + let size = SizeInfo::new(21.0, 51.0, 3.0, 3.0, 0.0, 0.0, false); let mut term = Term::new(&MockConfig::default(), size, Mock); let mut grid: Grid<Cell> = Grid::new(Line(3), Column(5), 0, Cell::default()); for i in 0..5 { @@ -2469,15 +2532,7 @@ mod tests { #[test] fn line_selection_works() { - let size = SizeInfo { - width: 21.0, - height: 51.0, - cell_width: 3.0, - cell_height: 3.0, - padding_x: 0.0, - padding_y: 0.0, - dpr: 1.0, - }; + let size = SizeInfo::new(21.0, 51.0, 3.0, 3.0, 0.0, 0.0, false); let mut term = Term::new(&MockConfig::default(), size, Mock); let mut grid: Grid<Cell> = Grid::new(Line(1), Column(5), 0, Cell::default()); for i in 0..5 { @@ -2498,15 +2553,7 @@ mod tests { #[test] fn selecting_empty_line() { - let size = SizeInfo { - width: 21.0, - height: 51.0, - cell_width: 3.0, - cell_height: 3.0, - padding_x: 0.0, - padding_y: 0.0, - dpr: 1.0, - }; + let size = SizeInfo::new(21.0, 51.0, 3.0, 3.0, 0.0, 0.0, false); let mut term = Term::new(&MockConfig::default(), size, Mock); let mut grid: Grid<Cell> = Grid::new(Line(3), Column(3), 0, Cell::default()); for l in 0..3 { @@ -2543,15 +2590,7 @@ mod tests { #[test] fn input_line_drawing_character() { - let size = SizeInfo { - width: 21.0, - height: 51.0, - cell_width: 3.0, - cell_height: 3.0, - padding_x: 0.0, - padding_y: 0.0, - dpr: 1.0, - }; + let size = SizeInfo::new(21.0, 51.0, 3.0, 3.0, 0.0, 0.0, false); let mut term = Term::new(&MockConfig::default(), size, Mock); let cursor = Point::new(Line(0), Column(0)); term.configure_charset(CharsetIndex::G0, StandardCharset::SpecialCharacterAndLineDrawing); @@ -2562,15 +2601,7 @@ mod tests { #[test] fn clear_saved_lines() { - let size = SizeInfo { - width: 21.0, - height: 51.0, - cell_width: 3.0, - cell_height: 3.0, - padding_x: 0.0, - padding_y: 0.0, - dpr: 1.0, - }; + let size = SizeInfo::new(21.0, 51.0, 3.0, 3.0, 0.0, 0.0, false); let mut term = Term::new(&MockConfig::default(), size, Mock); // Add one line of scrollback. @@ -2592,15 +2623,7 @@ mod tests { #[test] fn grow_lines_updates_active_cursor_pos() { - let mut size = SizeInfo { - width: 100.0, - height: 10.0, - cell_width: 1.0, - cell_height: 1.0, - padding_x: 0.0, - padding_y: 0.0, - dpr: 1.0, - }; + let mut size = SizeInfo::new(100.0, 10.0, 1.0, 1.0, 0.0, 0.0, false); let mut term = Term::new(&MockConfig::default(), size, Mock); // Create 10 lines of scrollback. @@ -2611,7 +2634,7 @@ mod tests { assert_eq!(term.grid.cursor.point, Point::new(Line(9), Column(0))); // Increase visible lines. - size.height = 30.; + size.screen_lines.0 = 30; term.resize(size); assert_eq!(term.history_size(), 0); @@ -2620,15 +2643,7 @@ mod tests { #[test] fn grow_lines_updates_inactive_cursor_pos() { - let mut size = SizeInfo { - width: 100.0, - height: 10.0, - cell_width: 1.0, - cell_height: 1.0, - padding_x: 0.0, - padding_y: 0.0, - dpr: 1.0, - }; + let mut size = SizeInfo::new(100.0, 10.0, 1.0, 1.0, 0.0, 0.0, false); let mut term = Term::new(&MockConfig::default(), size, Mock); // Create 10 lines of scrollback. @@ -2642,7 +2657,7 @@ mod tests { term.set_mode(ansi::Mode::SwapScreenAndSetRestoreCursor); // Increase visible lines. - size.height = 30.; + size.screen_lines.0 = 30; term.resize(size); // Leave alt screen. @@ -2654,15 +2669,7 @@ mod tests { #[test] fn shrink_lines_updates_active_cursor_pos() { - let mut size = SizeInfo { - width: 100.0, - height: 10.0, - cell_width: 1.0, - cell_height: 1.0, - padding_x: 0.0, - padding_y: 0.0, - dpr: 1.0, - }; + let mut size = SizeInfo::new(100.0, 10.0, 1.0, 1.0, 0.0, 0.0, false); let mut term = Term::new(&MockConfig::default(), size, Mock); // Create 10 lines of scrollback. @@ -2673,7 +2680,7 @@ mod tests { assert_eq!(term.grid.cursor.point, Point::new(Line(9), Column(0))); // Increase visible lines. - size.height = 5.; + size.screen_lines.0 = 5; term.resize(size); assert_eq!(term.history_size(), 15); @@ -2682,15 +2689,7 @@ mod tests { #[test] fn shrink_lines_updates_inactive_cursor_pos() { - let mut size = SizeInfo { - width: 100.0, - height: 10.0, - cell_width: 1.0, - cell_height: 1.0, - padding_x: 0.0, - padding_y: 0.0, - dpr: 1.0, - }; + let mut size = SizeInfo::new(100.0, 10.0, 1.0, 1.0, 0.0, 0.0, false); let mut term = Term::new(&MockConfig::default(), size, Mock); // Create 10 lines of scrollback. @@ -2704,7 +2703,7 @@ mod tests { term.set_mode(ansi::Mode::SwapScreenAndSetRestoreCursor); // Increase visible lines. - size.height = 5.; + size.screen_lines.0 = 5; term.resize(size); // Leave alt screen. @@ -2716,15 +2715,7 @@ mod tests { #[test] fn window_title() { - let size = SizeInfo { - width: 21.0, - height: 51.0, - cell_width: 3.0, - cell_height: 3.0, - padding_x: 0.0, - padding_y: 0.0, - dpr: 1.0, - }; + let size = SizeInfo::new(21.0, 51.0, 3.0, 3.0, 0.0, 0.0, false); let mut term = Term::new(&MockConfig::default(), size, Mock); // Title None by default. diff --git a/alacritty_terminal/src/tty/unix.rs b/alacritty_terminal/src/tty/unix.rs index c52da34d..9cce1983 100644 --- a/alacritty_terminal/src/tty/unix.rs +++ b/alacritty_terminal/src/tty/unix.rs @@ -357,10 +357,10 @@ pub trait ToWinsize { impl<'a> ToWinsize for &'a SizeInfo { fn to_winsize(&self) -> winsize { winsize { - ws_row: self.lines().0 as libc::c_ushort, + ws_row: self.screen_lines().0 as libc::c_ushort, ws_col: self.cols().0 as libc::c_ushort, - ws_xpixel: self.width as libc::c_ushort, - ws_ypixel: self.height as libc::c_ushort, + ws_xpixel: self.width() as libc::c_ushort, + ws_ypixel: self.height() as libc::c_ushort, } } } diff --git a/alacritty_terminal/src/tty/windows/conpty.rs b/alacritty_terminal/src/tty/windows/conpty.rs index b9748c8b..5469c7fe 100644 --- a/alacritty_terminal/src/tty/windows/conpty.rs +++ b/alacritty_terminal/src/tty/windows/conpty.rs @@ -233,12 +233,12 @@ impl OnResize for Conpty { } /// Helper to build a COORD from a SizeInfo, returning None in overflow cases. -fn coord_from_sizeinfo(sizeinfo: &SizeInfo) -> Option<COORD> { - let cols = sizeinfo.cols().0; - let lines = sizeinfo.lines().0; +fn coord_from_sizeinfo(size: &SizeInfo) -> Option<COORD> { + let cols = size.cols().0; + let lines = size.screen_lines().0; if cols <= i16::MAX as usize && lines <= i16::MAX as usize { - Some(COORD { X: sizeinfo.cols().0 as i16, Y: sizeinfo.lines().0 as i16 }) + Some(COORD { X: cols as i16, Y: lines as i16 }) } else { None } diff --git a/alacritty_terminal/src/tty/windows/winpty.rs b/alacritty_terminal/src/tty/windows/winpty.rs index f9dd56bb..5de4b401 100644 --- a/alacritty_terminal/src/tty/windows/winpty.rs +++ b/alacritty_terminal/src/tty/windows/winpty.rs @@ -20,7 +20,7 @@ pub fn new<C>(config: &Config<C>, size: &SizeInfo, _window_id: Option<usize>) -> // Create config. let mut wconfig = WinptyConfig::new(ConfigFlags::empty()).unwrap(); - wconfig.set_initial_size(size.cols().0 as i32, size.lines().0 as i32); + wconfig.set_initial_size(size.cols().0 as i32, size.screen_lines().0 as i32); wconfig.set_mouse_mode(&MouseMode::Auto); // Start agent. @@ -60,8 +60,8 @@ pub fn new<C>(config: &Config<C>, size: &SizeInfo, _window_id: Option<usize>) -> } impl OnResize for Agent { - fn on_resize(&mut self, sizeinfo: &SizeInfo) { - let (cols, lines) = (sizeinfo.cols().0, sizeinfo.lines().0); + fn on_resize(&mut self, size: &SizeInfo) { + let (cols, lines) = (size.cols().0, size.screen_lines().0); if cols > 0 && cols <= u16::MAX as usize && lines > 0 && lines <= u16::MAX as usize { self.set_size(cols as u16, lines as u16) .unwrap_or_else(|_| info!("Unable to set WinPTY size, did it die?")); diff --git a/alacritty_terminal/src/vi_mode.rs b/alacritty_terminal/src/vi_mode.rs index 53534f73..3959494f 100644 --- a/alacritty_terminal/src/vi_mode.rs +++ b/alacritty_terminal/src/vi_mode.rs @@ -407,15 +407,7 @@ mod tests { } fn term() -> Term<Mock> { - let size = SizeInfo { - width: 20., - height: 20., - cell_width: 1.0, - cell_height: 1.0, - padding_x: 0.0, - padding_y: 0.0, - dpr: 1.0, - }; + let size = SizeInfo::new(20., 20., 1.0, 1.0, 0.0, 0.0, false); Term::new(&MockConfig::default(), size, Mock) } diff --git a/alacritty_terminal/tests/ref/alt_reset/size.json b/alacritty_terminal/tests/ref/alt_reset/size.json index 99712902..f0e7f283 100644 --- a/alacritty_terminal/tests/ref/alt_reset/size.json +++ b/alacritty_terminal/tests/ref/alt_reset/size.json @@ -1 +1 @@ -{"width":1916.0,"height":1054.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"dpr":2.0}
\ No newline at end of file +{"width":1916.0,"height":1054.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"cols":106,"screen_lines":30} diff --git a/alacritty_terminal/tests/ref/clear_underline/size.json b/alacritty_terminal/tests/ref/clear_underline/size.json index 5a7fe4e4..a76b7abd 100644 --- a/alacritty_terminal/tests/ref/clear_underline/size.json +++ b/alacritty_terminal/tests/ref/clear_underline/size.json @@ -1 +1 @@ -{"width":662.0,"height":708.0,"cell_width":10.0,"cell_height":22.0,"padding_x":0.0,"padding_y":0.0,"dpr":1.0833333333333333}
\ No newline at end of file +{"width":662.0,"height":708.0,"cell_width":10.0,"cell_height":22.0,"padding_x":0.0,"padding_y":0.0,"cols":66,"screen_lines":32} diff --git a/alacritty_terminal/tests/ref/colored_reset/size.json b/alacritty_terminal/tests/ref/colored_reset/size.json index f7b43e61..6054e742 100644 --- a/alacritty_terminal/tests/ref/colored_reset/size.json +++ b/alacritty_terminal/tests/ref/colored_reset/size.json @@ -1 +1 @@ -{"width":939.0,"height":1020.0,"cell_width":8.0,"cell_height":16.0,"padding_x":5.0,"padding_y":6.0,"dpr":1.0}
\ No newline at end of file +{"width":939.0,"height":1020.0,"cell_width":8.0,"cell_height":16.0,"padding_x":5.0,"padding_y":6.0,"cols":116,"screen_lines":63} diff --git a/alacritty_terminal/tests/ref/csi_rep/size.json b/alacritty_terminal/tests/ref/csi_rep/size.json index 8439a658..0ac0cba2 100644 --- a/alacritty_terminal/tests/ref/csi_rep/size.json +++ b/alacritty_terminal/tests/ref/csi_rep/size.json @@ -1 +1 @@ -{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"dpr":2.0}
\ No newline at end of file +{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"cols":105,"screen_lines":29} diff --git a/alacritty_terminal/tests/ref/decaln_reset/size.json b/alacritty_terminal/tests/ref/decaln_reset/size.json index 99712902..f0e7f283 100644 --- a/alacritty_terminal/tests/ref/decaln_reset/size.json +++ b/alacritty_terminal/tests/ref/decaln_reset/size.json @@ -1 +1 @@ -{"width":1916.0,"height":1054.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"dpr":2.0}
\ No newline at end of file +{"width":1916.0,"height":1054.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"cols":106,"screen_lines":30} diff --git a/alacritty_terminal/tests/ref/deccolm_reset/size.json b/alacritty_terminal/tests/ref/deccolm_reset/size.json index 99712902..f0e7f283 100644 --- a/alacritty_terminal/tests/ref/deccolm_reset/size.json +++ b/alacritty_terminal/tests/ref/deccolm_reset/size.json @@ -1 +1 @@ -{"width":1916.0,"height":1054.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"dpr":2.0}
\ No newline at end of file +{"width":1916.0,"height":1054.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"cols":106,"screen_lines":30} diff --git a/alacritty_terminal/tests/ref/delete_chars_reset/size.json b/alacritty_terminal/tests/ref/delete_chars_reset/size.json index 99712902..f0e7f283 100644 --- a/alacritty_terminal/tests/ref/delete_chars_reset/size.json +++ b/alacritty_terminal/tests/ref/delete_chars_reset/size.json @@ -1 +1 @@ -{"width":1916.0,"height":1054.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"dpr":2.0}
\ No newline at end of file +{"width":1916.0,"height":1054.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"cols":106,"screen_lines":30} diff --git a/alacritty_terminal/tests/ref/delete_lines/size.json b/alacritty_terminal/tests/ref/delete_lines/size.json index 11c7c565..48d2598b 100644 --- a/alacritty_terminal/tests/ref/delete_lines/size.json +++ b/alacritty_terminal/tests/ref/delete_lines/size.json @@ -1 +1 @@ -{"width":939.0,"height":503.0,"cell_width":8.0,"cell_height":16.0,"padding_x":5.0,"padding_y":3.0,"dpr":1.0}
\ No newline at end of file +{"width":939.0,"height":503.0,"cell_width":8.0,"cell_height":16.0,"padding_x":5.0,"padding_y":3.0,"cols":116,"screen_lines":31} diff --git a/alacritty_terminal/tests/ref/erase_chars_reset/size.json b/alacritty_terminal/tests/ref/erase_chars_reset/size.json index 99712902..f0e7f283 100644 --- a/alacritty_terminal/tests/ref/erase_chars_reset/size.json +++ b/alacritty_terminal/tests/ref/erase_chars_reset/size.json @@ -1 +1 @@ -{"width":1916.0,"height":1054.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"dpr":2.0}
\ No newline at end of file +{"width":1916.0,"height":1054.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"cols":106,"screen_lines":30} diff --git a/alacritty_terminal/tests/ref/fish_cc/size.json b/alacritty_terminal/tests/ref/fish_cc/size.json index 8439a658..0ac0cba2 100644 --- a/alacritty_terminal/tests/ref/fish_cc/size.json +++ b/alacritty_terminal/tests/ref/fish_cc/size.json @@ -1 +1 @@ -{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"dpr":2.0}
\ No newline at end of file +{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"cols":105,"screen_lines":29} diff --git a/alacritty_terminal/tests/ref/grid_reset/size.json b/alacritty_terminal/tests/ref/grid_reset/size.json index 8439a658..0ac0cba2 100644 --- a/alacritty_terminal/tests/ref/grid_reset/size.json +++ b/alacritty_terminal/tests/ref/grid_reset/size.json @@ -1 +1 @@ -{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"dpr":2.0}
\ No newline at end of file +{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"cols":105,"screen_lines":29} diff --git a/alacritty_terminal/tests/ref/history/size.json b/alacritty_terminal/tests/ref/history/size.json index 8439a658..0ac0cba2 100644 --- a/alacritty_terminal/tests/ref/history/size.json +++ b/alacritty_terminal/tests/ref/history/size.json @@ -1 +1 @@ -{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"dpr":2.0}
\ No newline at end of file +{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"cols":105,"screen_lines":29} diff --git a/alacritty_terminal/tests/ref/indexed_256_colors/size.json b/alacritty_terminal/tests/ref/indexed_256_colors/size.json index 8439a658..0ac0cba2 100644 --- a/alacritty_terminal/tests/ref/indexed_256_colors/size.json +++ b/alacritty_terminal/tests/ref/indexed_256_colors/size.json @@ -1 +1 @@ -{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"dpr":2.0}
\ No newline at end of file +{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"cols":105,"screen_lines":29} diff --git a/alacritty_terminal/tests/ref/insert_blank_reset/size.json b/alacritty_terminal/tests/ref/insert_blank_reset/size.json index 99712902..f0e7f283 100644 --- a/alacritty_terminal/tests/ref/insert_blank_reset/size.json +++ b/alacritty_terminal/tests/ref/insert_blank_reset/size.json @@ -1 +1 @@ -{"width":1916.0,"height":1054.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"dpr":2.0}
\ No newline at end of file +{"width":1916.0,"height":1054.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"cols":106,"screen_lines":30} diff --git a/alacritty_terminal/tests/ref/issue_855/size.json b/alacritty_terminal/tests/ref/issue_855/size.json index 8439a658..0ac0cba2 100644 --- a/alacritty_terminal/tests/ref/issue_855/size.json +++ b/alacritty_terminal/tests/ref/issue_855/size.json @@ -1 +1 @@ -{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"dpr":2.0}
\ No newline at end of file +{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"cols":105,"screen_lines":29} diff --git a/alacritty_terminal/tests/ref/ll/size.json b/alacritty_terminal/tests/ref/ll/size.json index 8439a658..0ac0cba2 100644 --- a/alacritty_terminal/tests/ref/ll/size.json +++ b/alacritty_terminal/tests/ref/ll/size.json @@ -1 +1 @@ -{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"dpr":2.0}
\ No newline at end of file +{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"cols":105,"screen_lines":29} diff --git a/alacritty_terminal/tests/ref/newline_with_cursor_beyond_scroll_region/size.json b/alacritty_terminal/tests/ref/newline_with_cursor_beyond_scroll_region/size.json index 8439a658..0ac0cba2 100644 --- a/alacritty_terminal/tests/ref/newline_with_cursor_beyond_scroll_region/size.json +++ b/alacritty_terminal/tests/ref/newline_with_cursor_beyond_scroll_region/size.json @@ -1 +1 @@ -{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"dpr":2.0}
\ No newline at end of file +{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"cols":105,"screen_lines":29} diff --git a/alacritty_terminal/tests/ref/region_scroll_down/size.json b/alacritty_terminal/tests/ref/region_scroll_down/size.json index 11c7c565..48d2598b 100644 --- a/alacritty_terminal/tests/ref/region_scroll_down/size.json +++ b/alacritty_terminal/tests/ref/region_scroll_down/size.json @@ -1 +1 @@ -{"width":939.0,"height":503.0,"cell_width":8.0,"cell_height":16.0,"padding_x":5.0,"padding_y":3.0,"dpr":1.0}
\ No newline at end of file +{"width":939.0,"height":503.0,"cell_width":8.0,"cell_height":16.0,"padding_x":5.0,"padding_y":3.0,"cols":116,"screen_lines":31} diff --git a/alacritty_terminal/tests/ref/row_reset/size.json b/alacritty_terminal/tests/ref/row_reset/size.json index 97fa803f..927f25db 100644 --- a/alacritty_terminal/tests/ref/row_reset/size.json +++ b/alacritty_terminal/tests/ref/row_reset/size.json @@ -1 +1 @@ -{"width":1900.0,"height":1040.0,"cell_width":11.0,"cell_height":22.0,"padding_x":0.0,"padding_y":0.0,"dpr":2.0}
\ No newline at end of file +{"width":1900.0,"height":1040.0,"cell_width":11.0,"cell_height":22.0,"padding_x":0.0,"padding_y":0.0,"cols":172,"screen_lines":47} diff --git a/alacritty_terminal/tests/ref/saved_cursor/size.json b/alacritty_terminal/tests/ref/saved_cursor/size.json index 8a55d412..8f19f0da 100644 --- a/alacritty_terminal/tests/ref/saved_cursor/size.json +++ b/alacritty_terminal/tests/ref/saved_cursor/size.json @@ -1 +1 @@ -{"width":1259.0,"height":683.0,"cell_width":9.0,"cell_height":19.0,"padding_x":4.0,"padding_y":9.0,"dpr":1.1666666666666667}
\ No newline at end of file +{"width":1259.0,"height":683.0,"cell_width":9.0,"cell_height":19.0,"padding_x":4.0,"padding_y":9.0,"cols":139,"screen_lines":35} diff --git a/alacritty_terminal/tests/ref/saved_cursor_alt/size.json b/alacritty_terminal/tests/ref/saved_cursor_alt/size.json index 8a55d412..8f19f0da 100644 --- a/alacritty_terminal/tests/ref/saved_cursor_alt/size.json +++ b/alacritty_terminal/tests/ref/saved_cursor_alt/size.json @@ -1 +1 @@ -{"width":1259.0,"height":683.0,"cell_width":9.0,"cell_height":19.0,"padding_x":4.0,"padding_y":9.0,"dpr":1.1666666666666667}
\ No newline at end of file +{"width":1259.0,"height":683.0,"cell_width":9.0,"cell_height":19.0,"padding_x":4.0,"padding_y":9.0,"cols":139,"screen_lines":35} diff --git a/alacritty_terminal/tests/ref/scroll_up_reset/size.json b/alacritty_terminal/tests/ref/scroll_up_reset/size.json index 8ec182ba..86a3d608 100644 --- a/alacritty_terminal/tests/ref/scroll_up_reset/size.json +++ b/alacritty_terminal/tests/ref/scroll_up_reset/size.json @@ -1 +1 @@ -{"width":1840.0,"height":1040.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"dpr":2.0}
\ No newline at end of file +{"width":1840.0,"height":1040.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"cols":102,"screen_lines":29} diff --git a/alacritty_terminal/tests/ref/selective_erasure/size.json b/alacritty_terminal/tests/ref/selective_erasure/size.json index 58891d8a..47012031 100644 --- a/alacritty_terminal/tests/ref/selective_erasure/size.json +++ b/alacritty_terminal/tests/ref/selective_erasure/size.json @@ -1 +1 @@ -{"width":70.0,"height":63.0,"cell_width":7.0,"cell_height":21.0,"padding_x":0.0,"padding_y":0.0,"dpr":1.0}
\ No newline at end of file +{"width":70.0,"height":63.0,"cell_width":7.0,"cell_height":21.0,"padding_x":0.0,"padding_y":0.0,"cols":10,"screen_lines":3} diff --git a/alacritty_terminal/tests/ref/sgr/size.json b/alacritty_terminal/tests/ref/sgr/size.json index 8a55d412..8f19f0da 100644 --- a/alacritty_terminal/tests/ref/sgr/size.json +++ b/alacritty_terminal/tests/ref/sgr/size.json @@ -1 +1 @@ -{"width":1259.0,"height":683.0,"cell_width":9.0,"cell_height":19.0,"padding_x":4.0,"padding_y":9.0,"dpr":1.1666666666666667}
\ No newline at end of file +{"width":1259.0,"height":683.0,"cell_width":9.0,"cell_height":19.0,"padding_x":4.0,"padding_y":9.0,"cols":139,"screen_lines":35} diff --git a/alacritty_terminal/tests/ref/tab_rendering/size.json b/alacritty_terminal/tests/ref/tab_rendering/size.json index f7b43e61..6054e742 100644 --- a/alacritty_terminal/tests/ref/tab_rendering/size.json +++ b/alacritty_terminal/tests/ref/tab_rendering/size.json @@ -1 +1 @@ -{"width":939.0,"height":1020.0,"cell_width":8.0,"cell_height":16.0,"padding_x":5.0,"padding_y":6.0,"dpr":1.0}
\ No newline at end of file +{"width":939.0,"height":1020.0,"cell_width":8.0,"cell_height":16.0,"padding_x":5.0,"padding_y":6.0,"cols":116,"screen_lines":63} diff --git a/alacritty_terminal/tests/ref/tmux_git_log/size.json b/alacritty_terminal/tests/ref/tmux_git_log/size.json index 8439a658..0ac0cba2 100644 --- a/alacritty_terminal/tests/ref/tmux_git_log/size.json +++ b/alacritty_terminal/tests/ref/tmux_git_log/size.json @@ -1 +1 @@ -{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"dpr":2.0}
\ No newline at end of file +{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"cols":105,"screen_lines":29} diff --git a/alacritty_terminal/tests/ref/tmux_htop/size.json b/alacritty_terminal/tests/ref/tmux_htop/size.json index 8439a658..0ac0cba2 100644 --- a/alacritty_terminal/tests/ref/tmux_htop/size.json +++ b/alacritty_terminal/tests/ref/tmux_htop/size.json @@ -1 +1 @@ -{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"dpr":2.0}
\ No newline at end of file +{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"cols":105,"screen_lines":29} diff --git a/alacritty_terminal/tests/ref/underline/size.json b/alacritty_terminal/tests/ref/underline/size.json index 11c7c565..48d2598b 100644 --- a/alacritty_terminal/tests/ref/underline/size.json +++ b/alacritty_terminal/tests/ref/underline/size.json @@ -1 +1 @@ -{"width":939.0,"height":503.0,"cell_width":8.0,"cell_height":16.0,"padding_x":5.0,"padding_y":3.0,"dpr":1.0}
\ No newline at end of file +{"width":939.0,"height":503.0,"cell_width":8.0,"cell_height":16.0,"padding_x":5.0,"padding_y":3.0,"cols":116,"screen_lines":31} diff --git a/alacritty_terminal/tests/ref/vim_24bitcolors_bce/size.json b/alacritty_terminal/tests/ref/vim_24bitcolors_bce/size.json index 4cb2c708..3ceb4618 100644 --- a/alacritty_terminal/tests/ref/vim_24bitcolors_bce/size.json +++ b/alacritty_terminal/tests/ref/vim_24bitcolors_bce/size.json @@ -1 +1 @@ -{"width":1916.0,"height":2121.0,"cell_width":11.0,"cell_height":22.0,"padding_x":0.0,"padding_y":0.0,"dpr":2.0}
\ No newline at end of file +{"width":1916.0,"height":2121.0,"cell_width":11.0,"cell_height":22.0,"padding_x":0.0,"padding_y":0.0,"cols":174,"screen_lines":96} diff --git a/alacritty_terminal/tests/ref/vim_large_window_scroll/size.json b/alacritty_terminal/tests/ref/vim_large_window_scroll/size.json index 97fa803f..927f25db 100644 --- a/alacritty_terminal/tests/ref/vim_large_window_scroll/size.json +++ b/alacritty_terminal/tests/ref/vim_large_window_scroll/size.json @@ -1 +1 @@ -{"width":1900.0,"height":1040.0,"cell_width":11.0,"cell_height":22.0,"padding_x":0.0,"padding_y":0.0,"dpr":2.0}
\ No newline at end of file +{"width":1900.0,"height":1040.0,"cell_width":11.0,"cell_height":22.0,"padding_x":0.0,"padding_y":0.0,"cols":172,"screen_lines":47} diff --git a/alacritty_terminal/tests/ref/vim_simple_edit/size.json b/alacritty_terminal/tests/ref/vim_simple_edit/size.json index eb12da0f..b8c739ea 100644 --- a/alacritty_terminal/tests/ref/vim_simple_edit/size.json +++ b/alacritty_terminal/tests/ref/vim_simple_edit/size.json @@ -1 +1 @@ -{"width":644.0,"height":412.0,"cell_width":8.0,"cell_height":17.0,"padding_x":0.0,"padding_y":0.0}
\ No newline at end of file +{"width":644.0,"height":412.0,"cell_width":8.0,"cell_height":17.0,"padding_x":0.0,"padding_y":0.0,"cols":80,"screen_lines":24} diff --git a/alacritty_terminal/tests/ref/vttest_cursor_movement_1/size.json b/alacritty_terminal/tests/ref/vttest_cursor_movement_1/size.json index 8439a658..0ac0cba2 100644 --- a/alacritty_terminal/tests/ref/vttest_cursor_movement_1/size.json +++ b/alacritty_terminal/tests/ref/vttest_cursor_movement_1/size.json @@ -1 +1 @@ -{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"dpr":2.0}
\ No newline at end of file +{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"cols":105,"screen_lines":29} diff --git a/alacritty_terminal/tests/ref/vttest_insert/size.json b/alacritty_terminal/tests/ref/vttest_insert/size.json index 8439a658..0ac0cba2 100644 --- a/alacritty_terminal/tests/ref/vttest_insert/size.json +++ b/alacritty_terminal/tests/ref/vttest_insert/size.json @@ -1 +1 @@ -{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"dpr":2.0}
\ No newline at end of file +{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"cols":105,"screen_lines":29} diff --git a/alacritty_terminal/tests/ref/vttest_origin_mode_1/size.json b/alacritty_terminal/tests/ref/vttest_origin_mode_1/size.json index 8439a658..0ac0cba2 100644 --- a/alacritty_terminal/tests/ref/vttest_origin_mode_1/size.json +++ b/alacritty_terminal/tests/ref/vttest_origin_mode_1/size.json @@ -1 +1 @@ -{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"dpr":2.0}
\ No newline at end of file +{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"cols":105,"screen_lines":29} diff --git a/alacritty_terminal/tests/ref/vttest_origin_mode_2/size.json b/alacritty_terminal/tests/ref/vttest_origin_mode_2/size.json index 8439a658..0ac0cba2 100644 --- a/alacritty_terminal/tests/ref/vttest_origin_mode_2/size.json +++ b/alacritty_terminal/tests/ref/vttest_origin_mode_2/size.json @@ -1 +1 @@ -{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"dpr":2.0}
\ No newline at end of file +{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"cols":105,"screen_lines":29} diff --git a/alacritty_terminal/tests/ref/vttest_scroll/size.json b/alacritty_terminal/tests/ref/vttest_scroll/size.json index 8439a658..0ac0cba2 100644 --- a/alacritty_terminal/tests/ref/vttest_scroll/size.json +++ b/alacritty_terminal/tests/ref/vttest_scroll/size.json @@ -1 +1 @@ -{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"dpr":2.0}
\ No newline at end of file +{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"cols":105,"screen_lines":29} diff --git a/alacritty_terminal/tests/ref/vttest_tab_clear_set/size.json b/alacritty_terminal/tests/ref/vttest_tab_clear_set/size.json index 11c7c565..48d2598b 100644 --- a/alacritty_terminal/tests/ref/vttest_tab_clear_set/size.json +++ b/alacritty_terminal/tests/ref/vttest_tab_clear_set/size.json @@ -1 +1 @@ -{"width":939.0,"height":503.0,"cell_width":8.0,"cell_height":16.0,"padding_x":5.0,"padding_y":3.0,"dpr":1.0}
\ No newline at end of file +{"width":939.0,"height":503.0,"cell_width":8.0,"cell_height":16.0,"padding_x":5.0,"padding_y":3.0,"cols":116,"screen_lines":31} diff --git a/alacritty_terminal/tests/ref/wrapline_alt_toggle/size.json b/alacritty_terminal/tests/ref/wrapline_alt_toggle/size.json index 8a55d412..8f19f0da 100644 --- a/alacritty_terminal/tests/ref/wrapline_alt_toggle/size.json +++ b/alacritty_terminal/tests/ref/wrapline_alt_toggle/size.json @@ -1 +1 @@ -{"width":1259.0,"height":683.0,"cell_width":9.0,"cell_height":19.0,"padding_x":4.0,"padding_y":9.0,"dpr":1.1666666666666667}
\ No newline at end of file +{"width":1259.0,"height":683.0,"cell_width":9.0,"cell_height":19.0,"padding_x":4.0,"padding_y":9.0,"cols":139,"screen_lines":35} diff --git a/alacritty_terminal/tests/ref/zerowidth/size.json b/alacritty_terminal/tests/ref/zerowidth/size.json index 11c7c565..48d2598b 100644 --- a/alacritty_terminal/tests/ref/zerowidth/size.json +++ b/alacritty_terminal/tests/ref/zerowidth/size.json @@ -1 +1 @@ -{"width":939.0,"height":503.0,"cell_width":8.0,"cell_height":16.0,"padding_x":5.0,"padding_y":3.0,"dpr":1.0}
\ No newline at end of file +{"width":939.0,"height":503.0,"cell_width":8.0,"cell_height":16.0,"padding_x":5.0,"padding_y":3.0,"cols":116,"screen_lines":31} diff --git a/alacritty_terminal/tests/ref/zsh_tab_completion/size.json b/alacritty_terminal/tests/ref/zsh_tab_completion/size.json index 8439a658..0ac0cba2 100644 --- a/alacritty_terminal/tests/ref/zsh_tab_completion/size.json +++ b/alacritty_terminal/tests/ref/zsh_tab_completion/size.json @@ -1 +1 @@ -{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"dpr":2.0}
\ No newline at end of file +{"width":1900.0,"height":1038.0,"cell_width":18.0,"cell_height":35.0,"padding_x":0.0,"padding_y":0.0,"cols":105,"screen_lines":29} |