From 4e01dec636f9f0cf3c113b4ac587eb921efba275 Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Sun, 27 Oct 2019 17:48:02 -0700 Subject: [PATCH] font scaling now also resizes the window for opengl+software frontend --- src/frontend/software/termwindow.rs | 18 +++++++++++++++++- window/src/lib.rs | 6 ++++++ window/src/os/macos/window.rs | 17 +++++++++++++++++ window/src/os/windows/window.rs | 4 ++++ window/src/os/x11/window.rs | 5 +++++ 5 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/frontend/software/termwindow.rs b/src/frontend/software/termwindow.rs index e7858e432..0c4a8cea9 100644 --- a/src/frontend/software/termwindow.rs +++ b/src/frontend/software/termwindow.rs @@ -565,7 +565,13 @@ impl TermWindow { fn scaling_changed(&mut self, dimensions: Dimensions, font_scale: f64) { let mux = Mux::get().unwrap(); if let Some(window) = mux.get_window(self.mux_window_id) { - if dimensions.dpi != self.dimensions.dpi || font_scale != self.fonts.get_font_scale() { + let cols = self.dimensions.pixel_width / self.render_metrics.cell_size.width as usize; + let rows = self.dimensions.pixel_height / self.render_metrics.cell_size.height as usize; + + let scale_changed = + dimensions.dpi != self.dimensions.dpi || font_scale != self.fonts.get_font_scale(); + + if scale_changed { self.fonts .change_scaling(font_scale, dimensions.dpi as f64 / 96.); self.render_metrics = RenderMetrics::new(&self.fonts); @@ -593,6 +599,16 @@ impl TermWindow { for tab in window.iter() { tab.resize(size).ok(); } + + // Queue up a speculative resize in order to preserve the number of rows+cols + if scale_changed { + if let Some(window) = self.window.as_ref() { + window.set_inner_size( + cols * self.render_metrics.cell_size.width as usize, + rows * self.render_metrics.cell_size.height as usize, + ); + } + } }; } diff --git a/window/src/lib.rs b/window/src/lib.rs index aae4273de..3b7dcb934 100644 --- a/window/src/lib.rs +++ b/window/src/lib.rs @@ -169,6 +169,9 @@ pub trait WindowOps { /// Change the titlebar text for the window fn set_title(&self, title: &str); + /// Resize the inner or client area of the window + fn set_inner_size(&self, width: usize, height: usize); + /// Schedule a callback on the data associated with the window. /// The `Any` that is passed in corresponds to the WindowCallbacks /// impl you passed to `new_window`, pre-converted to Any so that @@ -208,4 +211,7 @@ pub trait WindowOpsMut { /// Change the titlebar text for the window fn set_title(&mut self, title: &str); + + /// Resize the inner or client area of the window + fn set_inner_size(&self, width: usize, height: usize); } diff --git a/window/src/os/macos/window.rs b/window/src/os/macos/window.rs index c7608dcb3..d90a4ab5e 100644 --- a/window/src/os/macos/window.rs +++ b/window/src/os/macos/window.rs @@ -296,6 +296,10 @@ impl WindowOps for Window { Connection::with_window_inner(self.0, move |inner| inner.set_title(&title)); } + fn set_inner_size(&self, width: usize, height: usize) { + Connection::with_window_inner(self.0, move |inner| inner.set_inner_size(width, height)); + } + fn apply(&self, func: F) where Self: Sized, @@ -381,6 +385,19 @@ impl WindowOpsMut for WindowInner { NSWindow::setTitle_(*self.window, *title); } } + + fn set_inner_size(&self, width: usize, height: usize) { + unsafe { + let frame = NSView::frame(*self.view as *mut _); + let backing_frame = NSView::convertRectToBacking(*self.view as *mut _, frame); + let scale = backing_frame.size.width / frame.size.width; + + NSWindow::setContentSize_( + *self.window, + NSSize::new(width as f64 / scale, height as f64 / scale), + ); + } + } } struct Inner { diff --git a/window/src/os/windows/window.rs b/window/src/os/windows/window.rs index 77a8af295..fc4bd41ef 100644 --- a/window/src/os/windows/window.rs +++ b/window/src/os/windows/window.rs @@ -239,6 +239,8 @@ impl WindowOpsMut for WindowInner { } } + fn set_inner_size(&self, _width: usize, _height: usize) {} + fn set_title(&mut self, title: &str) { let title = wide_string(title); unsafe { @@ -271,6 +273,8 @@ impl WindowOps for Window { Connection::with_window_inner(self.0, move |inner| inner.set_title(&title)); } + fn set_inner_size(&self, _width: usize, _height: usize) {} + fn apply(&self, func: F) where Self: Sized, diff --git a/window/src/os/x11/window.rs b/window/src/os/x11/window.rs index e2ef27642..13dfdb32c 100644 --- a/window/src/os/x11/window.rs +++ b/window/src/os/x11/window.rs @@ -466,6 +466,8 @@ impl WindowOpsMut for WindowInner { self.paint_all = true; } + fn set_inner_size(&self, _width: usize, _height: usize) {} + /// Change the title for the window manager fn set_title(&mut self, title: &str) { xcb_util::icccm::set_wm_name(self.conn.conn(), self.window_id, title); @@ -494,6 +496,9 @@ impl WindowOps for Window { let title = title.to_owned(); Connection::with_window_inner(self.0, move |inner| inner.set_title(&title)); } + + fn set_inner_size(&self, _width: usize, _height: usize) {} + fn apply(&self, func: F) where Self: Sized,