Split dpi module out into a separate crate (#3518)

Co-authored-by: John Nunley <dev@notgull.net>
This commit is contained in:
Mads Marquart 2024-02-26 14:52:00 +01:00 committed by GitHub
parent 7e28d7615e
commit e41f0eabb1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 255 additions and 208 deletions

1004
src/dpi.rs

File diff suppressed because it is too large Load diff

View file

@ -539,7 +539,7 @@ pub enum WindowEvent {
/// To update the window size, use the provided [`InnerSizeWriter`] handle. By default, the window is
/// resized to the value suggested by the OS, but it can be changed to any value.
///
/// For more information about DPI in general, see the [`dpi`](crate::dpi) module.
/// For more information about DPI in general, see the [`dpi`] crate.
ScaleFactorChanged {
scale_factor: f64,
/// Handle to update inner size during scale changes.

View file

@ -126,6 +126,25 @@
//! [`visible` set to `false`](crate::window::WindowAttributes::with_visible) and explicitly make the
//! window visible only once you're ready to render into it.
//!
//! # UI scaling
//!
//! UI scaling is important, go read the docs for the [`dpi`] crate for an
//! introduction.
//!
//! All of Winit's functions return physical types, but can take either logical or physical
//! coordinates as input, allowing you to use the most convenient coordinate system for your
//! particular application.
//!
//! Winit will dispatch a [`ScaleFactorChanged`] event whenever a window's scale factor has changed.
//! This can happen if the user drags their window from a standard-resolution monitor to a high-DPI
//! monitor or if the user changes their DPI settings. This allows you to rescale your application's
//! UI elements and adjust how the platform changes the window's size to reflect the new scale
//! factor. If a window hasn't received a [`ScaleFactorChanged`] event, its scale factor
//! can be found by calling [`window.scale_factor()`].
//!
//! [`ScaleFactorChanged`]: event::WindowEvent::ScaleFactorChanged
//! [`window.scale_factor()`]: window::Window::scale_factor
//!
//! # Cargo Features
//!
//! Winit provides the following Cargo features:
@ -177,7 +196,10 @@
#[cfg(feature = "rwh_06")]
pub use rwh_06 as raw_window_handle;
pub mod dpi;
// Re-export DPI types so that users don't have to put it in Cargo.toml.
#[doc(inline)]
pub use dpi;
#[macro_use]
pub mod error;
mod cursor;

View file

@ -145,7 +145,7 @@ impl MonitorHandle {
/// Returns the scale factor of the underlying monitor. To map logical pixels to physical
/// pixels and vice versa, use [`Window::scale_factor`].
///
/// See the [`dpi`](crate::dpi) module for more information.
/// See the [`dpi`] module for more information.
///
/// ## Platform-specific
///

View file

@ -16,7 +16,7 @@ use super::view::WinitView;
use super::view_controller::WinitViewController;
use crate::{
cursor::Cursor,
dpi::{self, LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Position, Size},
dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Position, Size},
error::{ExternalError, NotSupportedError, OsError as RootOsError},
event::{Event, WindowEvent},
icon::Icon,
@ -537,7 +537,7 @@ impl Window {
let screen = window.screen();
let screen_space = screen.coordinateSpace();
let screen_frame = view.convertRect_toCoordinateSpace(bounds, &screen_space);
let size = crate::dpi::LogicalSize {
let size = LogicalSize {
width: screen_frame.size.width as f64,
height: screen_frame.size.height as f64,
};

View file

@ -540,17 +540,54 @@ impl Window {
///
/// This value may differ from [`MonitorHandle::scale_factor`].
///
/// See the [`dpi`](crate::dpi) module for more information.
/// See the [`dpi`] crate for more information.
///
/// ## Platform-specific
///
/// - **X11:** This respects Xft.dpi, and can be overridden using the `WINIT_X11_SCALE_FACTOR` environment variable.
/// - **Wayland:** Uses the wp-fractional-scale protocol if available. Falls back to integer-scale factors otherwise.
/// - **Android:** Always returns 1.0.
/// - **iOS:** Can only be called on the main thread. Returns the underlying `UIView`'s
/// [`contentScaleFactor`].
/// The scale factor is calculated differently on different platforms:
///
/// - **Windows:** On Windows 8 and 10, per-monitor scaling is readily configured by users from the
/// display settings. While users are free to select any option they want, they're only given a
/// selection of "nice" scale factors, i.e. 1.0, 1.25, 1.5... on Windows 7. The scale factor is
/// global and changing it requires logging out. See [this article][windows_1] for technical
/// details.
/// - **macOS:** Recent macOS versions allow the user to change the scaling factor for specific
/// displays. When available, the user may pick a per-monitor scaling factor from a set of
/// pre-defined settings. All "retina displays" have a scaling factor above 1.0 by default,
/// but the specific value varies across devices.
/// - **X11:** Many man-hours have been spent trying to figure out how to handle DPI in X11. Winit
/// currently uses a three-pronged approach:
/// + Use the value in the `WINIT_X11_SCALE_FACTOR` environment variable if present.
/// + If not present, use the value set in `Xft.dpi` in Xresources.
/// + Otherwise, calculate the scale factor based on the millimeter monitor dimensions provided by XRandR.
///
/// If `WINIT_X11_SCALE_FACTOR` is set to `randr`, it'll ignore the `Xft.dpi` field and use the
/// XRandR scaling method. Generally speaking, you should try to configure the standard system
/// variables to do what you want before resorting to `WINIT_X11_SCALE_FACTOR`.
/// - **Wayland:** The scale factor is suggested by the compositor for each window individually by
/// using the wp-fractional-scale protocol if available. Falls back to integer-scale factors otherwise.
///
/// The monitor scale factor may differ from the window scale factor.
/// - **iOS:** Scale factors are set by Apple to the value that best suits the device, and range
/// from `1.0` to `3.0`. See [this article][apple_1] and [this article][apple_2] for more
/// information.
///
/// This uses the underlying `UIView`'s [`contentScaleFactor`].
/// - **Android:** Scale factors are set by the manufacturer to the value that best suits the
/// device, and range from `1.0` to `4.0`. See [this article][android_1] for more information.
///
/// This is currently unimplemented, and this function always returns 1.0.
/// - **Web:** The scale factor is the ratio between CSS pixels and the physical device pixels.
/// In other words, it is the value of [`window.devicePixelRatio`][web_1]. It is affected by
/// both the screen scaling and the browser zoom level and can go below `1.0`.
/// - **Orbital:** This is currently unimplemented, and this function always returns 1.0.
///
/// [`WindowEvent::ScaleFactorChanged`]: crate::event::WindowEvent::ScaleFactorChanged
/// [windows_1]: https://docs.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows
/// [apple_1]: https://developer.apple.com/library/archive/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/Displays/Displays.html
/// [apple_2]: https://developer.apple.com/design/human-interface-guidelines/macos/icons-and-images/image-size-and-resolution/
/// [android_1]: https://developer.android.com/training/multiscreen/screendensities
/// [web_1]: https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio
/// [`contentScaleFactor`]: https://developer.apple.com/documentation/uikit/uiview/1622657-contentscalefactor?language=objc
#[inline]
pub fn scale_factor(&self) -> f64 {