react-x11 1.2.0 → 2.0.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 (158) hide show
  1. package/README.md +330 -81
  2. package/package.json +132 -14
  3. package/src/ClickToComponent.js +9 -2
  4. package/src/DevToolsIntegration.js +440 -32
  5. package/src/Reconciler.js +463 -165
  6. package/src/a11y.js +1299 -0
  7. package/src/acceleratorhooks.js +86 -0
  8. package/src/accelerators.js +128 -0
  9. package/src/activate.js +168 -0
  10. package/src/anchor.js +360 -0
  11. package/src/appcontext.js +161 -0
  12. package/src/appearance.js +748 -0
  13. package/src/appearancehooks.js +96 -0
  14. package/src/apphooks.js +73 -0
  15. package/src/application.js +748 -0
  16. package/src/atspi.js +1953 -0
  17. package/src/bus.js +545 -0
  18. package/src/bushooks.js +136 -0
  19. package/src/clientmessage.js +140 -0
  20. package/src/clipboard.js +121 -0
  21. package/src/components/Button.js +148 -33
  22. package/src/components/Checkbox.js +66 -32
  23. package/src/components/Dialog.js +96 -29
  24. package/src/components/FileDialog.js +491 -0
  25. package/src/components/Icon.js +329 -0
  26. package/src/components/Menu.js +797 -133
  27. package/src/components/PasswordInput.js +434 -0
  28. package/src/components/ProgressBar.js +91 -12
  29. package/src/components/Radio.js +78 -35
  30. package/src/components/Select.js +255 -65
  31. package/src/components/Slider.js +102 -41
  32. package/src/components/SplitPane.js +206 -0
  33. package/src/components/Switch.js +100 -22
  34. package/src/components/Table.js +529 -0
  35. package/src/components/Tabs.js +211 -0
  36. package/src/components/Tooltip.js +528 -54
  37. package/src/components/anchor.js +154 -107
  38. package/src/components/change.js +34 -0
  39. package/src/components/dnd.js +103 -0
  40. package/src/components/index.js +16 -3
  41. package/src/components/keys.js +17 -20
  42. package/src/components/scribble.js +247 -0
  43. package/src/components/theme.js +350 -42
  44. package/src/components/typeahead.js +12 -2
  45. package/src/compose.js +868 -0
  46. package/src/compositing.js +224 -0
  47. package/src/dbusmenu.js +384 -0
  48. package/src/debug.d.ts +63 -0
  49. package/src/debug.js +642 -0
  50. package/src/decorations.js +486 -0
  51. package/src/desktopsettings.js +209 -0
  52. package/src/desktopsettingshooks.js +62 -0
  53. package/src/dnd.js +1725 -0
  54. package/src/editmenu.js +272 -0
  55. package/src/errors.js +98 -0
  56. package/src/events.js +1406 -162
  57. package/src/extensions.js +45 -0
  58. package/src/filedialog.js +375 -0
  59. package/src/filedialoghooks.js +132 -0
  60. package/src/fonthooks.js +64 -0
  61. package/src/fonts.js +301 -0
  62. package/src/foreignnodes.js +519 -0
  63. package/src/frame/child.js +33 -0
  64. package/src/frame/childmain.js +274 -0
  65. package/src/frame/env.js +140 -0
  66. package/src/frame/index.js +444 -0
  67. package/src/frame/lifecycle.js +67 -0
  68. package/src/frame/protocol.js +179 -0
  69. package/src/frames.js +73 -0
  70. package/src/glbackend.js +114 -0
  71. package/src/glnodes.js +125 -67
  72. package/src/globalmenu.js +683 -0
  73. package/src/host.d.ts +88 -0
  74. package/src/host.js +42 -0
  75. package/src/idle.js +490 -0
  76. package/src/idlehooks.js +100 -0
  77. package/src/imagesource.js +349 -0
  78. package/src/index.d.ts +475 -0
  79. package/src/index.js +83 -9
  80. package/src/inputtime.js +206 -0
  81. package/src/jsx-dev-runtime.d.ts +21 -0
  82. package/src/jsx-dev-runtime.js +2 -0
  83. package/src/jsx-runtime.d.ts +39 -0
  84. package/src/jsx-runtime.js +6 -0
  85. package/src/keyboard.js +256 -0
  86. package/src/keyboardstate.js +278 -0
  87. package/src/keyboardstatehooks.js +58 -0
  88. package/src/keysyms.d.ts +149 -0
  89. package/src/keysyms.js +270 -0
  90. package/src/locale.js +170 -0
  91. package/src/localehooks.js +47 -0
  92. package/src/menuitem.js +223 -0
  93. package/src/node.d.ts +597 -0
  94. package/src/node.js +44 -0
  95. package/src/nodes.js +9546 -690
  96. package/src/ntk.d.ts +44 -0
  97. package/src/ntk.js +25 -0
  98. package/src/paintcache.js +366 -0
  99. package/src/palette.js +380 -0
  100. package/src/pastestate.js +66 -0
  101. package/src/portal.js +461 -0
  102. package/src/priority.js +26 -0
  103. package/src/refresh/index.d.ts +40 -0
  104. package/src/refresh/index.js +122 -0
  105. package/src/refresh/loader.d.ts +37 -0
  106. package/src/refresh/loader.js +401 -0
  107. package/src/refresh/register.d.ts +5 -0
  108. package/src/refresh/register.js +13 -0
  109. package/src/registry.js +232 -0
  110. package/src/scale.js +626 -0
  111. package/src/scalehooks.js +27 -0
  112. package/src/screencolor.js +640 -0
  113. package/src/screencolorhooks.js +101 -0
  114. package/src/screens.js +754 -0
  115. package/src/screenshooks.js +137 -0
  116. package/src/startup.js +302 -0
  117. package/src/style.d.ts +126 -0
  118. package/src/style.js +33 -0
  119. package/src/styles.js +1482 -6
  120. package/src/svgnodes.js +306 -0
  121. package/src/testing/a11y.js +484 -0
  122. package/src/testing/components.js +414 -0
  123. package/src/testing/events.js +407 -0
  124. package/src/testing/harness.js +455 -0
  125. package/src/testing/index.d.ts +558 -0
  126. package/src/testing/index.js +85 -0
  127. package/src/testing/mock-app.js +463 -0
  128. package/src/testing/pixels.js +152 -0
  129. package/src/testing/queries.js +224 -0
  130. package/src/textrange.js +83 -0
  131. package/src/textselection.js +439 -0
  132. package/src/trace-registry.js +63 -0
  133. package/src/transfer.js +93 -0
  134. package/src/types/appearance.d.ts +84 -0
  135. package/src/types/application.d.ts +173 -0
  136. package/src/types/components.d.ts +820 -0
  137. package/src/types/dbus.d.ts +177 -0
  138. package/src/types/elements.d.ts +897 -0
  139. package/src/types/events.d.ts +549 -0
  140. package/src/types/filedialog.d.ts +260 -0
  141. package/src/types/fonts.d.ts +124 -0
  142. package/src/types/frame.d.ts +146 -0
  143. package/src/types/globalmenu.d.ts +42 -0
  144. package/src/types/nodes.d.ts +199 -0
  145. package/src/types/screencolor.d.ts +84 -0
  146. package/src/types/style.d.ts +434 -0
  147. package/src/types/system.d.ts +287 -0
  148. package/src/windowid.js +151 -0
  149. package/src/windowstate.js +393 -0
  150. package/src/xsettings.js +336 -0
  151. package/src/yoga.d.ts +55 -0
  152. package/src/yoga.js +135 -0
  153. package/src/components/Canvas3D.js +0 -28
  154. package/src/geometry3d.js +0 -223
  155. package/src/pointer3d.js +0 -158
  156. package/src/raycast3d.js +0 -146
  157. package/src/richnodes.js +0 -436
  158. package/src/scene3d.js +0 -683
