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
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
# Desktop integration on Windows: what works, and what does not
|
|
2
2
|
|
|
3
|
-
[
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Everything below was measured on this backend rather than inferred from the
|
|
8
|
-
API's existence. "Works" means a test asserts it or it was driven and seen.
|
|
3
|
+
What an app on the [win32 backend](windows.md) can reach today, what it
|
|
4
|
+
cannot, and which of the gaps have a route. Every row was measured on this
|
|
5
|
+
backend rather than inferred from the API's existence: "works" means a test
|
|
6
|
+
asserts it or it was driven and seen.
|
|
9
7
|
|
|
10
8
|
## Works
|
|
11
9
|
|
|
@@ -21,11 +19,11 @@ API's existence. "Works" means a test asserts it or it was driven and seen.
|
|
|
21
19
|
| pointer | `onMouseDown`, wheel, capture | all five buttons, `SetCapture` for drags leaving the window |
|
|
22
20
|
| focus | `onFocus`/`onBlur` | `WM_ACTIVATE` |
|
|
23
21
|
| window states | `useWindowState`, `<window maximized fullscreen alwaysOnTop>` | `ShowWindow`, `SetWindowPos`, a remembered frame for fullscreen |
|
|
24
|
-
| screens and DPI | `useScreens`, `useScale` | per-monitor v2;
|
|
22
|
+
| screens and DPI | `useScreens`, `useScale` | per-monitor v2; no live per-window re-scale yet ([windows.md](windows.md#scale-and-dpi)) |
|
|
25
23
|
| light/dark and accent | `useSystemAppearance` | `UISettings` and the theme registry; the frame follows through `DWMWA_USE_IMMERSIVE_DARK_MODE` |
|
|
26
|
-
| native control bezels | `<button>`, `<checkbox>`… | the visual styles engine,
|
|
24
|
+
| native control bezels | `<button>`, `<checkbox>`… | the visual styles engine, on a light desktop; dark ones are drawn (Windows' are not public) |
|
|
27
25
|
| file dialogs | `useFileDialog` | the Common Item Dialog, parented, modal on the UI thread |
|
|
28
|
-
| clipboard | `useClipboard` | text and format enumeration
|
|
26
|
+
| clipboard | `useClipboard` | text only, and format enumeration |
|
|
29
27
|
| tray icon and menu | `useTray` | `Shell_NotifyIcon` |
|
|
30
28
|
| taskbar progress | `useProgress` | `ITaskbarList3::SetProgressValue` |
|
|
31
29
|
| a badge on the icon | `useBadge`, `setBadge` | the count drawn into an overlay icon — Windows has no badge API |
|
|
@@ -34,7 +32,7 @@ API's existence. "Works" means a test asserts it or it was driven and seen.
|
|
|
34
32
|
| notifications | `notify`, `useNotifier` | a tray balloon, which the shell shows as a toast |
|
|
35
33
|
| idle time | `useIdle` | `GetLastInputInfo`, polled on the same adaptive wait the X rung uses |
|
|
36
34
|
| keeping the screen awake | `keepAwake`, `useKeepAwake` | `SetThreadExecutionState`, counted |
|
|
37
|
-
| reading a window back | `window.snapshot()` | `PrintWindow` with `PW_CLIENTONLY
|
|
35
|
+
| reading a window back | `window.snapshot()` | `PrintWindow` with `PW_CLIENTONLY` and `PW_RENDERFULLCONTENT` |
|
|
38
36
|
| locale | `systemLocale`, `useLocale` | ICU's own resolution, which reads the OS on Windows — no backend code |
|
|
39
37
|
| drag and drop | `useDropTarget`, `useDragSource` | `IDropTarget` and `DoDragDrop` over OLE, both directions |
|
|
40
38
|
| a thumbnail toolbar | `useThumbnailToolbar` | `ITaskbarList3::ThumbBarAddButtons` — **Windows only** |
|
|
@@ -48,43 +46,33 @@ API's existence. "Works" means a test asserts it or it was driven and seen.
|
|
|
48
46
|
|
|
49
47
|
### Input methods — built on IMM32, with the gaps that layer has
|
|
50
48
|
|
|
51
|
-
CJK input works
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
What it does not carry is what IMM32 itself no longer carries. Windows has
|
|
57
|
-
stopped loading IMM32 input methods, so every modern one — the new Microsoft
|
|
58
|
-
Japanese and Chinese IMEs included — is a TSF text service reaching an IMM32
|
|
59
|
-
window through a compatibility layer, and that layer does not pass on **voice
|
|
60
|
-
typing** (Win+H inserts nothing), the shell's **handwriting** panel, or
|
|
61
|
-
**shape-writing** on the touch keyboard. A TSF text store is what closes
|
|
62
|
-
those; windows.md §"IME" has the design and why it is the harder rung.
|
|
49
|
+
CJK input works, through the same composition events a Wayland text-input
|
|
50
|
+
drives, so an application handles one composition and gets both. The preedit
|
|
51
|
+
is drawn **in the field** rather than in a floating box, and the candidate
|
|
52
|
+
list follows the caret.
|
|
63
53
|
|
|
64
|
-
|
|
65
|
-
|
|
54
|
+
What it does not carry is what IMM32 itself no longer carries. Modern input
|
|
55
|
+
methods — the new Microsoft Japanese and Chinese IMEs included — are TSF text
|
|
56
|
+
services reaching an IMM32 window through a compatibility layer, which does
|
|
57
|
+
not pass on **voice typing** (Win+H inserts nothing), the shell's
|
|
58
|
+
**handwriting** panel, or **shape-writing** on the touch keyboard. A TSF text
|
|
59
|
+
store would close those; it is not built. Reconversion (asking the IME to
|
|
60
|
+
re-open a committed word) is not wired up either, though IMM32 carries it.
|
|
66
61
|
|
|
67
62
|
### Screen readers — built, without text ranges
|
|
68
63
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
`aria-valuenow` — is read
|
|
75
|
-
AT-SPI bridge reads, so the two backends cannot disagree
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
reuse candidate for the same shape, and a provider of our own was built
|
|
82
|
-
instead so the release pipeline does not grow a Rust toolchain for both
|
|
83
|
-
architectures.
|
|
84
|
-
|
|
85
|
-
**What is missing is `ITextProvider`.** A `<textinput>` exposes its value, so a
|
|
86
|
-
screen reader reads the field and hears edits, but caret-by-caret and
|
|
87
|
-
word-by-word navigation _inside_ it is not there. That is the next piece.
|
|
64
|
+
Screen readers are served by a UI Automation provider of this project's own,
|
|
65
|
+
answering from a copy of the tree the app pushes, so a screen reader is never
|
|
66
|
+
paced by the app's busiest moment. Roles, names, descriptions, states,
|
|
67
|
+
bounding rectangles, focus and the Invoke, Toggle, Value and RangeValue
|
|
68
|
+
patterns all cross; `announce()` goes out as a UIA notification. Everything an
|
|
69
|
+
app writes — `role`, `aria-label`, `aria-checked`, `aria-valuenow` — is read
|
|
70
|
+
by the same code the AT-SPI bridge reads, so the two backends cannot disagree
|
|
71
|
+
about what a node is.
|
|
72
|
+
|
|
73
|
+
**What is missing is `ITextProvider`.** A `<textinput>` exposes its value, so
|
|
74
|
+
a screen reader reads the field and hears edits, but caret-by-caret and
|
|
75
|
+
word-by-word navigation _inside_ it is not there.
|
|
88
76
|
|
|
89
77
|
## Not implemented
|
|
90
78
|
|
|
@@ -94,27 +82,22 @@ Ordered by what it costs an app today.
|
|
|
94
82
|
|
|
95
83
|
The jump list is built (`useJumpList` above) but it is **not** what
|
|
96
84
|
`useLauncherMenu` means, and is deliberately not wired to it. A launcher-menu
|
|
97
|
-
item carries a callback; a jump-list task starts a _new process_ with
|
|
98
|
-
because the shell launches the program rather than calling into
|
|
99
|
-
one. Mapping one onto the other would quietly change what a click
|
|
100
|
-
|
|
101
|
-
They become the same feature once a second launch can hand its arguments to
|
|
102
|
-
the first, which is the activation work below.
|
|
85
|
+
item carries a callback; a jump-list task starts a _new process_ with
|
|
86
|
+
arguments, because the shell launches the program rather than calling into
|
|
87
|
+
the running one. Mapping one onto the other would quietly change what a click
|
|
88
|
+
does.
|
|
103
89
|
|
|
104
90
|
### Activation — file associations, URL schemes, second launches
|
|
105
91
|
|
|
106
|
-
`useAppOpen` and `useAppActivate` fire on
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
or `ISingleInstanceApp`. [uri-schemes.md](uri-schemes.md) documents what the
|
|
111
|
-
other platforms do.
|
|
92
|
+
`useAppOpen` and `useAppActivate` never fire on Windows: there are no file
|
|
93
|
+
associations, no URL schemes and no single-instance handoff yet, so a second
|
|
94
|
+
launch is a second process. [uri-schemes.md](uri-schemes.md) documents what
|
|
95
|
+
the other platforms do.
|
|
112
96
|
|
|
113
97
|
### Eyedropper — the pixel is read, the ladder has no rung
|
|
114
98
|
|
|
115
|
-
The bridge reads a screen pixel
|
|
116
|
-
`
|
|
117
|
-
so `useEyedropper()` reports `supported: false` here until one draws the
|
|
99
|
+
The bridge reads a screen pixel (`app.screenColorAt`, `app.pointerPosition`),
|
|
100
|
+
but `useEyedropper()` reports `supported: false` here until a rung draws the
|
|
118
101
|
loupe over it.
|
|
119
102
|
|
|
120
103
|
### Calendar — blocked, not missing
|
|
@@ -126,9 +109,9 @@ package identity. Unpackaged, there is nothing to call, and the hook reports
|
|
|
126
109
|
### Permissions — nothing to ask
|
|
127
110
|
|
|
128
111
|
`usePermission` has no Windows meaning for an unpackaged app: the capability
|
|
129
|
-
API is for packaged apps, and everything else sits under one per-device
|
|
130
|
-
The
|
|
131
|
-
own error is the answer.
|
|
112
|
+
API is for packaged apps, and everything else sits under one per-device
|
|
113
|
+
switch. The answer is `'unknown'` until something is attempted, and the
|
|
114
|
+
attempt's own error is the answer.
|
|
132
115
|
|
|
133
116
|
### Global menu — not a Windows concept
|
|
134
117
|
|
|
@@ -137,43 +120,36 @@ own error is the answer.
|
|
|
137
120
|
|
|
138
121
|
### Keyboard grabs
|
|
139
122
|
|
|
140
|
-
`grabKeyboard` accepts and does nothing: there is no Windows mechanism for it
|
|
141
|
-
|
|
142
|
-
only while it is the foreground window.
|
|
123
|
+
`grabKeyboard` accepts and does nothing: there is no Windows mechanism for it.
|
|
124
|
+
A popup that asked for keys gets them only while it is the foreground window.
|
|
143
125
|
|
|
144
126
|
`grabPointer` is a different story — see below.
|
|
145
127
|
|
|
146
128
|
## Built, with limits worth knowing: `<popup grab>`
|
|
147
129
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
`<popup grab>` dismiss the way they do everywhere else:
|
|
130
|
+
Windows has no pointer grab to give — `SetCapture` sends a window the mouse
|
|
131
|
+
only while a button is already down — so the dismissal is reproduced from two
|
|
132
|
+
signals, and `<Select>`, `<Menu>` and any `<popup grab>` close the way they do
|
|
133
|
+
everywhere else:
|
|
153
134
|
|
|
154
|
-
- a press delivered to **another window of this application** — a click in
|
|
155
|
-
owner behind the menu, in a second window, or in the menu a submenu came
|
|
135
|
+
- a press delivered to **another window of this application** — a click in
|
|
136
|
+
the owner behind the menu, in a second window, or in the menu a submenu came
|
|
156
137
|
from;
|
|
157
|
-
- the application **losing activation** — a press in another application or
|
|
158
|
-
the desktop. A popup
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
Both end in the same made-up outside press the Wayland backend sends for
|
|
162
|
-
`xdg_popup.popup_done`, and the Cocoa backend's grab rule redirects a press to
|
|
163
|
-
the holder the same way, so all four backends answer a dismissal through one
|
|
164
|
-
path (`_dismissOutside` in src/events.js).
|
|
138
|
+
- the application **losing activation** — a press in another application or
|
|
139
|
+
on the desktop. A popup never takes activation itself, so opening one raises
|
|
140
|
+
no blur.
|
|
165
141
|
|
|
166
142
|
**The gap**: a press on the _non-client_ area of one of our own windows — a
|
|
167
|
-
title bar, a resize border
|
|
168
|
-
|
|
169
|
-
|
|
143
|
+
title bar, a resize border — is not reported, so a menu left open while the
|
|
144
|
+
user drags the window behind it stays open. X11's grab covers that and this
|
|
145
|
+
does not.
|
|
170
146
|
|
|
171
147
|
## What Windows has that nothing else does
|
|
172
148
|
|
|
173
|
-
|
|
174
|
-
their own, and
|
|
175
|
-
|
|
176
|
-
|
|
149
|
+
Some Windows surfaces have no cross-platform API to fit into, so they have
|
|
150
|
+
APIs of their own, and **a backend installs a method, and its presence is the
|
|
151
|
+
capability**. They are reported as features of the launcher, beside the badge
|
|
152
|
+
and the progress bar:
|
|
177
153
|
|
|
178
154
|
```jsx
|
|
179
155
|
const launcher = useDesktopCapability('launcher');
|
|
@@ -186,48 +162,16 @@ launcher.features.recentDocuments; // the shell's Recent lists
|
|
|
186
162
|
They live there rather than in `useSupports()` because `useSupports` answers
|
|
187
163
|
for the **display** — transparency, shaders, embedding — and a taskbar button
|
|
188
164
|
is not a display property; and because a boolean cannot say _which_ launcher
|
|
189
|
-
answered
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
- **
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
taskbar.
|
|
203
|
-
- ~~**Recent documents.**~~ Built: `useRecentDocument`.
|
|
204
|
-
- **Explorer verbs.** "Open with", a context-menu handler, a preview handler,
|
|
205
|
-
a thumbnail provider. All of these are COM servers registered per file type,
|
|
206
|
-
and on Windows 11 a context-menu handler must be a packaged app extension —
|
|
207
|
-
which puts them behind packaging along with the calendar.
|
|
208
|
-
- **Protocol activation.** `myapp://` as a first-class launch, which is the
|
|
209
|
-
activation work above seen from the other side.
|
|
210
|
-
- **Taskbar overlay as a status light.** Already reachable: `setBadge` takes a
|
|
211
|
-
label, and an app that wants a dot rather than a number can pass one
|
|
212
|
-
character.
|
|
213
|
-
|
|
214
|
-
## What would fit this library and exists nowhere yet
|
|
215
|
-
|
|
216
|
-
Not Windows-specific — gaps in the cross-platform surface that Windows happens
|
|
217
|
-
to be able to answer.
|
|
218
|
-
|
|
219
|
-
- **A print dialog and a print surface.** No backend has one. Windows has
|
|
220
|
-
`PrintDlgEx` and the XPS document API; macOS has `NSPrintOperation`;
|
|
221
|
-
freedesktop has the portal. A `<Print>` surface that takes the same verb
|
|
222
|
-
table the screen does is a natural fit for a renderer that already draws
|
|
223
|
-
through one.
|
|
224
|
-
- **A colour chooser.** `useEyedropper` samples a pixel; nothing offers the
|
|
225
|
-
system's colour picker. `IColorPickerDialog` (WinUI), `NSColorPanel` and the
|
|
226
|
-
portal all exist.
|
|
227
|
-
- **A font chooser.** `IDWriteFontSet` plus the Common Item Dialog's
|
|
228
|
-
chooser, `NSFontPanel`, the portal's.
|
|
229
|
-
- **Session lifecycle.** `WM_QUERYENDSESSION` and `WM_ENDSESSION` on Windows,
|
|
230
|
-
`NSApplicationDelegate` on macOS, the session manager on Linux — an app that
|
|
231
|
-
wants to save before logout has no hook on any backend.
|
|
232
|
-
- **Power and battery.** `GetSystemPowerStatus`, `IOPowerSources`, UPower.
|
|
233
|
-
A `useBattery` would be one hook over three.
|
|
165
|
+
answered. Every other backend answers false for the three, and the hooks do
|
|
166
|
+
nothing where the method is absent. `examples/taskbar.jsx` is the shape;
|
|
167
|
+
there is no `process.platform` in it.
|
|
168
|
+
|
|
169
|
+
- **Thumbnail toolbars** — `useThumbnailToolbar`: up to seven buttons under
|
|
170
|
+
the taskbar thumbnail, play/pause/next for a media app.
|
|
171
|
+
- **Recent documents** — `useRecentDocument`.
|
|
172
|
+
- **A jump list** — `useJumpList` (see [`useLauncherMenu`](#uselaunchermenu-is-inert)).
|
|
173
|
+
- **Taskbar overlay as a status light**: `setBadge` takes a label, and an app
|
|
174
|
+
that wants a dot rather than a number can pass one character.
|
|
175
|
+
|
|
176
|
+
Ideas not built yet are in the
|
|
177
|
+
[design notes](../design/windows-integrations.md#what-windows-has-that-nothing-else-does).
|