From 3443033dec3b0db909f83f0019c15b6161784da8 Mon Sep 17 00:00:00 2001 From: Greg V Date: Tue, 3 Apr 2018 02:11:43 +0300 Subject: [PATCH] Handle HiDPI factor change event The Display's resize channel is now a command channel, for both resize and factor change commands --- font/src/darwin/mod.rs | 4 ++++ font/src/ft/mod.rs | 3 +++ font/src/lib.rs | 3 +++ src/bin/alacritty.rs | 4 ++-- src/display.rs | 27 ++++++++++++++++++--------- src/event.rs | 20 ++++++++++++-------- src/renderer/mod.rs | 4 ++++ 7 files changed, 46 insertions(+), 19 deletions(-) diff --git a/font/src/darwin/mod.rs b/font/src/darwin/mod.rs index 14381113b14..dd617408bc1 100644 --- a/font/src/darwin/mod.rs +++ b/font/src/darwin/mod.rs @@ -183,6 +183,10 @@ impl ::Rasterize for Rasterizer { Err(Error::MissingGlyph(glyph.c)) }) } + + fn set_device_pixel_ratio(&mut self, dpr: f32) { + self.device_pixel_ratio = dpr; + } } impl Rasterizer { diff --git a/font/src/ft/mod.rs b/font/src/ft/mod.rs index 68d2faf3d6b..b0d9642892c 100644 --- a/font/src/ft/mod.rs +++ b/font/src/ft/mod.rs @@ -106,6 +106,9 @@ impl ::Rasterize for FreeTypeRasterizer { self.get_rendered_glyph(glyph_key) } + fn set_device_pixel_ratio(&mut self, dpr: f32) { + self.device_pixel_ratio = dpr; + } } pub trait IntoFontconfigType { diff --git a/font/src/lib.rs b/font/src/lib.rs index 330ed362083..5984b9d1ed2 100644 --- a/font/src/lib.rs +++ b/font/src/lib.rs @@ -332,4 +332,7 @@ pub trait Rasterize { /// Rasterize the glyph described by `GlyphKey`. fn get_glyph(&mut self, &GlyphKey) -> Result; + + /// Update stored device pixel ratio + fn set_device_pixel_ratio(&mut self, f32); } diff --git a/src/bin/alacritty.rs b/src/bin/alacritty.rs index 5d4e3fb072b..8497a14006a 100644 --- a/src/bin/alacritty.rs +++ b/src/bin/alacritty.rs @@ -164,7 +164,7 @@ fn run(mut config: Config, options: &cli::Options) -> Result<(), Box> { // Need the Rc> here since a ref is shared in the resize callback let mut processor = event::Processor::new( event_loop::Notifier(event_loop.channel()), - display.resize_channel(), + display.command_channel(), options, &config, options.ref_test, @@ -209,7 +209,7 @@ fn run(mut config: Config, options: &cli::Options) -> Result<(), Box> { // Try to update the position of the input method editor let (x, y) = display.current_xim_spot(&terminal); window.send_xim_spot(x, y); - // Handle pending resize events + // Handle pending resize (and HiDPI factor change) events // // The second argument is a list of types that want to be notified // of display size changes. diff --git a/src/display.rs b/src/display.rs index f01736a61aa..80e8e1f9285 100644 --- a/src/display.rs +++ b/src/display.rs @@ -86,13 +86,18 @@ impl From for Error { } } +pub enum DisplayCommand { + NewSize(u32, u32), + NewHiDPIFactor(f32), +} + /// The display wraps a window, font rasterizer, and GPU renderer pub struct Display { renderer: QuadRenderer, glyph_cache: GlyphCache, render_timer: bool, - rx: mpsc::Receiver<(u32, u32)>, - tx: mpsc::Sender<(u32, u32)>, + rx: mpsc::Receiver, + tx: mpsc::Sender, meter: Meter, font_size: font::Size, size_info: SizeInfo, @@ -220,11 +225,11 @@ impl Display { Ok((glyph_cache, cell_width.floor(), cell_height.floor())) } - pub fn update_glyph_cache(&mut self, config: &Config) { + pub fn update_glyph_cache(&mut self, config: &Config, new_dpr: Option) { 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, new_dpr, &mut api); }); let metrics = cache.font_metrics(); @@ -233,11 +238,11 @@ impl Display { } #[inline] - pub fn resize_channel(&self) -> mpsc::Sender<(u32, u32)> { + pub fn command_channel(&self) -> mpsc::Sender { self.tx.clone() } - /// Process pending resize events + /// Process pending resize (and HiDPI factor) events pub fn handle_resize( &mut self, terminal: &mut MutexGuard, @@ -248,16 +253,20 @@ impl Display { // iterator. This has the effect of coalescing multiple resize // events into one. let mut new_size = None; + let mut new_dpr = None; // Take most recent resize event, if any while let Ok(sz) = self.rx.try_recv() { - new_size = Some(sz); + match sz { + DisplayCommand::NewSize(w, h) => new_size = Some((w, h)), + DisplayCommand::NewHiDPIFactor(dpr) => new_dpr = Some(dpr) + } } // Font size modification detected - if terminal.font_size != self.font_size { + if terminal.font_size != self.font_size || new_dpr.is_some() { self.font_size = terminal.font_size; - self.update_glyph_cache(config); + self.update_glyph_cache(config, new_dpr); if new_size == None { // Force a resize to refresh things diff --git a/src/event.rs b/src/event.rs index 72cc61e69f0..a69579a0efd 100644 --- a/src/event.rs +++ b/src/event.rs @@ -12,7 +12,7 @@ use copypasta::{Clipboard, Load, Store}; use config::{self, Config}; use cli::Options; -use display::OnResize; +use display::{OnResize, DisplayCommand}; use index::{Line, Column, Side, Point}; use input::{self, MouseBinding, KeyBinding}; use selection::Selection; @@ -190,7 +190,7 @@ pub struct Processor { wait_for_event: bool, notifier: N, mouse: Mouse, - resize_tx: mpsc::Sender<(u32, u32)>, + display_tx: mpsc::Sender, ref_test: bool, size_info: SizeInfo, pub selection: Option, @@ -219,7 +219,7 @@ impl Processor { /// pty. pub fn new( notifier: N, - resize_tx: mpsc::Sender<(u32, u32)>, + display_tx: mpsc::Sender, options: &Options, config: &Config, ref_test: bool, @@ -232,7 +232,7 @@ impl Processor { print_events: options.print_events, wait_for_event: true, notifier, - resize_tx, + display_tx, ref_test, mouse: Default::default(), selection: None, @@ -253,7 +253,7 @@ impl Processor { processor: &mut input::Processor<'a, ActionContext<'a, N>>, event: Event, ref_test: bool, - resize_tx: &mpsc::Sender<(u32, u32)>, + display_tx: &mpsc::Sender, hide_cursor: &mut bool, window_is_focused: &mut bool, ) { @@ -287,9 +287,13 @@ impl Processor { ::std::process::exit(0); }, Resized(w, h) => { - resize_tx.send((w, h)).expect("send new size"); + display_tx.send(DisplayCommand::NewSize(w, h)).expect("send new size"); processor.ctx.terminal.dirty = true; }, + HiDPIFactorChanged(dpr) => { + display_tx.send(DisplayCommand::NewHiDPIFactor(dpr)).expect("send new size"); + processor.ctx.terminal.dirty = true; + } KeyboardInput { input, .. } => { let glutin::KeyboardInput { state, virtual_keycode, modifiers, .. } = input; processor.process_key(state, virtual_keycode, &modifiers); @@ -370,7 +374,7 @@ impl Processor { let print_events = self.print_events; let ref_test = self.ref_test; - let resize_tx = &self.resize_tx; + let display_tx = &self.display_tx; if self.wait_for_event { // A Vec is used here since wait_events can potentially yield @@ -418,7 +422,7 @@ impl Processor { &mut processor, event, ref_test, - resize_tx, + display_tx, hide_cursor, &mut window_is_focused, ); diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index 56ae4b14505..911bb0981ce 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -296,6 +296,7 @@ impl GlyphCache { &mut self, font: &config::Font, size: font::Size, + new_dpr: Option, loader: &mut L ) -> Result<(), font::Error> { // Clear currently cached data in both GL and the registry @@ -306,6 +307,9 @@ impl GlyphCache { 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)?; + if let Some(dpr) = new_dpr { + self.rasterizer.set_device_pixel_ratio(dpr); + } self.rasterizer.get_glyph(&GlyphKey { font_key: regular, c: 'm', size: font.size() })?; let metrics = self.rasterizer.metrics(regular)?;