react-x11 2.51.1 → 2.52.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.
Files changed (91) hide show
  1. package/README.md +87 -54
  2. package/docs/README.md +410 -0
  3. package/docs/accessibility.md +628 -0
  4. package/docs/appearance.md +416 -0
  5. package/docs/architecture/accessibility.md +470 -0
  6. package/docs/architecture/animation.md +707 -0
  7. package/docs/architecture/container-queries.md +525 -0
  8. package/docs/architecture/custom-layout.md +334 -0
  9. package/docs/architecture/drag-and-drop.md +941 -0
  10. package/docs/architecture/element-layer-contents.md +622 -0
  11. package/docs/architecture/frame-pacing.md +255 -0
  12. package/docs/architecture/grid-layout.md +358 -0
  13. package/docs/architecture/protocol-efficiency.md +357 -0
  14. package/docs/architecture/video.md +1149 -0
  15. package/docs/architecture/windowed-regions.md +854 -0
  16. package/docs/click-to-component.md +125 -0
  17. package/docs/clipboard.md +281 -0
  18. package/docs/components.md +1749 -0
  19. package/docs/dbus.md +277 -0
  20. package/docs/debugging.md +464 -0
  21. package/docs/desktop-calendar.md +284 -0
  22. package/docs/desktop.md +648 -0
  23. package/docs/devtools.md +250 -0
  24. package/docs/drag-and-drop.md +663 -0
  25. package/docs/ecosystem/animation.md +394 -0
  26. package/docs/ecosystem/data-fetching.md +201 -0
  27. package/docs/ecosystem/dev-tooling.md +436 -0
  28. package/docs/ecosystem/forms.md +313 -0
  29. package/docs/ecosystem/headless.md +219 -0
  30. package/docs/ecosystem/i18n.md +89 -0
  31. package/docs/ecosystem/icons.md +410 -0
  32. package/docs/ecosystem/layout.md +216 -0
  33. package/docs/ecosystem/routing.md +146 -0
  34. package/docs/ecosystem/state.md +361 -0
  35. package/docs/ecosystem/testing.md +500 -0
  36. package/docs/ecosystem/theming.md +540 -0
  37. package/docs/ecosystem.md +473 -0
  38. package/docs/elements.md +2762 -0
  39. package/docs/embedding.md +288 -0
  40. package/docs/events.md +1025 -0
  41. package/docs/extending.md +2242 -0
  42. package/docs/eyedropper.md +223 -0
  43. package/docs/filedialog.md +258 -0
  44. package/docs/frame.md +580 -0
  45. package/docs/gl.md +170 -0
  46. package/docs/globalmenu.md +278 -0
  47. package/docs/glx.md +137 -0
  48. package/docs/macos.md +3295 -0
  49. package/docs/notifications.md +164 -0
  50. package/docs/packaging.md +611 -0
  51. package/docs/permissions.md +148 -0
  52. package/docs/react-features.md +430 -0
  53. package/docs/remote.md +223 -0
  54. package/docs/scale.md +339 -0
  55. package/docs/security.md +132 -0
  56. package/docs/styling.md +1928 -0
  57. package/docs/system.md +599 -0
  58. package/docs/testing.md +514 -0
  59. package/docs/typescript.md +117 -0
  60. package/docs/uri-schemes.md +380 -0
  61. package/docs/wayland-backend.md +591 -0
  62. package/docs/wayland.md +545 -0
  63. package/docs/windows-embedding.md +271 -0
  64. package/docs/windows-gl.md +221 -0
  65. package/docs/windows-integrations.md +233 -0
  66. package/docs/windows.md +1404 -0
  67. package/package.json +9 -2
  68. package/src/bus.js +39 -26
  69. package/src/cli/create.d.ts +43 -0
  70. package/src/cli/create.js +305 -0
  71. package/src/cli/env.js +484 -0
  72. package/src/cli/index.js +29 -2
  73. package/src/cli/templates/AGENTS.template.md +195 -0
  74. package/src/cli/templates/DESIGN.template.md +269 -0
  75. package/src/desktopintegration.js +2 -1
  76. package/src/desktopsettings.js +193 -24
  77. package/src/filedialog.js +3 -3
  78. package/src/keyboardstate.js +28 -0
  79. package/src/node.d.ts +10 -10
  80. package/src/portal.js +31 -0
  81. package/src/screencolor.js +5 -10
  82. package/src/types/system.d.ts +8 -6
  83. package/src/wayland/app.js +59 -0
  84. package/src/wayland/clipboard.js +14 -7
  85. package/src/wayland/connection.js +3 -0
  86. package/src/wayland/context2d.js +129 -10
  87. package/src/wayland/protocols/index.json +6 -0
  88. package/src/wayland/protocols/xdg-foreign-unstable-v2.json +1 -0
  89. package/src/wayland/seat.js +28 -1
  90. package/src/wayland/swapchain.js +23 -0
  91. package/src/wayland/xkb.js +137 -0
