From 67aa729f95b954a7ea49166edacafd175669e15a Mon Sep 17 00:00:00 2001 From: kryptan Date: Thu, 12 Oct 2017 02:49:57 +0300 Subject: [PATCH 1/3] Implement public API for high-DPI #105 --- src/events.rs | 9 +++++ src/platform/android/mod.rs | 5 +++ src/platform/emscripten/mod.rs | 5 +++ src/platform/ios/mod.rs | 5 +++ src/platform/linux/mod.rs | 5 +++ src/platform/linux/wayland/context.rs | 5 +++ src/platform/linux/x11/monitor.rs | 5 +++ src/platform/macos/monitor.rs | 5 +++ src/platform/windows/monitor.rs | 5 +++ src/window.rs | 47 +++++++-------------------- 10 files changed, 61 insertions(+), 35 deletions(-) diff --git a/src/events.rs b/src/events.rs index 24b815efa7..ef5c6e9b99 100644 --- a/src/events.rs +++ b/src/events.rs @@ -87,6 +87,15 @@ pub enum WindowEvent { /// Touch event has been received Touch(Touch), + + /// DPI scaling factor of the window has changed. + /// + /// The following actions cause DPI changes: + /// + /// * A user changes the resolution. + /// * A user changes the desktop scaling value (e.g. in Control Panel on Windows). + /// * A user moves the application window to a display with a different DPI. + HiDPIFactorChanged(f32), } /// Represents raw hardware events that are not associated with any particular window. diff --git a/src/platform/android/mod.rs b/src/platform/android/mod.rs index 037477beb1..ca10a94e33 100644 --- a/src/platform/android/mod.rs +++ b/src/platform/android/mod.rs @@ -164,6 +164,11 @@ impl MonitorId { // Android assumes single screen (0, 0) } + + #[inline] + pub fn get_hidpi_factor(&self) -> f32 { + 1.0 + } } #[derive(Clone, Default)] diff --git a/src/platform/emscripten/mod.rs b/src/platform/emscripten/mod.rs index 1d89392866..a3389cf0ec 100644 --- a/src/platform/emscripten/mod.rs +++ b/src/platform/emscripten/mod.rs @@ -42,6 +42,11 @@ impl MonitorId { pub fn get_dimensions(&self) -> (u32, u32) { (0, 0) } + + #[inline] + pub fn get_hidpi_factor(&self) -> f32 { + 1.0 + } } // Used to assign a callback to emscripten main loop diff --git a/src/platform/ios/mod.rs b/src/platform/ios/mod.rs index 9d74626423..5148097783 100644 --- a/src/platform/ios/mod.rs +++ b/src/platform/ios/mod.rs @@ -145,6 +145,11 @@ impl MonitorId { // iOS assumes single screen (0, 0) } + + #[inline] + pub fn get_hidpi_factor(&self) -> f32 { + 1.0 + } } pub struct EventsLoop { diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs index ba147f1224..6079466af6 100644 --- a/src/platform/linux/mod.rs +++ b/src/platform/linux/mod.rs @@ -94,6 +94,11 @@ impl MonitorId { &MonitorId::Wayland(ref m) => m.get_position(), } } + + #[inline] + pub fn get_hidpi_factor(&self) -> f32 { + 1.0 + } } impl Window { diff --git a/src/platform/linux/wayland/context.rs b/src/platform/linux/wayland/context.rs index ca399fceec..8c592de891 100644 --- a/src/platform/linux/wayland/context.rs +++ b/src/platform/linux/wayland/context.rs @@ -407,6 +407,11 @@ impl MonitorId { // if we reach here, this monitor does not exist any more (0,0) } + + #[inline] + pub fn get_hidpi_factor(&self) -> f32 { + 1.0 + } } // a handler to release the ressources acquired to draw the initial white screen as soon as diff --git a/src/platform/linux/x11/monitor.rs b/src/platform/linux/x11/monitor.rs index 463dde6cce..cd05b15379 100644 --- a/src/platform/linux/x11/monitor.rs +++ b/src/platform/linux/x11/monitor.rs @@ -101,4 +101,9 @@ impl MonitorId { pub fn get_position(&self) -> (u32, u32) { self.position } + + #[inline] + pub fn get_hidpi_factor(&self) -> f32 { + 1.0 + } } diff --git a/src/platform/macos/monitor.rs b/src/platform/macos/monitor.rs index 76b5dfe8c4..85bca223ec 100644 --- a/src/platform/macos/monitor.rs +++ b/src/platform/macos/monitor.rs @@ -53,4 +53,9 @@ impl MonitorId { pub fn get_position(&self) -> (u32, u32) { unimplemented!() } + + #[inline] + pub fn get_hidpi_factor(&self) -> f32 { + 1.0 + } } diff --git a/src/platform/windows/monitor.rs b/src/platform/windows/monitor.rs index 14eea3eeb8..7653fd7899 100644 --- a/src/platform/windows/monitor.rs +++ b/src/platform/windows/monitor.rs @@ -181,4 +181,9 @@ impl MonitorId { pub fn get_position(&self) -> (u32, u32) { self.position } + + #[inline] + pub fn get_hidpi_factor(&self) -> f32 { + 1.0 + } } diff --git a/src/window.rs b/src/window.rs index cdc07172c6..c2bdc65d1b 100644 --- a/src/window.rs +++ b/src/window.rs @@ -91,7 +91,7 @@ impl WindowBuilder { self } - /// Enables multitouch + /// Enables multitouch. #[inline] pub fn with_multitouch(mut self) -> WindowBuilder { self.window.multitouch = true; @@ -183,7 +183,7 @@ impl Window { /// Modifies the position of the window. /// - /// See `get_position` for more informations about the coordinates. + /// See `get_position` for more information about the coordinates. /// /// This is a no-op if the window has already been closed. #[inline] @@ -191,46 +191,17 @@ impl Window { self.window.set_position(x, y) } - /// Returns the size in points of the client area of the window. + /// Returns the size in pixels of the client area of the window. /// /// The client area is the content of the window, excluding the title bar and borders. - /// To get the dimensions of the frame buffer when calling `glViewport`, multiply with hidpi factor. + /// These are the dimensions that need to be supplied to `glViewport`. /// /// Returns `None` if the window no longer exists. - /// - /// DEPRECATED #[inline] pub fn get_inner_size(&self) -> Option<(u32, u32)> { self.window.get_inner_size() } - /// Returns the size in points of the client area of the window. - /// - /// The client area is the content of the window, excluding the title bar and borders. - /// To get the dimensions of the frame buffer when calling `glViewport`, multiply with hidpi factor. - /// - /// Returns `None` if the window no longer exists. - #[inline] - pub fn get_inner_size_points(&self) -> Option<(u32, u32)> { - self.window.get_inner_size() - } - - - /// Returns the size in pixels of the client area of the window. - /// - /// The client area is the content of the window, excluding the title bar and borders. - /// These are the dimensions of the frame buffer, and the dimensions that you should use - /// when you call `glViewport`. - /// - /// Returns `None` if the window no longer exists. - #[inline] - pub fn get_inner_size_pixels(&self) -> Option<(u32, u32)> { - self.window.get_inner_size().map(|(x, y)| { - let hidpi = self.hidpi_factor(); - ((x as f32 * hidpi) as u32, (y as f32 * hidpi) as u32) - }) - } - /// Returns the size in pixels of the window. /// /// These dimensions include title bar and borders. If you don't want these, you should use @@ -244,7 +215,7 @@ impl Window { /// Modifies the inner size of the window. /// - /// See `get_inner_size` for more informations about the values. + /// See `get_inner_size` for more information about the values. /// /// This is a no-op if the window has already been closed. #[inline] @@ -323,7 +294,7 @@ impl Window { } /// An iterator for the list of available monitors. -// Implementation note: we retreive the list once, then serve each element by one by one. +// Implementation note: we retrieve the list once, then serve each element by one by one. // This may change in the future. pub struct AvailableMonitorsIter { pub(crate) data: VecDequeIter, @@ -370,4 +341,10 @@ impl MonitorId { pub fn get_position(&self) -> (u32, u32) { self.inner.get_position() } + + /// Returns the ratio between the monitor's physical pixels and logical pixels. + #[inline] + pub fn get_hidpi_factor(&self) -> f32 { + self.inner.get_hidpi_factor() + } } From 785707826b15a5558948007f0bdfeecb0e7c96e5 Mon Sep 17 00:00:00 2001 From: kryptan Date: Fri, 13 Oct 2017 14:43:29 +0300 Subject: [PATCH 2/3] Recover get_inner_size_points and get_inner_size_pixels and change their implementation assuming get_inner_size() returns size in pixels --- src/platform/linux/x11/window.rs | 2 +- src/window.rs | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/platform/linux/x11/window.rs b/src/platform/linux/x11/window.rs index e0e75b6b0f..be8bcdd845 100644 --- a/src/platform/linux/x11/window.rs +++ b/src/platform/linux/x11/window.rs @@ -473,7 +473,7 @@ impl Window2 { #[inline] pub fn get_inner_size(&self) -> Option<(u32, u32)> { - self.get_geometry().map(|(_, _, w, h, _)| ((w as f32 / self.hidpi_factor()) as u32, (h as f32 / self.hidpi_factor()) as u32)) + self.get_geometry().map(|(_, _, w, h, _)| (w, h)) } #[inline] diff --git a/src/window.rs b/src/window.rs index c2bdc65d1b..55ed9e15eb 100644 --- a/src/window.rs +++ b/src/window.rs @@ -202,6 +202,38 @@ impl Window { self.window.get_inner_size() } + /// Returns the size in points of the client area of the window. + /// + /// The client area is the content of the window, excluding the title bar and borders. + /// To get the dimensions of the frame buffer when calling `glViewport`, multiply with hidpi factor. + /// + /// Returns `None` if the window no longer exists. + /// + /// DEPRECATED + #[inline] + #[deprecated] + pub fn get_inner_size_points(&self) -> Option<(u32, u32)> { + self.window.get_inner_size().map(|(x, y)| { + let hidpi = self.hidpi_factor(); + ((x as f32 / hidpi) as u32, (y as f32 / hidpi) as u32) + }) + } + + /// Returns the size in pixels of the client area of the window. + /// + /// The client area is the content of the window, excluding the title bar and borders. + /// These are the dimensions of the frame buffer, and the dimensions that you should use + /// when you call `glViewport`. + /// + /// Returns `None` if the window no longer exists. + /// + /// DEPRECATED + #[inline] + #[deprecated] + pub fn get_inner_size_pixels(&self) -> Option<(u32, u32)> { + self.window.get_inner_size() + } + /// Returns the size in pixels of the window. /// /// These dimensions include title bar and borders. If you don't want these, you should use From b0ee43956b7b60b5dca9a80250f047957778dd26 Mon Sep 17 00:00:00 2001 From: kryptan Date: Mon, 16 Oct 2017 01:48:30 +0300 Subject: [PATCH 3/3] Update changelog for high-DPI changes --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d972827548..1cfa5bdcb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Unreleased +- Added event `WindowEvent::HiDPIFactorChanged`. +- Added method `MonitorId::get_hidpi_factor`. +- Deprecated `get_inner_size_pixels` and `get_inner_size_points` methods of `Window` in favor of +`get_inner_size`. + # Version 0.8.3 (2017-10-11) - Fixed issue of calls to `set_inner_size` blocking on Windows.