summaryrefslogtreecommitdiff
path: root/src/display.rs
diff options
context:
space:
mode:
authorChristian Duerr <chrisduerr@users.noreply.github.com>2019-04-14 15:37:58 +0000
committerGitHub <noreply@github.com>2019-04-14 15:37:58 +0000
commit5174f9b27488902e7862aeb470aa0f0375c95e46 (patch)
treebc22c88820e15a0bf1379bbfa371404c9706802b /src/display.rs
parentaac62ce5acd2ef4d05a54bc13b7cf30c30f129b2 (diff)
downloadalacritty-5174f9b27488902e7862aeb470aa0f0375c95e46.tar.gz
alacritty-5174f9b27488902e7862aeb470aa0f0375c95e46.zip
Fix duplicate resize events
If a resize event is identical to the current size, it is no longer propagated but the resize is discarded immediately. To further prevent resizes when not necessary, the list of monitors is enumerated and the DPR of the first display is assumed to be the target DPR. This allows spawning a window with dimensions when the config has columns and lines specified and the window only needs to be resized if the estimated DPR is not correct. Fixes #1825. Fixes #204.
Diffstat (limited to 'src/display.rs')
-rw-r--r--src/display.rs106
1 files changed, 75 insertions, 31 deletions
diff --git a/src/display.rs b/src/display.rs
index 8dca2f64..ed88f957 100644
--- a/src/display.rs
+++ b/src/display.rs
@@ -18,6 +18,7 @@ use std::f64;
use std::sync::mpsc;
use glutin::dpi::{PhysicalPosition, PhysicalSize};
+use glutin::EventsLoop;
use parking_lot::MutexGuard;
use crate::cli;
@@ -137,16 +138,24 @@ impl Display {
// Extract some properties from config
let render_timer = config.render_timer();
+ // Guess DPR based on first monitor
+ let event_loop = EventsLoop::new();
+ let estimated_dpr =
+ event_loop.get_available_monitors().next().map(|m| m.get_hidpi_factor()).unwrap_or(1.);
+
+ // Guess the target window dimensions
+ let metrics = GlyphCache::static_metrics(config, estimated_dpr as f32)?;
+ let (cell_width, cell_height) = Self::compute_cell_size(config, &metrics);
+ let dimensions =
+ Self::calculate_dimensions(config, options, estimated_dpr, cell_width, cell_height);
+
+ debug!("Estimated DPR: {}", estimated_dpr);
+ debug!("Estimated Cell Size: {} x {}", cell_width, cell_height);
+ debug!("Estimated Dimensions: {:?}", dimensions);
+
// Create the window where Alacritty will be displayed
- let mut window = Window::new(&options, config.window())?;
-
- // TODO: replace `set_position` with `with_position` once available
- // Upstream issue: https://github.com/tomaka/winit/issues/806
- // Set window position early so it doesn't "teleport"
- let position = options.position().or_else(|| config.position());
- if let Some(position) = position {
- window.set_position(position.x, position.y);
- }
+ let logical = dimensions.map(|d| PhysicalSize::new(d.0, d.1).to_logical(estimated_dpr));
+ let mut window = Window::new(event_loop, &options, config.window(), logical)?;
let dpr = window.hidpi_factor();
info!("Device pixel ratio: {}", dpr);
@@ -156,43 +165,39 @@ impl Display {
window.inner_size_pixels().expect("glutin returns window size").to_physical(dpr);
// Create renderer
- let mut renderer = QuadRenderer::new(viewport_size)?;
+ let mut renderer = QuadRenderer::new()?;
let (glyph_cache, cell_width, cell_height) =
Self::new_glyph_cache(dpr, &mut renderer, config)?;
- let dimensions = options.dimensions().unwrap_or_else(|| config.dimensions());
-
let mut padding_x = f64::from(config.padding().x) * dpr;
let mut padding_y = f64::from(config.padding().y) * dpr;
- if dimensions.columns_u32() > 0
- && dimensions.lines_u32() > 0
- && !config.window().start_maximized()
+ if let Some((width, height)) =
+ Self::calculate_dimensions(config, options, dpr, cell_width, cell_height)
{
- // Calculate new size based on cols/lines specified in config
- let width = cell_width as u32 * dimensions.columns_u32();
- let height = cell_height as u32 * dimensions.lines_u32();
- padding_x = padding_x.floor();
- padding_y = padding_y.floor();
-
- viewport_size = PhysicalSize::new(
- f64::from(width) + 2. * padding_x,
- f64::from(height) + 2. * padding_y,
- );
+ if dimensions == Some((width, height)) {
+ info!("Estimated DPR correctly, skipping resize");
+ } else {
+ viewport_size = PhysicalSize::new(width, height);
+ window.set_inner_size(viewport_size.to_logical(dpr));
+ }
} else if config.window().dynamic_padding() {
// Make sure additional padding is spread evenly
let cw = f64::from(cell_width);
let ch = f64::from(cell_height);
- padding_x = (padding_x + (viewport_size.width - 2. * padding_x) % cw / 2.).floor();
- padding_y = (padding_y + (viewport_size.height - 2. * padding_y) % ch / 2.).floor();
+ padding_x = padding_x + (viewport_size.width - 2. * padding_x) % cw / 2.;
+ padding_y = padding_y + (viewport_size.height - 2. * padding_y) % ch / 2.;
}
- window.set_inner_size(viewport_size.to_logical(dpr));
+ padding_x = padding_x.floor();
+ padding_y = padding_y.floor();
+
+ // Update OpenGL projection
renderer.resize(viewport_size, padding_x as f32, padding_y as f32);
- info!("Cell Size: ({} x {})", cell_width, cell_height);
- info!("Padding: ({} x {})", padding_x, padding_y);
+ info!("Cell Size: {} x {}", cell_width, cell_height);
+ info!("Padding: {} x {}", padding_x, padding_y);
let size_info = SizeInfo {
dpr,
@@ -227,12 +232,41 @@ impl Display {
tx,
rx,
meter: Meter::new(),
- font_size: font::Size::new(0.),
+ font_size: config.font().size(),
size_info,
last_message: None,
})
}
+ fn calculate_dimensions(
+ config: &Config,
+ options: &cli::Options,
+ dpr: f64,
+ cell_width: f32,
+ cell_height: f32,
+ ) -> Option<(f64, f64)> {
+ let dimensions = options.dimensions().unwrap_or_else(|| config.dimensions());
+
+ if dimensions.columns_u32() == 0
+ || dimensions.lines_u32() == 0
+ || config.window().start_maximized()
+ {
+ return None;
+ }
+
+ let padding_x = f64::from(config.padding().x) * dpr;
+ let padding_y = f64::from(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 = (f64::from(grid_width) + 2. * padding_x).floor();
+ let height = (f64::from(grid_height) + 2. * padding_y).floor();
+
+ Some((width, height))
+ }
+
fn new_glyph_cache(
dpr: f64,
renderer: &mut QuadRenderer,
@@ -321,6 +355,16 @@ impl Display {
let font_changed =
terminal.font_size != self.font_size || (dpr - self.size_info.dpr).abs() > f64::EPSILON;
+ // Skip resize if nothing changed
+ if let Some(new_size) = new_size {
+ if !font_changed
+ && (new_size.width - f64::from(self.size_info.width)).abs() < f64::EPSILON
+ && (new_size.height - f64::from(self.size_info.height)).abs() < f64::EPSILON
+ {
+ return;
+ }
+ }
+
if font_changed || self.last_message != terminal.message_buffer_mut().message() {
if new_size == None {
// Force a resize to refresh things