package/README.md CHANGED
@@ -11,12 +11,14 @@ A React renderer for **desktop applications**, whose host is a display
11
11
  system rather than a document. React's job in a renderer is to compute what
12
12
  changed; the renderer's job is to turn that into side effects on some host —
13
13
  in react-dom those are DOM mutations, here they are **X11 protocol requests**
14
- written to a socket, or **Core Animation layers and CoreGraphics drawing** on
15
- macOS. There is no DOM, no HTML and no browser engine underneath: this is not
16
- Electron with a different skin, and `<div>` is not an element that exists.
17
- Build GUI programs for a Linux desktop, for a display at the other end of an
18
- ssh connection, or as a native Mac app, with your React / React Native
19
- experience — flexbox layout, components, hooks, synthetic events.
14
+ written to a socket, **Core Animation layers and CoreGraphics drawing** on
15
+ macOS, **Direct2D drawing on DirectComposition surfaces** on Windows, or GL
16
+ frames handed to a **Wayland** compositor. There is no DOM and no browser
17
+ engine underneath: this is not Electron with a different skin, and `<div>` is
18
+ not an element that exists. Build GUI programs for a Linux desktop, for a
19
+ display at the other end of an ssh connection, as a native Mac app or a
20
+ Windows one, with your React / React Native experience — flexbox layout,
21
+ components, hooks, synthetic events.
20
22
 
21
23
  ### Four backends, one tree
22
24
 
