diff options
author | Matt Keeler <mkeeler@users.noreply.github.com> | 2018-11-10 11:08:48 -0500 |
---|---|---|
committer | Christian Duerr <chrisduerr@users.noreply.github.com> | 2018-11-10 16:08:48 +0000 |
commit | 2434547fce7bf47a848f088f2600e8ba7027a62b (patch) | |
tree | 551a50b1071e6208c76c9e26b38b40f60605f2c7 /src | |
parent | 81617983bb4b3b17f18dab938bb572757aa54920 (diff) | |
download | alacritty-2434547fce7bf47a848f088f2600e8ba7027a62b.tar.gz alacritty-2434547fce7bf47a848f088f2600e8ba7027a62b.zip |
Upgrade Glutin to v0.19.0
Some changes include:
• Use the with_hardware_acceleration function on the ContextBuilder to not require the discrete GPU
• Remove the LMenu and RMenu virtual key codes (winit 0.16.0 removed these because Windows now generates LAlt and RAlt instead
• Replace set_cursor_state with hide_cursor (winit 0.16.0 removed the set_cursor_state function)
• Replace GlWindow::hidpi_factor with GlWindow::get_hidpi_factor and change to expecting an f64
• Use the glutin/winit dpi size and position types where possible
Glutin's dpi change event has been implemented. All size events now
return logical sizes. As a result of that, the logical sizes are translated
in the `display::handle_rezize` method so DPI scaling works correctly.
When the DPI is changed, the glyph cache is updated to make use of the
correct font size again.
Moving a window to a different screen which is a different DPI caused a
racing condition where the logical size of the event was sent to the
`handle_resize` method in `src/display.rs`, however if there was a DPI
change event before `handle_resize` is able to process this message, it
would incorrectly use the new DPI to scale the resize event.
To solve this issue instead of sending the logical size to the
`handle_resize` method and then converting it to a physical size in
there, the `LogicalSize` of the resize event is transformed into a
`PhysicalSize` as soon as it's received. This fixes potential racing
conditions since all events are processed in order.
The padding has been changed so it's also scaled by DPR.
The `scale_with_dpi` config option has been removed. If it's not present
a warning will be emitted.
The `winit` dependency on Windows has been removed. All interactions
with winit in Alacritty are handled through glutin.
Diffstat (limited to 'src')
-rw-r--r-- | src/config.rs | 57 | ||||
-rw-r--r-- | src/display.rs | 90 | ||||
-rw-r--r-- | src/event.rs | 33 | ||||
-rw-r--r-- | src/input.rs | 6 | ||||
-rw-r--r-- | src/lib.rs | 5 | ||||
-rw-r--r-- | src/main.rs | 1 | ||||
-rw-r--r-- | src/renderer/mod.rs | 62 | ||||
-rw-r--r-- | src/term/mod.rs | 15 | ||||
-rw-r--r-- | src/window.rs | 139 |
9 files changed, 190 insertions, 218 deletions
diff --git a/src/config.rs b/src/config.rs index 85859cfe..b638ea43 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1869,8 +1869,26 @@ pub struct Font { #[serde(default="true_bool", deserialize_with = "default_true_bool")] use_thin_strokes: bool, - #[serde(default="true_bool", deserialize_with = "default_true_bool")] - scale_with_dpi: bool, + // TODO: Deprecated + #[serde(default, deserialize_with = "deserialize_scale_with_dpi")] + scale_with_dpi: Option<()>, +} + +fn deserialize_scale_with_dpi<'a, D>(deserializer: D) -> ::std::result::Result<Option<()>, D::Error> +where + D: de::Deserializer<'a>, +{ + use ::util::fmt; + // This is necessary in order to get serde to complete deserialization of the configuration + let _ignored = bool::deserialize(deserializer); + eprintln!( + "{}", + fmt::Yellow( + "The `scale_with_dpi` setting has been removed, \ + on X11 the WINIT_HIDPI_FACTOR environment variable can be used instead." + ) + ); + Ok(None) } fn default_bold_desc() -> FontDescription { @@ -1923,11 +1941,6 @@ impl Font { .. self } } - - /// Check whether dpi should be applied - pub fn scale_with_dpi(&self) -> bool { - self.scale_with_dpi - } } #[cfg(target_os = "macos")] @@ -1939,7 +1952,7 @@ impl Default for Font { italic: FontDescription::new_with_family("Menlo"), size: Size::new(11.0), use_thin_strokes: true, - scale_with_dpi: true, + scale_with_dpi: None, glyph_offset: Default::default(), offset: Default::default(), } @@ -1955,7 +1968,7 @@ impl Default for Font { italic: FontDescription::new_with_family("monospace"), size: Size::new(11.0), use_thin_strokes: false, - scale_with_dpi: true, + scale_with_dpi: None, glyph_offset: Default::default(), offset: Default::default(), } @@ -1971,9 +1984,9 @@ impl Default for Font { italic: FontDescription::new_with_family("Consolas"), size: Size::new(11.0), use_thin_strokes: false, - offset: Default::default(), + scale_with_dpi: None, glyph_offset: Default::default(), - scale_with_dpi: false, + offset: Default::default(), } } } @@ -2156,6 +2169,15 @@ pub enum Key { F13, F14, F15, + F16, + F17, + F18, + F19, + F20, + F21, + F22, + F23, + F24, Snapshot, Scroll, Pause, @@ -2206,7 +2228,6 @@ pub enum Key { LAlt, LBracket, LControl, - LMenu, LShift, LWin, Mail, @@ -2231,7 +2252,6 @@ pub enum Key { RAlt, RBracket, RControl, - RMenu, RShift, RWin, Semicolon, @@ -2317,6 +2337,15 @@ impl Key { F13 => Key::F13, F14 => Key::F14, F15 => Key::F15, + F16 => Key::F16, + F17 => Key::F17, + F18 => Key::F18, + F19 => Key::F19, + F20 => Key::F20, + F21 => Key::F21, + F22 => Key::F22, + F23 => Key::F23, + F24 => Key::F24, Snapshot => Key::Snapshot, Scroll => Key::Scroll, Pause => Key::Pause, @@ -2367,7 +2396,6 @@ impl Key { LAlt => Key::LAlt, LBracket => Key::LBracket, LControl => Key::LControl, - LMenu => Key::LMenu, LShift => Key::LShift, LWin => Key::LWin, Mail => Key::Mail, @@ -2392,7 +2420,6 @@ impl Key { RAlt => Key::RAlt, RBracket => Key::RBracket, RControl => Key::RControl, - RMenu => Key::RMenu, RShift => Key::RShift, RWin => Key::RWin, Semicolon => Key::Semicolon, diff --git a/src/display.rs b/src/display.rs index d5a2ea0a..f4d48120 100644 --- a/src/display.rs +++ b/src/display.rs @@ -15,10 +15,11 @@ //! The display subsystem including window management, font rasterization, and //! GPU drawing. use std::sync::mpsc; +use std::f64; use parking_lot::MutexGuard; -use Rgb; +use {LogicalPosition, PhysicalSize, Rgb}; use cli; use config::Config; use font::{self, Rasterize}; @@ -27,7 +28,8 @@ use renderer::{self, GlyphCache, QuadRenderer}; use term::{Term, SizeInfo, RenderableCell}; use sync::FairMutex; -use window::{self, Pixels, SetInnerSize, Size, Window}; +use window::{self, Window}; + #[derive(Debug)] pub enum Error { @@ -93,8 +95,8 @@ pub struct Display { renderer: QuadRenderer, glyph_cache: GlyphCache, render_timer: bool, - rx: mpsc::Receiver<(u32, u32)>, - tx: mpsc::Sender<(u32, u32)>, + rx: mpsc::Receiver<PhysicalSize>, + tx: mpsc::Sender<PhysicalSize>, meter: Meter, font_size: font::Size, size_info: SizeInfo, @@ -135,19 +137,15 @@ impl Display { // Create the window where Alacritty will be displayed let mut window = Window::new(&options, config.window())?; + let dpr = window.hidpi_factor(); + info!("device_pixel_ratio: {}", dpr); + // get window properties for initializing the other subsystems let mut viewport_size = window.inner_size_pixels() - .expect("glutin returns window size"); - let dpr = if config.font().scale_with_dpi() { - window.hidpi_factor() - } else { - 1.0 - }; - - info!("device_pixel_ratio: {}", dpr); + .expect("glutin returns window size").to_physical(dpr); // Create renderer - let mut renderer = QuadRenderer::new(config, viewport_size)?; + let mut renderer = QuadRenderer::new(config, viewport_size, dpr)?; let (glyph_cache, cell_width, cell_height) = Self::new_glyph_cache(dpr, &mut renderer, config)?; @@ -161,25 +159,25 @@ impl Display { let width = cell_width as u32 * dimensions.columns_u32(); let height = cell_height as u32 * dimensions.lines_u32(); - let new_viewport_size = Size { - width: Pixels(width + 2 * u32::from(config.padding().x)), - height: Pixels(height + 2 * u32::from(config.padding().y)), - }; + let new_viewport_size = PhysicalSize::new( + f64::from(width + 2 * (f64::from(config.padding().x) * dpr) as u32), + f64::from(height + 2 * (f64::from(config.padding().y) * dpr) as u32) as f64); - window.set_inner_size(&new_viewport_size); - renderer.resize(new_viewport_size.width.0 as _, new_viewport_size.height.0 as _); - viewport_size = new_viewport_size + window.set_inner_size(new_viewport_size.to_logical(dpr)); + renderer.resize(new_viewport_size, dpr); + viewport_size = new_viewport_size; } info!("Cell Size: ({} x {})", cell_width, cell_height); let size_info = SizeInfo { - width: viewport_size.width.0 as f32, - height: viewport_size.height.0 as f32, + dpr, + width: viewport_size.width as f32, + height: viewport_size.height as f32, cell_width: cell_width as f32, cell_height: cell_height as f32, - padding_x: f32::from(config.padding().x), - padding_y: f32::from(config.padding().y), + padding_x: (f64::from(config.padding().x) * dpr).floor() as f32, + padding_y: (f64::from(config.padding().y) * dpr).floor() as f32, }; // Channel for resize events @@ -215,11 +213,11 @@ impl Display { }) } - fn new_glyph_cache(dpr: f32, renderer: &mut QuadRenderer, config: &Config) + fn new_glyph_cache(dpr: f64, renderer: &mut QuadRenderer, config: &Config) -> Result<(GlyphCache, f32, f32), Error> { let font = config.font().clone(); - let rasterizer = font::Rasterizer::new(dpr, config.use_thin_strokes())?; + let rasterizer = font::Rasterizer::new(dpr as f32, config.use_thin_strokes())?; // Initialize glyph cache let glyph_cache = { @@ -252,10 +250,11 @@ impl Display { } pub fn update_glyph_cache(&mut self, config: &Config) { + let dpr = self.size_info.dpr; let cache = &mut self.glyph_cache; let size = self.font_size; self.renderer.with_loader(|mut api| { - let _ = cache.update_font_size(config.font(), size, &mut api); + let _ = cache.update_font_size(config.font(), size, dpr, &mut api); }); let metrics = cache.font_metrics(); @@ -264,7 +263,7 @@ impl Display { } #[inline] - pub fn resize_channel(&self) -> mpsc::Sender<(u32, u32)> { + pub fn resize_channel(&self) -> mpsc::Sender<PhysicalSize> { self.tx.clone() } @@ -285,26 +284,35 @@ impl Display { let mut new_size = None; // Take most recent resize event, if any - while let Ok(sz) = self.rx.try_recv() { - new_size = Some(sz); + while let Ok(size) = self.rx.try_recv() { + new_size = Some(size); } - // Font size modification detected - if terminal.font_size != self.font_size { - self.font_size = terminal.font_size; - self.update_glyph_cache(config); + // Update the DPR + let dpr = self.window.hidpi_factor(); + // Font size/DPI factor modification detected + if terminal.font_size != self.font_size || (dpr - self.size_info.dpr).abs() > f64::EPSILON { if new_size == None { // Force a resize to refresh things - new_size = Some((self.size_info.width as u32, self.size_info.height as u32)); + new_size = Some(PhysicalSize::new( + f64::from(self.size_info.width) / self.size_info.dpr * dpr, + f64::from(self.size_info.height) / self.size_info.dpr * dpr, + )); } + + self.font_size = terminal.font_size; + self.size_info.dpr = dpr; + self.size_info.padding_x = (f64::from(config.padding().x) * dpr).floor() as f32; + self.size_info.padding_y = (f64::from(config.padding().y) * dpr).floor() as f32; + self.update_glyph_cache(config); } // Receive any resize events; only call gl::Viewport on last // available - if let Some((w, h)) = new_size.take() { - self.size_info.width = w as f32; - self.size_info.height = h as f32; + if let Some(psize) = new_size.take() { + self.size_info.width = psize.width as f32; + self.size_info.height = psize.height as f32; let size = &self.size_info; terminal.resize(size); @@ -313,8 +321,8 @@ impl Display { item.on_resize(size) } - self.window.resize(w, h); - self.renderer.resize(w as i32, h as i32); + self.window.resize(psize); + self.renderer.resize(psize, dpr); } } @@ -416,7 +424,7 @@ impl Display { padding_y: py, ..} = *terminal.size_info(); let nspot_y = (py + (row + 1) as f32 * ch) as i32; let nspot_x = (px + col as f32 * cw) as i32; - self.window().set_ime_spot(nspot_x, nspot_y); + self.window().set_ime_spot(LogicalPosition::from((nspot_x, nspot_y))); } } diff --git a/src/event.rs b/src/event.rs index b3def0eb..a61450f3 100644 --- a/src/event.rs +++ b/src/event.rs @@ -23,6 +23,7 @@ use term::{Term, SizeInfo, TermMode, Search}; use util::limit; use util::fmt::Red; use window::Window; +use PhysicalSize; /// Byte sequences are sent to a `Notify` in response to some events pub trait Notify { @@ -35,7 +36,7 @@ pub trait Notify { pub struct ActionContext<'a, N: 'a> { pub notifier: &'a mut N, pub terminal: &'a mut Term, - pub size_info: &'a SizeInfo, + pub size_info: &'a mut SizeInfo, pub mouse: &'a mut Mouse, pub received_count: &'a mut usize, pub suppress_chars: &'a mut bool, @@ -251,7 +252,7 @@ pub struct Processor<N> { wait_for_event: bool, notifier: N, mouse: Mouse, - resize_tx: mpsc::Sender<(u32, u32)>, + resize_tx: mpsc::Sender<PhysicalSize>, ref_test: bool, size_info: SizeInfo, hide_mouse_when_typing: bool, @@ -280,7 +281,7 @@ impl<N: Notify> Processor<N> { /// pty. pub fn new( notifier: N, - resize_tx: mpsc::Sender<(u32, u32)>, + resize_tx: mpsc::Sender<PhysicalSize>, options: &Options, config: &Config, ref_test: bool, @@ -316,7 +317,7 @@ impl<N: Notify> Processor<N> { processor: &mut input::Processor<'a, ActionContext<'a, N>>, event: Event, ref_test: bool, - resize_tx: &mpsc::Sender<(u32, u32)>, + resize_tx: &mpsc::Sender<PhysicalSize>, hide_mouse: &mut bool, window_is_focused: &mut bool, ) { @@ -350,8 +351,13 @@ impl<N: Notify> Processor<N> { // FIXME should do a more graceful shutdown ::std::process::exit(0); }, - Resized(w, h) => { - resize_tx.send((w, h)).expect("send new size"); + Resized(lsize) => { + // Resize events are emitted via glutin/winit with logical sizes + // However the terminal, window and renderer use physical sizes + // so a conversion must be done here + resize_tx + .send(lsize.to_physical(processor.ctx.size_info.dpr)) + .expect("send new size"); processor.ctx.terminal.dirty = true; }, KeyboardInput { input, .. } => { @@ -371,9 +377,10 @@ impl<N: Notify> Processor<N> { processor.ctx.terminal.dirty = true; } }, - CursorMoved { position: (x, y), modifiers, .. } => { - let x = limit(x as i32, 0, processor.ctx.size_info.width as i32); - let y = limit(y as i32, 0, processor.ctx.size_info.height as i32); + CursorMoved { position: lpos, modifiers, .. } => { + let (x, y) = lpos.to_physical(processor.ctx.size_info.dpr).into(); + let x: i32 = limit(x, 0, processor.ctx.size_info.width as i32); + let y: i32 = limit(y, 0, processor.ctx.size_info.height as i32); *hide_mouse = false; processor.mouse_moved(x as usize, y as usize, modifiers); @@ -402,7 +409,11 @@ impl<N: Notify> Processor<N> { use input::ActionContext; let path: String = path.to_string_lossy().into(); processor.ctx.write_to_pty(path.into_bytes()); - } + }, + HiDpiFactorChanged(new_dpr) => { + processor.ctx.size_info.dpr = new_dpr; + processor.ctx.terminal.dirty = true; + }, _ => (), } }, @@ -453,7 +464,7 @@ impl<N: Notify> Processor<N> { terminal: &mut terminal, notifier: &mut self.notifier, mouse: &mut self.mouse, - size_info: &self.size_info, + size_info: &mut self.size_info, received_count: &mut self.received_count, suppress_chars: &mut self.suppress_chars, last_modifiers: &mut self.last_modifiers, diff --git a/src/input.rs b/src/input.rs index 5235066b..600a1abe 100644 --- a/src/input.rs +++ b/src/input.rs @@ -575,14 +575,15 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> { self.ctx.mouse_mut().lines_scrolled = to_scroll % 1.0; }, - MouseScrollDelta::PixelDelta(_x, y) => { + MouseScrollDelta::PixelDelta(lpos) => { match phase { TouchPhase::Started => { // Reset offset to zero self.ctx.mouse_mut().scroll_px = 0; }, TouchPhase::Moved => { - self.ctx.mouse_mut().scroll_px += y as i32; + let (_x, y): (i32, i32) = lpos.into(); + self.ctx.mouse_mut().scroll_px += y; let height = self.ctx.size_info().cell_height as i32; while self.ctx.mouse().scroll_px.abs() >= height { @@ -904,6 +905,7 @@ mod tests { cell_height: 3.0, padding_x: 0.0, padding_y: 0.0, + dpr: 1.0, }; let mut terminal = Term::new(&config, size); @@ -36,8 +36,6 @@ extern crate winpty; #[cfg(windows)] extern crate dunce; #[cfg(windows)] -extern crate winit; -#[cfg(windows)] extern crate image; #[cfg(target_os = "macos")] @@ -95,6 +93,9 @@ use std::ops::Mul; pub use grid::Grid; pub use term::Term; +/// Re-export size and position types from glutin/winit +pub use glutin::dpi::{PhysicalSize,LogicalSize,LogicalPosition,PhysicalPosition}; + /// Facade around [winit's `MouseCursor`](glutin::MouseCursor) #[derive(Debug, Eq, PartialEq, Copy, Clone)] pub enum MouseCursor { diff --git a/src/main.rs b/src/main.rs index af21b980..e72df15d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -223,6 +223,7 @@ fn run(mut config: Config, options: &cli::Options) -> Result<(), Box<Error>> { // Maybe draw the terminal if terminal_lock.needs_draw() { // Try to update the position of the input method editor + #[cfg(not(windows))] display.update_ime_position(&terminal_lock); // Handle pending resize events diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index 28b44633..cb36210f 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -31,9 +31,7 @@ use notify::{watcher, DebouncedEvent, RecursiveMode, Watcher}; use config::{self, Config, Delta}; use term::{self, cell, RenderableCell}; -use window::{Pixels, Size}; - -use Rgb; +use {PhysicalSize, Rgb}; // Shader paths for live reload static TEXT_SHADER_F_PATH: &'static str = concat!(env!("CARGO_MANIFEST_DIR"), "/res/text.f.glsl"); @@ -291,20 +289,25 @@ impl GlyphCache { &mut self, font: &config::Font, size: font::Size, + dpr: f64, loader: &mut L ) -> Result<(), font::Error> { // Clear currently cached data in both GL and the registry loader.clear(); self.cache = HashMap::default(); + // Update dpi scaling + self.rasterizer.update_dpr(dpr as f32); + // Recompute font keys let font = font.to_owned().with_size(size); - info!("Font size changed: {:?}", font.size); let (regular, bold, italic) = Self::compute_font_keys(&font, &mut self.rasterizer)?; self.rasterizer.get_glyph(GlyphKey { font_key: regular, c: 'm', size: font.size() })?; let metrics = self.rasterizer.metrics(regular, size)?; + info!("Font size changed: {:?} [DPR: {}]", font.size, dpr); + self.font_size = font.size; self.font_key = regular; self.bold_key = bold; @@ -468,8 +471,8 @@ const ATLAS_SIZE: i32 = 1024; impl QuadRenderer { // TODO should probably hand this a transform instead of width/height - pub fn new(config: &Config, size: Size<Pixels<u32>>) -> Result<QuadRenderer, Error> { - let program = ShaderProgram::new(config, size)?; + pub fn new(config: &Config, size: PhysicalSize, dpr: f64) -> Result<QuadRenderer, Error> { + let program = ShaderProgram::new(config, size, dpr)?; let mut vao: GLuint = 0; let mut vbo: GLuint = 0; @@ -664,13 +667,7 @@ impl QuadRenderer { while let Ok(msg) = self.rx.try_recv() { match msg { Msg::ShaderReload => { - self.reload_shaders( - config, - Size { - width: Pixels(props.width as u32), - height: Pixels(props.height as u32), - }, - ); + self.reload_shaders(config, PhysicalSize::new(f64::from(props.width), f64::from(props.height)), props.dpr); } } } @@ -722,9 +719,9 @@ impl QuadRenderer { }) } - pub fn reload_shaders(&mut self, config: &Config, size: Size<Pixels<u32>>) { + pub fn reload_shaders(&mut self, config: &Config, size: PhysicalSize, dpr: f64) { warn!("Reloading shaders ..."); - let program = match ShaderProgram::new(config, size) { + let program = match ShaderProgram::new(config, size, dpr) { Ok(program) => { warn!(" ... OK"); program @@ -750,23 +747,20 @@ impl QuadRenderer { self.program = program; } - pub fn resize(&mut self, width: i32, height: i32) { - let padding_x = i32::from(self.program.padding_x); - let padding_y = i32::from(self.program.padding_y); + pub fn resize(&mut self, size: PhysicalSize, dpr: f64) { + let (width, height) : (u32, u32) = size.into(); + + let padding_x = (f64::from(self.program.padding_x) * dpr) as i32; + let padding_y = (f64::from(self.program.padding_y) * dpr) as i32; // viewport unsafe { - gl::Viewport( - padding_x, - padding_y, - width - 2 * padding_x, - height - 2 * padding_y, - ); + gl::Viewport(padding_x, padding_y, (width as i32) - 2 * padding_x, (height as i32) - 2 * padding_y); } // update projection self.program.activate(); - self.program.update_projection(width as f32, height as f32); + self.program.update_projection(width as f32, height as f32, dpr as f32); self.program.deactivate(); } } @@ -1004,7 +998,8 @@ impl ShaderProgram { pub fn new( config: &Config, - size: Size<Pixels<u32>>, + size: PhysicalSize, + dpr: f64 ) -> Result<ShaderProgram, ShaderCreationError> { let vertex_source = if cfg!(feature = "live-shader-reload") { None @@ -1066,17 +1061,20 @@ impl ShaderProgram { padding_y: config.padding().y, }; - shader.update_projection(*size.width as f32, *size.height as f32); + shader.update_projection(size.width as f32, size.height as f32, dpr as f32); shader.deactivate(); Ok(shader) } - fn update_projection(&self, width: f32, height: f32) { + fn update_projection(&self, width: f32, height: f32, dpr: f32) { + let padding_x = (f32::from(self.padding_x) * dpr).floor(); + let padding_y = (f32::from(self.padding_y) * dpr).floor(); + // Bounds check - if (width as u32) < (2 * u32::from(self.padding_x)) || - (height as u32) < (2 * u32::from(self.padding_y)) + if (width as u32) < (2 * padding_x as u32) || + (height as u32) < (2 * padding_y as u32) { return; } @@ -1088,8 +1086,8 @@ impl ShaderProgram { // correctly. let ortho = cgmath::ortho( 0., - width - 2. * f32::from(self.padding_x), - 2. * f32::from(self.padding_y), + width - (2. * padding_x), + 2. * padding_y, height, -1., 1., diff --git a/src/term/mod.rs b/src/term/mod.rs index 971755af..39213ee2 100644 --- a/src/term/mod.rs +++ b/src/term/mod.rs @@ -832,6 +832,10 @@ pub struct SizeInfo { /// Horizontal window padding pub padding_y: f32, + + /// DPI factor of the current window + #[serde(default)] + pub dpr: f64, } impl SizeInfo { @@ -2065,6 +2069,7 @@ mod tests { cell_height: 3.0, padding_x: 0.0, padding_y: 0.0, + dpr: 1.0, }; let mut term = Term::new(&Default::default(), size); let mut grid: Grid<Cell> = Grid::new(Line(3), Column(5), 0, Cell::default()); @@ -2108,6 +2113,7 @@ mod tests { cell_height: 3.0, padding_x: 0.0, padding_y: 0.0, + dpr: 1.0, }; let mut term = Term::new(&Default::default(), size); let mut grid: Grid<Cell> = Grid::new(Line(1), Column(5), 0, Cell::default()); @@ -2133,6 +2139,7 @@ mod tests { cell_height: 3.0, padding_x: 0.0, padding_y: 0.0, + dpr: 1.0, }; let mut term = Term::new(&Default::default(), size); let mut grid: Grid<Cell> = Grid::new(Line(3), Column(3), 0, Cell::default()); @@ -2177,6 +2184,7 @@ mod tests { cell_height: 3.0, padding_x: 0.0, padding_y: 0.0, + dpr: 1.0, }; let mut term = Term::new(&Default::default(), size); let cursor = Point::new(Line(0), Column(0)); @@ -2195,6 +2203,7 @@ mod tests { cell_height: 3.0, padding_x: 0.0, padding_y: 0.0, + dpr: 1.0, }; let config: Config = Default::default(); let mut term: Term = Term::new(&config, size); @@ -2223,6 +2232,7 @@ mod tests { cell_height: 3.0, padding_x: 0.0, padding_y: 0.0, + dpr: 1.0, }; let config: Config = Default::default(); let mut term: Term = Term::new(&config, size); @@ -2242,6 +2252,7 @@ mod tests { cell_height: 3.0, padding_x: 0.0, padding_y: 0.0, + dpr: 1.0, }; let config: Config = Default::default(); let mut term: Term = Term::new(&config, size); @@ -2262,6 +2273,7 @@ mod tests { cell_height: 3.0, padding_x: 0.0, padding_y: 0.0, + dpr: 1.0 }; let config: Config = Default::default(); let mut term: Term = Term::new(&config, size); @@ -2288,6 +2300,7 @@ mod tests { cell_height: 3.0, padding_x: 0.0, padding_y: 0.0, + dpr: 1.0, }; let mut term = Term::new(&Default::default(), size); let mut grid: Grid<Cell> = Grid::new(Line(1), Column(15), 0, Cell::default()); @@ -2323,6 +2336,7 @@ mod tests { cell_height: 3.0, padding_x: 0.0, padding_y: 0.0, + dpr: 1.0, }; let mut term = Term::new(&Default::default(), size); let mut grid: Grid<Cell> = Grid::new(Line(1), Column(15), 0, Cell::default()); @@ -2357,6 +2371,7 @@ mod tests { cell_height: 3.0, padding_x: 0.0, padding_y: 0.0, + dpr: 1.0, }; let mut term = Term::new(&Default::default(), size); let mut grid: Grid<Cell> = Grid::new(Line(1), Column(15), 0, Cell::default()); diff --git a/src/window.rs b/src/window.rs index cb753d40..a19fd9c5 100644 --- a/src/window.rs +++ b/src/window.rs @@ -12,21 +12,21 @@ // See the License for the specific language governing permissions and // limitations under the License. use std::convert::From; -use std::fmt::{self, Display}; -use std::ops::Deref; +use std::fmt::Display; use gl; use glutin::GlContext; #[cfg(windows)] -use winit::Icon; +use glutin::Icon; #[cfg(windows)] use image::ImageFormat; use glutin::{ - self, ContextBuilder, ControlFlow, CursorState, Event, EventsLoop, + self, ContextBuilder, ControlFlow, Event, EventsLoop, MouseCursor as GlutinMouseCursor, WindowBuilder, }; -use MouseCursor; +use {LogicalPosition, LogicalSize, MouseCursor, PhysicalSize}; + use cli::Options; use config::{Decorations, WindowConfig}; @@ -90,82 +90,7 @@ pub struct DeviceProperties { /// /// This will be 1. on standard displays and may have a different value on /// hidpi displays. - pub scale_factor: f32, -} - -/// Size of the window -#[derive(Debug, Copy, Clone)] -pub struct Size<T> { - pub width: T, - pub height: T, -} - -/// Strongly typed Pixels unit -#[derive(Debug, Copy, Clone)] -pub struct Pixels<T>(pub T); - -/// Strongly typed Points unit -/// -/// Points are like pixels but adjusted for DPI. -#[derive(Debug, Copy, Clone)] -pub struct Points<T>(pub T); - -pub trait ToPoints { - fn to_points(&self, scale: f32) -> Size<Points<u32>>; -} - -impl ToPoints for Size<Points<u32>> { - #[inline] - fn to_points(&self, _scale: f32) -> Size<Points<u32>> { - *self - } -} - -impl ToPoints for Size<Pixels<u32>> { - fn to_points(&self, scale: f32) -> Size<Points<u32>> { - let width_pts = (*self.width as f32 / scale) as u32; - let height_pts = (*self.height as f32 / scale) as u32; - - Size { - width: Points(width_pts), - height: Points(height_pts), - } - } -} - -impl<T: Display> Display for Size<T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{} × {}", self.width, self.height) - } -} - -macro_rules! deref_newtype { - ($($src:ty),+) => { - $( - impl<T> Deref for $src { - type Target = T; - - #[inline] - fn deref(&self) -> &Self::Target { - &self.0 - } - } - )+ - } -} - -deref_newtype! { Points<T>, Pixels<T> } - -impl<T: Display> Display for Pixels<T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}px", self.0) - } -} - -impl<T: Display> Display for Points<T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}pts", self.0) - } + pub scale_factor: f64, } impl ::std::error::Error for Error { @@ -210,7 +135,10 @@ fn create_gl_window( event_loop: &EventsLoop, srgb: bool, ) -> ::std::result::Result<glutin::GlWindow, glutin::CreationError> { - let context = ContextBuilder::new().with_srgb(srgb).with_vsync(true); + let context = ContextBuilder::new() + .with_srgb(srgb) + .with_vsync(true) + .with_hardware_acceleration(None); ::glutin::GlWindow::new(window, context, event_loop) } @@ -258,20 +186,21 @@ impl Window { /// rasterization depend on DPI and scale factor. pub fn device_properties(&self) -> DeviceProperties { DeviceProperties { - scale_factor: self.window.hidpi_factor(), + scale_factor: self.window.get_hidpi_factor(), } } - pub fn inner_size_pixels(&self) -> Option<Size<Pixels<u32>>> { - self.window.get_inner_size().map(|(w, h)| Size { - width: Pixels(w), - height: Pixels(h), - }) + pub fn inner_size_pixels(&self) -> Option<LogicalSize> { + self.window.get_inner_size() + } + + pub fn set_inner_size(&mut self, size: LogicalSize) { + self.window.set_inner_size(size); } #[inline] - pub fn hidpi_factor(&self) -> f32 { - self.window.hidpi_factor() + pub fn hidpi_factor(&self) -> f64 { + self.window.get_hidpi_factor() } #[inline] @@ -296,8 +225,8 @@ impl Window { } #[inline] - pub fn resize(&self, width: u32, height: u32) { - self.window.resize(width, height); + pub fn resize(&self, size: PhysicalSize) { + self.window.resize(size); } /// Block waiting for events @@ -330,13 +259,7 @@ impl Window { pub fn set_mouse_visible(&mut self, visible: bool) { if visible != self.mouse_visible { self.mouse_visible = visible; - if let Err(err) = self.window.set_cursor_state(if visible { - CursorState::Normal - } else { - CursorState::Hide - }) { - warn!("Failed to set mouse cursor visibility: {}", err); - } + self.window.hide_cursor(!visible); } } @@ -448,10 +371,8 @@ impl Window { )] pub fn set_urgent(&self, _is_urgent: bool) {} - pub fn set_ime_spot(&self, _x: i32, _y: i32) { - // This is not implemented on windows as of winit 0.15.1 - #[cfg(not(windows))] - self.window.set_ime_spot(_x, _y); + pub fn set_ime_spot(&self, pos: LogicalPosition) { + self.window.set_ime_spot(pos); } #[cfg(not(any(target_os = "macos", target_os = "windows")))] @@ -554,15 +475,3 @@ impl Proxy { self.inner.wakeup().unwrap(); } } - -pub trait SetInnerSize<T> { - fn set_inner_size<S: ToPoints>(&mut self, size: &S); -} - -impl SetInnerSize<Pixels<u32>> for Window { - fn set_inner_size<T: ToPoints>(&mut self, size: &T) { - let size = size.to_points(self.hidpi_factor()); - self.window - .set_inner_size(*size.width as _, *size.height as _); - } -} |