1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
//! Global **user-experience scale** factor.
//!
//! Distinct from [`crate::device_scale`], which tracks the physical
//! device-pixel ratio so glyphs stay crisp on HiDPI displays. The UX
//! scale exists because the same logical pixel feels very different
//! to a user on a desktop monitor at desk distance vs. a phone held
//! at arm's length.
//!
//! The cleanest mental model:
//!
//! - **`device_scale`**: pixels per logical unit on the physical
//! display surface. Always set by the platform shell to whatever
//! `window.devicePixelRatio` / `winit::Window::scale_factor`
//! reports. Driven by the hardware.
//! - **`ux_scale`**: how much bigger the *user* wants every logical
//! unit to be on top of that. Driven by ergonomic / accessibility
//! needs — small on a 27" monitor read at arm's length, bigger on
//! a 6" phone read at arm's length, bigger still for users with
//! reduced vision.
//!
//! The framework multiplies the two when it computes the effective
//! viewport / paint transform inside [`crate::App`]. Widgets always
//! see "logical" units (already divided by the effective scale), so
//! no per-widget changes are needed — only platform shells need to
//! call [`set_ux_scale`].
//!
//! ## Suggested values
//!
//! - `1.0` — desktop / laptop / cursor-driven UI. The default.
//! - `1.6` – `1.8` — mobile touch (phone / tablet) where the user
//! reads at arm's length and needs ~44 px touch targets. Auto-set
//! when [`crate::input_profile::set_input_profile`] is called with
//! any mobile variant.
//! - User-controlled accessibility setting on top of that — `1.0` to
//! `2.0+` for users who explicitly want bigger UI.
use Cell;
thread_local!
/// Current UX scale factor. Multiplied with [`crate::device_scale`] in
/// [`crate::App::layout`] / [`crate::App::paint`] to give the effective
/// "physical pixels per logical unit" the framework actually uses.
/// Set the UX scale factor. Panics on non-positive values in debug.
///
/// Platform shells typically call this once at startup after they've
/// figured out the device profile, and again from a settings UI that
/// lets the user tune readability.
/// Combined "physical pixels per logical unit" the framework uses
/// for layout / paint scaling. `device_scale * ux_scale`.