@@ -47,21 +49,28 @@ main thread ([docs/macos.md](docs/macos.md#js-on-a-worker-a-ui-thread-of-the-bri
47
49
 
48
50
  Two more backends exist beside these, serving the goal of **full
49
51
  cross-platform support**, and both are younger than the two above.
50
- **native Wayland** ([docs/wayland.md](docs/wayland.md)) is opt-in rather than
51
- automatic, because X11 stays the default on Linux — the remote case is the
52
- flagship reason this project exists and Wayland has no network transparency.
53
- **Windows** ([docs/windows.md](docs/windows.md)) — Win32 windows, Direct2D
54
- and DirectWrite, DWM compositing through DirectComposition — renders and
55
- takes mouse input, with the desktop integrations still to come. Each is a
56
- backend beside the others rather than a replacement for any of them: the
57
- same tree, the same components, the same `style` objects.
52
+ **native Wayland** ([docs/wayland-backend.md](docs/wayland-backend.md)) —
53
+ the wire protocol in JavaScript and a GLES rasterizer of its own, on mutter,
54
+ sway and labwc, with no Xwayland in the path — is opt-in
55
+ (`REACT_X11_BACKEND=wayland`) rather than automatic, because X11 stays the
56
+ default on Linux: the remote case is the flagship reason this project exists
57
+ and Wayland has no network transparency. **Windows**
58
+ ([docs/windows.md](docs/windows.md)) — Win32 windows, Direct2D and
59
+ DirectWrite, DWM compositing through DirectComposition — is the default on
60
+ Windows, with the keyboard, an IME, a screen-reader bridge and most of the
61
+ desktop integrations in place
62
+ ([docs/windows-integrations.md](docs/windows-integrations.md) is the
63
+ measured list). Each is a backend beside the others rather than a
64
+ replacement for any of them: the same tree, the same components, the same
65
+ `style` objects.
58
66
 
59
67
  Layout is [yoga-layout](https://www.npmjs.com/package/yoga-layout) (WASM) on
60
- both, and text shaping is [fontkit](https://github.com/foliojs/fontkit) on
61
- the X11 side, CoreText on the Cocoa one. **`npm install` never compiles
62
- anything**: the X11 stack is JavaScript all the way down, and the two native
63
- addons in the tree — the Cocoa bridge and `x11-dri` for direct GL — are
64
- optional dependencies that ship prebuilt. And `npm test` doesn't even need
68
+ every backend, and text shaping is [fontkit](https://github.com/foliojs/fontkit)
69
+ through ntk on X11 and Wayland, CoreText on Cocoa and DirectWrite on Windows.
70
+ **`npm install` never compiles anything**: the X11 stack is JavaScript all
71
+ the way down, and the native addons in the tree — the Cocoa and win32
72
+ bridges, and `x11-dri` for direct GL and the Wayland socket — are optional
73
+ dependencies that ship prebuilt. And `npm test` doesn't even need
65
74
  an X server (node-x11 ships an in-process pure-JS X server that the tests
66
75
  render into and read pixels back from; every screenshot below was rendered
67
76
  that way too, by driving the real examples through the real event
@@ -141,30 +150,41 @@ three:
141
150
  Drag and drop works both ways with the desktop, and the taskbar's own
142
151
  surfaces — a thumbnail toolbar, a jump list, recent documents — are there
143
152
  behind a capability, so an app that also runs elsewhere asks
144
- `useSupports()` rather than the platform. What it does not have is **IME
145
- and screen-reader support**: an app is unusable with a screen reader and
146
- in CJK input. So an app that needs either on Windows _this month_ still
147
- wants Electron or Tauri.
153
+ `useSupports()` rather than the platform. CJK input goes through an
154
+ IMM32 input method and screen readers through a UI Automation provider of
155
+ the project's own, both with gaps worth reading before you rely on them:
156
+ no voice typing or handwriting (those want a TSF text store), and no
157
+ caret-by-caret reading inside a text field yet. Nor is there activation —
158
+ file associations, URL schemes and second launches — so an app that needs
159
+ any of that on Windows _this month_ still wants Electron or Tauri.
148
160
  [docs/windows-integrations.md](docs/windows-integrations.md) is the
149
161
  measured status and [docs/windows.md](docs/windows.md) the design. The three
150
162
  targets are not the same app: the desktop-shell half of X11 (`<foreign>`
151
163
  embedding, panel struts, substructure redirect, the window-manager example
152
164
  below) has no macOS or Windows equivalent, and `react-x11/test` drives the
153
165
  X11 backend only. [docs/macos.md](docs/macos.md) says which is which.
154
- - **native Wayland — today.** There is no Wayland backend yet. Ordinary
155
- application windows work fine on a Wayland desktop through Xwayland, which
156
- is not going away — but the desktop-shell half of X11 (panel struts,
157
- global key grabs, screen capture, and the window-manager example below)
158
- needs a real X session. A native backend is coming too, as a **target
159
- beside X11, not a migration**: [docs/wayland.md](docs/wayland.md) is the
160
- RFC, from the fd transport up to what the rendering would ride on.
166
+ - **native Wayland — today.** The native backend is opt-in and young:
167
+ windows, text, input, an input method, the clipboard, popups, drag and
168
+ drop and layer-shell docks and panels run on mutter, sway and labwc, and
169
+ [docs/wayland-backend.md](docs/wayland-backend.md#what-is-left) lists what
170
+ is left — no multisampling, no `<Frame>` panes, no drag icon. Ordinary
171
+ application windows also work on a Wayland desktop through Xwayland, which
172
+ is not going away — but the desktop-shell half of X11 (`<foreign>`
173
+ embedding, global key grabs, and the window-manager example below) needs a
174
+ real X session. It is a **target beside X11, not a migration**;
175
+ [docs/wayland.md](docs/wayland.md) is the RFC it was built from.
161
176
  - **reusing web components.** There is no DOM. Your MUI, your Tailwind and
162
177
  your `recharts` do not come with you; the state, data-fetching, validation
163
178
  and math libraries mostly do. [docs/ecosystem.md](docs/ecosystem.md) says
164
179
  which is which, and what the failure looks like when it is the wrong one.
165
- - **rendering HTML.** There is no HTML element and no webview. Rich
166
- documents are markdown, through `<Markdown>` in
167
- [`@react-x11/components`](https://github.com/sidorares/react-x11-components).
180
+ - **being a browser.** There is no webview and no browser engine to embed.
181
+ HTML is a component rather than a substrate: `<Html>` in
182
+ [`@react-x11/components`](https://github.com/sidorares/react-x11-components)
183
+ renders an HTML + CSS document with a layout engine of its own — selectable,
184
+ with real widgets for its form controls, and with a page's scripts run
185
+ against a DOM when `scripts` turns them on — and `<Markdown>` beside it
186
+ renders markdown. Both are for documents an app shows; an app that _is_ a
187
+ web app still wants Electron or Tauri.
168
188
  - **text entry outside Latin.** See [Known issues](#known-issues).
169
189
 
170
190
  The screenshots below are the X11 backend, rendered headlessly into
@@ -258,6 +278,7 @@ drawn tree. See [docs/elements.md](docs/elements.md) for the full reference.
258
278
  | `<textarea>` | the same editor, wrapped and multi-line, scrolling with its content |
259
279
  | `<image>` | PNG/JPEG/WebP from `src` (more formats under Bun), natural-size aware; also pixels the server already has |
260
280
  | `<canvas>` | escape hatch: `onDraw={(ctx, {width, height}) => …}` with a canvas-like 2d context (XRender-backed on X11, CoreGraphics on Cocoa) |
281
+ | `<video>` | decoded frames the app pushes, on every backend, or a `src` the platform plays itself where it has a player |
261
282
  | `<svg>` | static SVG (paths, shapes, gradients, transforms), sized like `<image>` |
262
283
  | `<glarea>` | an OpenGL surface in the layout — see [3D](#3d) |
263
284
  | `<foreign>` | another application's X window, laid out as an element. **X11 only** ([docs/embedding.md](docs/embedding.md)) |
@@ -303,8 +324,9 @@ entry just blinks. The OAuth redirect this is for has an easier answer that
303
324
  needs none of it, and the page says so first. See
304
325
  [docs/uri-schemes.md](docs/uri-schemes.md).
305
326
 
306
- **Drag and drop** works with the rest of the desktop on both backends —
307
- XDND on X11, `NSDraggingSession` on Cocoa. `<box dropAccept={['files']}
327
+ **Drag and drop** works with the rest of the desktop on every backend —
328
+ XDND on X11, `NSDraggingSession` on Cocoa, OLE on Windows, `wl_data_device`
329
+ on Wayland. `<box dropAccept={['files']}
308
330
  onDrop={…}>` takes a file dragged out of Nautilus or Finder, and
309
331
  `<box draggable dragData={…}>` can be dropped into a file manager or an
310
332
  editor. Drags that stay inside the app never touch the wire and hand their
@@ -318,16 +340,16 @@ Everything an app does outside its own windows is a **ladder**: the best
318
340
  rung the machine actually has, the same hook whichever one answers, and a
319
341
  first-class "this desktop cannot" rather than a throw.
320
342
 
321
- | what | rungs, best first |
322
- | ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
323
- | [open/save panels](docs/filedialog.md) `useFileDialog()` | `NSOpenPanel` · the XDG portal · `osascript` · one react-x11 draws |
324
- | [notifications](docs/notifications.md) `notify()` | UNUserNotificationCenter · `org.freedesktop.Notifications` · `osascript` · `notify-send` |
325
- | [light/dark, accent](docs/appearance.md) `useSystemAppearance()` | the settings portal · macOS · XSETTINGS — remembered on disk, so the first frame is not a flash |
326
- | [permissions](docs/permissions.md) `usePermission()` | TCC on macOS · the Settings pane · `'unknown'` on Linux until the device portals land |
327
- | [the user's real events](docs/desktop-calendar.md) | EventKit through the bridge · EventKit through `osascript` · Evolution Data Server |
328
- | [sample a screen colour](docs/eyedropper.md) `useEyedropper()` | `NSColorSampler` · the portal's picker · a crosshair grab on plain X11 |
329
- | a badge on the icon `setBadge()` | `NSDockTile.badgeLabel` · `com.canonical.Unity.LauncherEntry` |
330
- | a tray icon `useTray()` | `NSStatusItem`. **Cocoa only today** — `available` is false on X11 until StatusNotifierItem lands ([#353](https://github.com/sidorares/react-x11/issues/353)) |
343
+ | what | rungs, best first |
344
+ | ---------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
345
+ | [open/save panels](docs/filedialog.md) `useFileDialog()` | `NSOpenPanel` / the Common Item Dialog · the XDG portal · `osascript` · one react-x11 draws |
346
+ | [notifications](docs/notifications.md) `notify()` | UNUserNotificationCenter / a tray balloon on Windows · `org.freedesktop.Notifications` · `osascript` · `notify-send` |
347
+ | [light/dark, accent](docs/appearance.md) `useSystemAppearance()` | the settings portal · macOS · XSETTINGS — remembered on disk, so the first frame is not a flash |
348
+ | [permissions](docs/permissions.md) `usePermission()` | TCC on macOS · the Settings pane · `'unknown'` on Linux until the device portals land |
349
+ | [the user's real events](docs/desktop-calendar.md) | EventKit through the bridge · EventKit through `osascript` · Evolution Data Server |
350
+ | [sample a screen colour](docs/eyedropper.md) `useEyedropper()` | `NSColorSampler` · the portal's picker · a crosshair grab on plain X11 |
351
+ | a badge on the icon `setBadge()` | `NSDockTile.badgeLabel` / a taskbar overlay icon · `com.canonical.Unity.LauncherEntry` |
352
+ | a tray icon `useTray()` | `NSStatusItem` / `Shell_NotifyIcon` · `org.kde.StatusNotifierItem` — `available` is false on a desktop with no tray host, such as stock GNOME |
331
353
 
332
354
  [docs/system.md](docs/system.md) is the rest of the machine — monitors,
333
355
  window state, idle, keyboard layout, locale — and
@@ -336,8 +358,8 @@ itself.
336
358
 
337
359
  ### 3D
338
360
 
339
- `<glarea>` is a GL surface in the layout, with three ways underneath it and
340
- the same `onDraw` over all three:
361
+ `<glarea>` is a GL surface in the layout, with the same `onDraw` over every
362
+ way underneath it — three on the mature backends:
341
363
 
342
364
  - **indirect GLX** (the X11 default) — the GL protocol encoded into the X
343
365
  connection, no native bindings and no GPU driver bindings, the same
@@ -352,6 +374,10 @@ the same `onDraw` over all three:
352
374
  sublayer of the window; shaders and render targets, on any Mac, with no
353
375
  X server involved.
354
376
 
377
+ The two younger backends have their own: WGL on Windows, composited through
378
+ DirectComposition ([docs/windows-gl.md](docs/windows-gl.md)), and on Wayland
379
+ a viewport into the window's own GLES target.
380
+
355
381
  ```jsx
356
382
  <glarea
357
383
  style={{ flexGrow: 1 }}
@@ -376,8 +402,8 @@ a scroll container from scrolling, like the DOM.
376
402
 
377
403
  ## Examples
378
404
 
379
- On macOS these run natively, with no X server; everywhere else they need
380
- one — and "an X server" is a broader thing than it sounds: your Linux
405
+ On macOS and Windows these run natively, with no X server; everywhere else
406
+ they need one — and "an X server" is a broader thing than it sounds: your Linux
381
407
  desktop, XQuartz, `Xvfb` for automation, `Xephyr` for a disposable screen, a
382
408
  VNC server, or your own display reached over `ssh -X` from wherever the
383
409
  program actually runs — see [docs/remote.md](docs/remote.md), which is the
@@ -419,8 +445,8 @@ neither.
419
445
  ### Window manager
420
446
 
421
447
  `examples:wm` is a real reparenting window manager, and it is **X11 only** —
422
- substructure redirect has no macOS equivalent, so this is one of the places
423
- the two backends are not the same app. It takes over the root window, puts
448
+ substructure redirect has no macOS, Windows or Wayland-client equivalent, so
449
+ this is one of the places the backends are not the same app. It takes over the root window, puts
424
450
  every application's window inside a frame it draws, and moves, resizes,
425
451
  focuses and closes them. The frames are ordinary react-x11 `<window>`s — the
426
452
  titlebar, the buttons and the eight resize handles are components with
@@ -475,7 +501,7 @@ an element by clicking it in the app; "highlight updates when components
475
501
  render" outlines the rects that just re-rendered; the style editor edits a
476
502
  selected element's style live; and the Profiler can restart the app to
477
503
  record its mount. All of it is above the display system, so it works the
478
- same on both backends. `REACT_X11_DEVTOOLS_HOST` /
504
+ same on every backend. `REACT_X11_DEVTOOLS_HOST` /
479
505
  `REACT_X11_DEVTOOLS_PORT` override the default `localhost:8097`. See
480
506
  [docs/devtools.md](docs/devtools.md).
481
507
 
@@ -602,10 +628,17 @@ the character that was actually typed.
602
628
  Cocoa the character arrives with the event, so AltGr-style levels type;
603
629
  an `NSTextInputClient` IME for CJK is not built there either.
604
630
 
631
+ On the other two backends the input method is the platform's: the
632
+ Wayland backend speaks `zwp_text_input_v3` to the compositor's IME, and the
633
+ Windows one answers IMM32, so CJK composes on both
634
+ ([docs/windows-integrations.md](docs/windows-integrations.md) has Windows'
635
+ limits).
636
+
605
637
  Two more places the backends genuinely differ, so you can plan around them
606
638
  rather than discover them: `react-x11/test` drives the **X11** backend only,
607
- and the AT-SPI accessibility bridge is X11's — on Cocoa `createRoot()`
608
- leaves it off, and an `NSAccessibility` bridge is not built yet
639
+ and the accessibility bridges are AT-SPI on Linux and UI Automation on
640
+ Windows — on Cocoa `createRoot()` leaves accessibility off, and an
641
+ `NSAccessibility` bridge is not built yet
609
642
  ([docs/accessibility.md](docs/accessibility.md)).
610
643
 
611
644
  ## Security