react-x11 2.52.0 → 2.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -10
- package/docs/README.md +160 -314
- package/docs/accessibility.md +176 -229
- package/docs/appearance.md +77 -176
- package/docs/click-to-component.md +18 -51
- package/docs/clipboard.md +40 -59
- package/docs/components.md +518 -1036
- package/docs/dbus.md +61 -133
- package/docs/debugging.md +152 -245
- package/docs/desktop-calendar.md +51 -88
- package/docs/desktop.md +222 -347
- package/docs/devtools.md +50 -167
- package/docs/drag-and-drop.md +126 -204
- package/docs/ecosystem/animation.md +91 -125
- package/docs/ecosystem/data-fetching.md +38 -53
- package/docs/ecosystem/dev-tooling.md +159 -202
- package/docs/ecosystem/forms.md +61 -97
- package/docs/ecosystem/headless.md +64 -89
- package/docs/ecosystem/i18n.md +18 -21
- package/docs/ecosystem/icons.md +93 -126
- package/docs/ecosystem/layout.md +42 -52
- package/docs/ecosystem/routing.md +18 -29
- package/docs/ecosystem/state.md +71 -88
- package/docs/ecosystem/testing.md +131 -157
- package/docs/ecosystem/theming.md +119 -165
- package/docs/ecosystem.md +145 -179
- package/docs/elements.md +1091 -1774
- package/docs/embedding.md +83 -132
- package/docs/events.md +412 -695
- package/docs/extending.md +784 -1326
- package/docs/eyedropper.md +63 -122
- package/docs/filedialog.md +71 -107
- package/docs/frame.md +195 -339
- package/docs/gl.md +65 -62
- package/docs/globalmenu.md +63 -146
- package/docs/macos.md +531 -3234
- package/docs/notifications.md +33 -47
- package/docs/packaging.md +166 -309
- package/docs/permissions.md +9 -14
- package/docs/react-features.md +81 -106
- package/docs/remote.md +32 -76
- package/docs/scale.md +72 -186
- package/docs/styling.md +329 -547
- package/docs/system.md +200 -280
- package/docs/testing.md +63 -83
- package/docs/typescript.md +6 -48
- package/docs/uri-schemes.md +67 -107
- package/docs/wayland-backend.md +200 -459
- package/docs/windows-integrations.md +75 -131
- package/docs/windows.md +343 -1367
- package/package.json +3 -2
- package/src/Reconciler.js +2 -2
- package/src/a11y.js +1 -1
- package/src/backend/context2d.js +3 -3
- package/src/bootstrap.js +1 -1
- package/src/cocoa/app.js +6 -6
- package/src/cocoa/bezels.js +1 -1
- package/src/cocoa/fonts.js +1 -1
- package/src/cocoa/globalmenu.js +1 -1
- package/src/cocoa/keymap.js +1 -1
- package/src/cocoa/panewindow.js +1 -1
- package/src/cocoa/player.js +1 -1
- package/src/cocoa/presenter.js +2 -2
- package/src/cocoa/promotion.js +1 -1
- package/src/cocoa/relaunch.js +1 -1
- package/src/cocoa/threaded.js +1 -1
- package/src/cocoa/video.js +1 -1
- package/src/cocoa/window.js +4 -4
- package/src/components/Menu.js +7 -2
- package/src/components/Switch.js +1 -1
- package/src/components/native.js +1 -1
- package/src/dnd.js +2 -2
- package/src/glnodes.js +1 -1
- package/src/grid.js +1 -1
- package/src/layouts.js +1 -1
- package/src/nodes/animation.js +1 -1
- package/src/nodes/invalidate.js +1 -1
- package/src/nodes/layouthost.js +1 -1
- package/src/nodes/video.js +19 -8
- package/src/nodes/window/droptarget.js +1 -1
- package/src/pacing.js +1 -1
- package/src/refresh/index.js +2 -1
- package/src/types/video.d.ts +5 -2
- package/src/videobackend.js +28 -0
- package/src/videoframes.js +29 -16
- package/src/wayland/app.js +27 -0
- package/src/wayland/video.js +376 -0
- package/src/win32/a11y.js +1 -1
- package/src/win32/app.js +2 -2
- package/src/win32/fonts.js +1 -1
- package/src/win32/glarea.js +4 -4
- package/src/win32/overlay.js +1 -1
- package/src/win32/panewindow.js +3 -3
- package/src/win32/shell.js +1 -1
- package/src/win32/window.js +2 -2
- package/src/windowid.js +1 -1
- package/src/xvideo.js +189 -0
- package/docs/architecture/accessibility.md +0 -470
- package/docs/architecture/animation.md +0 -707
- package/docs/architecture/container-queries.md +0 -525
- package/docs/architecture/custom-layout.md +0 -334
- package/docs/architecture/drag-and-drop.md +0 -941
- package/docs/architecture/element-layer-contents.md +0 -622
- package/docs/architecture/frame-pacing.md +0 -255
- package/docs/architecture/grid-layout.md +0 -358
- package/docs/architecture/protocol-efficiency.md +0 -357
- package/docs/architecture/video.md +0 -1149
- package/docs/architecture/windowed-regions.md +0 -854
- package/docs/glx.md +0 -137
- package/docs/wayland.md +0 -545
- package/docs/windows-embedding.md +0 -271
- package/docs/windows-gl.md +0 -221
package/docs/scale.md
CHANGED
|
@@ -42,10 +42,8 @@ const scale = useScale(); // 1, 2, 1.5... static for the life of the root
|
|
|
42
42
|
logical math)
|
|
43
43
|
- `<canvas onDraw>`: the browser's own canvas contract — the box arrives in
|
|
44
44
|
device pixels and the payload carries `scale`, so detail is drawn on the
|
|
45
|
-
real grid.
|
|
46
|
-
through
|
|
47
|
-
would move an app's `fillText` without growing it — and it would knock
|
|
48
|
-
every fill off ntk's server-side fast paths besides.
|
|
45
|
+
real grid. It is deliberately not pre-scaled with `ctx.scale()`: text
|
|
46
|
+
drawn through a scaled transform moves without growing.
|
|
49
47
|
- a registered element's `paint()` and `hitTest()` (see
|
|
50
48
|
[extending.md](extending.md)): `this.style` and `this.abs` arrive already
|
|
51
49
|
device, and so are `paintDamage()`, the rects handed to `invalidate` and
|
|
@@ -55,108 +53,62 @@ const scale = useScale(); // 1, 2, 1.5... static for the life of the root
|
|
|
55
53
|
|
|
56
54
|
Fonts are the point of the whole exercise: a `fontSize: 14` at scale 2 is
|
|
57
55
|
shaped, measured and rasterized at 28px. Text on a retina panel is _sharper_,
|
|
58
|
-
not bigger-blurrier
|
|
59
|
-
|
|
56
|
+
not bigger-blurrier.
|
|
57
|
+
|
|
58
|
+
Fractional scales (`1.25`, `1.5`) work end to end, with the usual X11
|
|
59
|
+
caveat: a 1-logical-px hairline at 1.25x is 1 or 2 device pixels depending
|
|
60
|
+
on where it lands. Integer scales have no such seams.
|
|
60
61
|
|
|
61
62
|
"Logical" is per node rather than per window as soon as a `scale` prop is in
|
|
62
63
|
the tree: everything in the first list is divided by the scale of the node
|
|
63
64
|
it is about, which is the display's until an enclosing `scale` says
|
|
64
|
-
otherwise. See
|
|
65
|
+
otherwise. See [A subtree of its own](#a-subtree-of-its-own) below.
|
|
65
66
|
|
|
66
67
|
## How `'auto'` decides
|
|
67
68
|
|
|
68
|
-
X11
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
(in 1024ths of a dpi on the wire; a daemon writing plain dpi is read
|
|
78
|
-
right too). This is what the desktop's own settings dialog writes and
|
|
79
|
-
what every GTK app on the screen is already obeying.
|
|
80
|
-
3. **`RESOURCE_MANAGER`** — `Xft.dpi`, the `xrdb` convention winit,
|
|
81
|
-
Chromium and every terminal emulator read.
|
|
69
|
+
X11 has no scale protocol, so `'auto'` consults these in order and takes the
|
|
70
|
+
first that answers:
|
|
71
|
+
|
|
72
|
+
1. **Environment** — `REACT_X11_SCALE` (wins over everything, an explicit
|
|
73
|
+
`scale:` number included: it is the accessibility escape hatch), then
|
|
74
|
+
`GDK_SCALE`, then `QT_SCALE_FACTOR`.
|
|
75
|
+
2. **XSETTINGS** — `Gdk/WindowScalingFactor` when it is 2+, then `Xft/DPI`:
|
|
76
|
+
what the desktop's own settings dialog writes.
|
|
77
|
+
3. **`RESOURCE_MANAGER`** — `Xft.dpi`, the `xrdb` convention.
|
|
82
78
|
4. **RandR millimetres** — the panel's physical size against its pixel
|
|
83
|
-
size,
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
lying, the pixel grid itself is the last signal: nothing ships as a 1x
|
|
91
|
-
panel with a grid ≥3000 wide or taller than 1600 on its short side, so
|
|
92
|
-
those are called 2x and everything else 1x. That takes in the 2560×1664
|
|
93
|
-
and 2880×1800 lids, and a VM window over any retina panel (a UTM window
|
|
94
|
-
on a 14″ MacBook is 2488×1668). Only the confident call is made without
|
|
95
|
-
physical data — 2560×1440 and 2560×1600 stay 1x on purpose, because
|
|
96
|
-
they are the commonest 1x desk monitors there are and only millimetres
|
|
97
|
-
could tell them from a 13″ retina lid.
|
|
79
|
+
size, per output, under mutter's viewing-distance model: the DPI that
|
|
80
|
+
counts as 1x is 135 under a 20″ diagonal and 110 over it, snapped to
|
|
81
|
+
quarter steps in [1, 3]. A 27″ 2560×1440 monitor is 1x, a 27″ 4K 1.5x, a
|
|
82
|
+
16″ MacBook panel 2x.
|
|
83
|
+
5. **The resolution class** — when the millimetres are absent or not
|
|
84
|
+
credible: a grid ≥3000 wide, or taller than 1600 on its short side, is
|
|
85
|
+
2x, and everything else 1x. 2560×1440 and 2560×1600 stay 1x.
|
|
98
86
|
6. **1.**
|
|
99
87
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
(
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
(`Virtual-*`, `qxl`, …). `XWAYLAND*` outputs skip the hardware rung too:
|
|
110
|
-
the compositor owns scaling there and publishes its decision through rung
|
|
111
|
-
2, in both of its Xwayland modes.
|
|
88
|
+
**96 is not an answer**: `Xft.dpi: 96` and `Gdk/WindowScalingFactor: 1` are
|
|
89
|
+
what daemons publish when nobody opened the dialog, so they fall through to
|
|
90
|
+
the hardware rather than pinning an unconfigured 4K laptop to 1x. And
|
|
91
|
+
**millimetres are believed only when credible**: zeroes, aspect ratios
|
|
92
|
+
posing as sizes, a physical/pixel aspect mismatch and virtual machines'
|
|
93
|
+
monitors (by EDID — QEMU, VMware, VirtualBox, Parallels, Hyper-V — and by
|
|
94
|
+
connector name, `Virtual-*`, `qxl`, …) fall through to rung 5. So do
|
|
95
|
+
`XWAYLAND*` outputs' millimetres: the compositor owns scaling there and
|
|
96
|
+
publishes its decision through rung 2.
|
|
112
97
|
|
|
113
98
|
### Servers that are not describing hardware
|
|
114
99
|
|
|
115
|
-
Rungs 4–5 read a panel, so they are skipped where the connection has
|
|
116
|
-
panel to describe. Two cases, both of them servers people really run:
|
|
117
|
-
|
|
118
|
-
- **XQuartz**, detected by the `Apple-WM` extension. macOS composes the
|
|
119
|
-
desktop in _points_ and hands X the point space, already normalised for
|
|
120
|
-
density: a 16″ retina lid arrives as 1728×1080, a 1x monitor beside it as
|
|
121
|
-
2560×1403, and the window server scales what it is given onto whichever
|
|
122
|
-
panel the window lands on. Inferring a factor here doubles a size macOS
|
|
123
|
-
is about to double again, so the ladder answers 1x with the source
|
|
124
|
-
`xquartz` — the same exemption `XWAYLAND` gets, for the same reason.
|
|
125
|
-
- **A single synthetic output covering every monitor.** XQuartz, Xvfb,
|
|
126
|
-
x11vnc and TigerVNC, Xephyr and pre-RandR drivers answer the output walk
|
|
127
|
-
with one output — usually named `default`, always without millimetres —
|
|
128
|
-
whose CRTC is the _union_ of the desktop. Two 2560×1440 monitors union to
|
|
129
|
-
5120×1440, which rung 5 reads as a retina panel; the machine this was
|
|
130
|
-
found on unioned a retina lid and two 1x monitors into 5120×2520 and drew
|
|
131
|
-
every widget at double size. Xinerama reports those heads separately, so
|
|
132
|
-
more heads than outputs retires rung 5 (`isUnionOutput`). Rung 4 survives
|
|
133
|
-
it — credible millimetres describe real glass however the pixels were
|
|
134
|
-
divided up, which is what an `xrandr --setmonitor` split of one ultrawide
|
|
135
|
-
is.
|
|
136
|
-
|
|
137
|
-
Both guards sit _below_ the configured rungs: `REACT_X11_SCALE`,
|
|
138
|
-
`GDK_SCALE` and a desktop's own XSETTINGS still win, because a person who
|
|
139
|
-
typed a factor outranks the platform.
|
|
140
|
-
|
|
141
|
-
### The machine this was built against
|
|
142
|
-
|
|
143
|
-
A 16″ MacBook panel handed 1:1 to a UTM Linux guest (XFCE, X11) defeats
|
|
144
|
-
rungs 1–4 simultaneously, which is why the ladder has five:
|
|
100
|
+
Rungs 4–5 read a panel, so they are skipped where the connection has none:
|
|
145
101
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
RandR
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
```
|
|
102
|
+
- **XQuartz** (the `Apple-WM` extension) hands X macOS's point space,
|
|
103
|
+
already normalised for density, and macOS scales the window onto whichever
|
|
104
|
+
panel it lands on. The answer is 1x, with the source `xquartz`.
|
|
105
|
+
- **A single synthetic output covering every monitor** — Xvfb, x11vnc,
|
|
106
|
+
TigerVNC, Xephyr and pre-RandR drivers — would read the union of two 1x
|
|
107
|
+
monitors as a retina panel, so rung 5 is skipped when Xinerama reports
|
|
108
|
+
more heads than outputs. Credible millimetres (rung 4) still count.
|
|
154
109
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
untouched default. Run `node scripts/scale-probe.mjs` against any display
|
|
158
|
-
to see the same table for it, or `REACT_X11_DEBUG_SCALE=1` in an app to
|
|
159
|
-
watch the ladder resolve.
|
|
110
|
+
`REACT_X11_SCALE`, `GDK_SCALE` and a desktop's own XSETTINGS still win over
|
|
111
|
+
both. `REACT_X11_DEBUG_SCALE=1` in an app prints how the ladder resolved.
|
|
160
112
|
|
|
161
113
|
## On Wayland
|
|
162
114
|
|
|
@@ -170,16 +122,11 @@ as sharp at 1.5 as at 2. Two things still outrank it, as on X11:
|
|
|
170
122
|
absolutely: device (buffer) pixels per logical pixel. On a compositor at
|
|
171
123
|
1x, `REACT_X11_SCALE=2` is a window twice the size drawn at full
|
|
172
124
|
resolution, not a small one stretched.
|
|
173
|
-
- **The resolution class, when the compositor says 1.**
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
out at the compositor's word comes up half the size it is on the host.
|
|
177
|
-
When every output is at 1x and the largest has no credible millimetres
|
|
178
|
-
(`classifyMm`) but a retina-class grid, the layout is 2x — what the X11
|
|
125
|
+
- **The resolution class, when the compositor says 1.** When every output
|
|
126
|
+
is at 1x and the largest has no credible millimetres but a retina-class
|
|
127
|
+
grid — a VM window over a retina panel — the layout is 2x, as the X11
|
|
179
128
|
ladder answers for the same screen through Xwayland. A compositor that
|
|
180
|
-
scales any output
|
|
181
|
-
someone's choice), and credible millimetres were the compositor's own
|
|
182
|
-
evidence, so both keep their answer.
|
|
129
|
+
scales any output, or credible millimetres, keep the compositor's answer.
|
|
183
130
|
|
|
184
131
|
The frame a window draws for itself follows the compositor, not the
|
|
185
132
|
layout: it is drawn at the desktop's scale, beside every other window's.
|
|
@@ -187,24 +134,20 @@ layout: it is drawn at the desktop's scale, beside every other window's.
|
|
|
187
134
|
|
|
188
135
|
## Several monitors
|
|
189
136
|
|
|
190
|
-
Rungs 4–5 are computed for every connected output
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
scale for the session, chosen for the display you called primary.
|
|
137
|
+
Rungs 4–5 are computed for every connected output. The **root's** scale —
|
|
138
|
+
the one layout and paint use — is the primary output's (the largest, where
|
|
139
|
+
nothing is flagged primary), as GNOME does on X11: one scale for the
|
|
140
|
+
session.
|
|
195
141
|
|
|
196
142
|
The per-output answers ride on `useScreens()` — every entry carries its own
|
|
197
143
|
`scale` — so an app that places windows can do better, and a window can be
|
|
198
|
-
pinned with `createRoot({ scale })` per root.
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
tries it, and "chosen at creation, static after" is the behaviour of
|
|
203
|
-
everything else on this window system.
|
|
144
|
+
pinned with `createRoot({ scale })` per root. A window is **not** re-scaled
|
|
145
|
+
as it is dragged between mismatched monitors: X11 has one coordinate space
|
|
146
|
+
and no per-window scale protocol, so the scale is chosen at creation and
|
|
147
|
+
static after.
|
|
204
148
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
that GTK3 apps mostly share it; restart the app.
|
|
149
|
+
It is static for the session too: a mid-session change of `Xft.dpi` or a
|
|
150
|
+
monitor swap does not re-scale running windows. Restart the app.
|
|
208
151
|
|
|
209
152
|
## A subtree of its own
|
|
210
153
|
|
|
@@ -221,10 +164,9 @@ The semantics are CSS's `zoom`, not a transform:
|
|
|
221
164
|
|
|
222
165
|
- A node's **effective scale** is its parent's times its own `scale` prop,
|
|
223
166
|
so nested props multiply and the display scale is the floor they multiply.
|
|
224
|
-
`node.scale` is that number, and
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
`paint()` — follows with no second mechanism.
|
|
167
|
+
`node.scale` is that number, and everything the display scale reaches —
|
|
168
|
+
styles, the caret and scrollbars, shadows and gradients, a registered
|
|
169
|
+
element's own `paint()` — follows it.
|
|
228
170
|
- **The node's own style scales too.** `scale={2}` on a box with
|
|
229
171
|
`padding: 8` gets 16 device pixels of padding, not 8 with bigger children
|
|
230
172
|
inside it. That is what makes the caller's job the one-liner above: divide
|
|
@@ -239,11 +181,8 @@ The semantics are CSS's `zoom`, not a transform:
|
|
|
239
181
|
|
|
240
182
|
What it is for: an element that owns a viewport — a graph pane, a canvas, a
|
|
241
183
|
map — and mounts application content inside it. The pane draws its own
|
|
242
|
-
world, and the React subtree beside it
|
|
243
|
-
|
|
244
|
-
transforming the context" below) and a layer transform on the Cocoa
|
|
245
|
-
presenter would draw a zoomed body whose hit testing still lived at the
|
|
246
|
-
unzoomed rects.
|
|
184
|
+
world, and the React subtree beside it follows the same zoom, laid out,
|
|
185
|
+
drawn and hit at the zoomed size.
|
|
247
186
|
|
|
248
187
|
### What a boundary costs
|
|
249
188
|
|
|
@@ -274,66 +213,13 @@ font size to shape and cache, so a wheel handler feeding the raw accumulator
|
|
|
274
213
|
into `scale` makes a new set of glyphs per frame. Round to a step — 5%, or
|
|
275
214
|
a ladder of preset zooms — and the cache does its job.
|
|
276
215
|
|
|
277
|
-
##
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
The composition is the contribution: desktop configuration first (rungs
|
|
289
|
-
1–3, which is where Chromium/SDL stop — correct on configured desktops,
|
|
290
|
-
tiny on unconfigured HiDPI ones), mutter's perceptual model where the
|
|
291
|
-
hardware is honest (which is where winit's mm math stops — right until an
|
|
292
|
-
EDID lies), and the resolution class where it is not (which nobody else
|
|
293
|
-
has, and which is the only rung that survives a VM).
|
|
294
|
-
|
|
295
|
-
## Design notes
|
|
296
|
-
|
|
297
|
-
**Why multiply values instead of transforming the context.** Two hard
|
|
298
|
-
reasons, both ntk's. Its 2d context batches solid fills into server-side
|
|
299
|
-
`Render.FillRectangles` and takes similar fast paths for strokes, rounded
|
|
300
|
-
rects and glyph runs — all gated on an identity transform, so a frame-wide
|
|
301
|
-
`ctx.scale(2,2)` would rasterize every box in the UI as polygons. And its
|
|
302
|
-
text model sizes glyphs from the font while only _positioning_ them through
|
|
303
|
-
the transform, so scaled-transform text comes out moved but not grown.
|
|
304
|
-
Multiplying at the style funnel instead means paint code, damage rects, the
|
|
305
|
-
scroll blit and the paint cache all keep working in integer device pixels
|
|
306
|
-
with the transforms they always had. (`paintcache.js` even guards against
|
|
307
|
-
the other choice: a non-identity CTM disables it entirely.)
|
|
308
|
-
|
|
309
|
-
**Where the multiply lives.** One place for styles —
|
|
310
|
-
`scaleResolvedStyle()`, at the end of the style funnel in `_syncStyle`, so
|
|
311
|
-
state blocks, size queries and the flex shorthand all still think in the
|
|
312
|
-
logical pixels the app wrote. One place for the theme's font size — the
|
|
313
|
-
root branch of `inheritedTextStyle`, because descendants inherit an
|
|
314
|
-
already-resolved size and any second multiply would compound. One place for
|
|
315
|
-
window geometry (`scaleWindowGeometry`), one per string-parsed decoration
|
|
316
|
-
(`shadowSpecs`/`gradientSpec`, whose parses are memoized on the raw string
|
|
317
|
-
so the scale rides into the memo key), and division at each app-facing
|
|
318
|
-
egress (`SyntheticEvent`, `getClientRects`, `onScroll`, `useScreens`…).
|
|
319
|
-
`yoga` needs no `pointScaleFactor` games: layout runs directly in device
|
|
320
|
-
pixels and its ordinary whole-pixel rounding is what keeps a 1-logical-px
|
|
321
|
-
border crisp at 1.5x.
|
|
322
|
-
|
|
323
|
-
**Fractional scales** work end to end (`1.25`, `1.5`, quarter steps from
|
|
324
|
-
the ladder), with the usual X11 caveat: a 1-logical-px hairline at 1.25x is
|
|
325
|
-
1 or 2 device pixels depending on where it lands. Integer scales have no
|
|
326
|
-
such seams.
|
|
327
|
-
|
|
328
|
-
**What tests see.** The headless harnesses resolve to exactly 1 — a mock
|
|
329
|
-
app has no display to ask — so every geometry assertion in the suite means
|
|
330
|
-
its numbers literally. `createRoot({ app, scale: 2 })` opts a test in, and
|
|
331
|
-
so does `renderX11(element, { scale: 2 })` from `react-x11/test`;
|
|
332
|
-
`test/scale-render.test.js` is the boundary contract pinned as tests.
|
|
333
|
-
`setScaleForTests()` (from `src/scale.js`) pins a factor without a
|
|
334
|
-
connection.
|
|
335
|
-
|
|
336
|
-
**Known costs.** The paint cache's per-item budget is device pixels, so at
|
|
337
|
-
2x a widget occupies 4× the budget it did — icons and checkboxes still fit
|
|
338
|
-
comfortably. Damage rects, protocol traffic and backing stores scale the
|
|
339
|
-
same way any HiDPI surface does.
|
|
216
|
+
## In tests
|
|
217
|
+
|
|
218
|
+
The headless harnesses resolve to exactly 1 — a mock app has no display to
|
|
219
|
+
ask — so a geometry assertion means its numbers literally.
|
|
220
|
+
`createRoot({ app, scale: 2 })` opts a test in, and so does
|
|
221
|
+
`renderX11(element, { scale: 2 })` from `react-x11/test`.
|
|
222
|
+
|
|
223
|
+
Design notes — the ladder's rationale, prior art, and why lengths are
|
|
224
|
+
multiplied rather than the context transformed:
|
|
225
|
+
[design/scale.md](../design/scale.md).
|