aboutsummaryrefslogtreecommitdiff
path: root/src/display.rs
diff options
context:
space:
mode:
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