@@ -0,0 +1,96 @@
1
+ // `useSystemAppearance()` — the desktop's appearance as something a component
2
+ // re-renders on.
3
+ //
4
+ // The store lives in `appearance.js` and is process-global, because that is
5
+ // what it describes: one desktop, one set of preferences, shared by every
6
+ // root in the process the way the D-Bus connection under it is.
7
+
8
+ import { useCallback, useSyncExternalStore } from 'react';
9
+
10
+ import {
11
+ appearanceSnapshot,
12
+ systemAppearance,
13
+ watchAppearance,
14
+ } from './appearance.js';
15
+ import { useAppOrNull } from './appcontext.js';
16
+
17
+ /**
18
+ * Read the store, and start the ladder if `enabled`.
19
+ *
20
+ * The flag exists for `<ThemeProvider>`, which calls this on every render and
21
+ * must not open a D-Bus connection for an app that gave it a single palette
22
+ * and no `dark`. Hooks cannot be conditional, so the condition goes in here
23
+ * rather than into which hooks run.
24
+ */
25
+ function useAppearance(enabled) {
26
+ const app = useAppOrNull();
27
+ const subscribe = useCallback(
28
+ (onChange) => {
29
+ if (!enabled) return () => {};
30
+ // Subscribe, *then* ask — the same ordering the portal rung uses
31
+ // internally, and for the same reason. React's own re-check after
32
+ // subscribing would cover a value that landed in between, but not a
33
+ // change that arrived and left.
34
+ const stop = watchAppearance(onChange);
35
+ systemAppearance({ app }).catch(() => {
36
+ // `systemAppearance` does not reject; this is belt and braces so a
37
+ // future rung cannot turn a desktop probe into an unhandled rejection
38
+ });
39
+ return stop;
40
+ },
41
+ [app, enabled],
42
+ );
43
+ // The same frozen object until something changes — `getSnapshot` returning
44
+ // a fresh `{ colorScheme, … }` per call is what makes React loop.
45
+ return useSyncExternalStore(
46
+ subscribe,
47
+ appearanceSnapshot,
48
+ appearanceSnapshot,
49
+ );
50
+ }
51
+
52
+ /** Not public: `<ThemeProvider>`'s seam, so following the desktop is opt-in. */
53
+ export function useAppearanceWhen(enabled) {
54
+ return useAppearance(enabled);
55
+ }
56
+
57
+ /**
58
+ * What the desktop looks like, live.
59
+ *
60
+ * ```jsx
61
+ * const { colorScheme, accent, contrast, reducedMotion } = useSystemAppearance();
62
+ *
63
+ * <box style={{ backgroundColor: colorScheme === 'dark' ? '#1e1e1e' : 'white' }}>
64
+ * <Button style={{ backgroundColor: accent ?? '#2980b9' }} label="Save" />
65
+ * </box>
66
+ * ```
67
+ *
68
+ * | | |
69
+ * | --- | --- |
70
+ * | `colorScheme` | `'light'`, `'dark'` or `'no-preference'` |
71
+ * | `accent` | `'#ed5b00'`, or **null** — most backends do not implement it |
72
+ * | `contrast` | `'normal'` or `'high'` |
73
+ * | `reducedMotion` | `true` when the user asked for less animation |
74
+ * | `source` | `'portal'`, `'xsettings'`, `'macos'`, `'cache'`, or null |
75
+ *
76
+ * **`'no-preference'` means use your own default**, not "use light". And
77
+ * `accent` is null far more often than not, so fall back to your own brand
78
+ * colour rather than to grey — an app that goes colourless on a desktop that
79
+ * simply did not answer the question looks broken.
80
+ *
81
+ * The **first** render is served from what this machine answered last time
82
+ * (`source: 'cache'`), so it starts in the right colours rather than in the
83
+ * defaults, and a real rung replaces it a frame or two later. An app that
84
+ * needs a verified answer before it draws anything at all — the first launch
85
+ * on a machine — waits for one:
86
+ *
87
+ * ```jsx
88
+ * const [root] = await Promise.all([createRoot(), systemAppearance()]);
89
+ * ```
90
+ *
91
+ * See `docs/appearance.md`, and `<ThemeProvider dark={…}>` for the case where
92
+ * all you want is for the app to follow the desktop.
93
+ */
94
+ export function useSystemAppearance() {
95
+ return useAppearance(true);
96
+ }
@@ -0,0 +1,73 @@
1
+ // The two inbound events, as rendering code sees them.
2
+ //
3
+ // Thin on purpose. `application.js` owns the bus, the buffer and the replay;
4
+ // this is the lid that lets a component take a deep link without the app
5
+ // author threading a callback down from the module scope where
6
+ // `registerApplication()` had to be called.
7
+ //
8
+ // There is **nothing to wrap** — the registration is process-global, because
9
+ // an application has one identity on the desktop — so these work in any tree,
10
+ // including a component library's.
11
+
12
+ import { useEffect, useRef } from 'react';
13
+
14
+ import { onAppActivate, onAppOpen } from './application.js';
15
+
16
+ /**
17
+ * Subscribe without re-subscribing when the handler identity changes.
18
+ *
19
+ * The subscription must be installed **once**, on mount: a launch that arrived
20
+ * before anything was listening is replayed to the first handler that
21
+ * attaches, and re-subscribing on every render would keep re-arming a drain
22
+ * that has already happened while doing nothing useful. The handler itself is
23
+ * read at call time, so a link that arrives three minutes from now runs the
24
+ * closure from the current render rather than the mounting one.
25
+ */
26
+ function useLaunchSubscription(subscribe, handler) {
27
+ const live = useRef(handler);
28
+ live.current = handler;
29
+ useEffect(() => subscribe((...args) => live.current?.(...args)), [subscribe]);
30
+ }
31
+
32
+ /**
33
+ * The desktop handed this app URIs to open — a `myapp://` link clicked
34
+ * somewhere else, or a document opened from a file manager.
35
+ *
36
+ * ```jsx
37
+ * function App() {
38
+ * const win = useRef(null);
39
+ * useAppOpen((uris, ctx) => {
40
+ * activateWindow(win, { timestamp: ctx.timestamp });
41
+ * const code = new URL(uris[0]).searchParams.get('code');
42
+ * finishLogin(code);
43
+ * });
44
+ * return <window ref={win}>…</window>;
45
+ * }
46
+ * ```
47
+ *
48
+ * Fires for links that arrived **before the tree mounted** too, which is the
49
+ * normal case when the bus started this process to deliver one: they are
50
+ * buffered and replayed to the first handler that attaches.
51
+ *
52
+ * `uris` is attacker-controlled input from an unauthenticated local peer —
53
+ * `Open` is callable by anything on the session bus. Validate before acting,
54
+ * and never treat a URI's path as a filesystem path. See docs/uri-schemes.md.
55
+ */
56
+ export function useAppOpen(handler) {
57
+ useLaunchSubscription(onAppOpen, handler);
58
+ }
59
+
60
+ /**
61
+ * The desktop asked this app to come forward with nothing to open — the user
62
+ * launched it again from the panel while it was already running.
63
+ *
64
+ * ```jsx
65
+ * useAppActivate((ctx) => activateWindow(win, { timestamp: ctx.timestamp }));
66
+ * ```
67
+ *
68
+ * Nothing is raised for you: an app that answers a second launch by opening a
69
+ * new document should not have to undo a raise first.
70
+ */
71
+ export function useAppActivate(handler) {
72
+ useLaunchSubscription(onAppActivate, handler);
73
+ }