react-x11 2.10.2 → 2.12.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 (100) hide show
  1. package/README.md +278 -129
  2. package/package.json +10 -3
  3. package/src/Reconciler.js +15 -17
  4. package/src/a11y.js +2 -2
  5. package/src/anchor.js +7 -5
  6. package/src/bootstrap.js +14 -0
  7. package/src/clientmessage.js +1 -1
  8. package/src/cocoa/app.js +304 -49
  9. package/src/cocoa/bezels.js +175 -30
  10. package/src/cocoa/dnd.js +27 -13
  11. package/src/cocoa/fonts.js +3 -3
  12. package/src/cocoa/glarea.js +20 -3
  13. package/src/cocoa/main.d.ts +8 -0
  14. package/src/cocoa/main.js +43 -0
  15. package/src/cocoa/panehost.js +15 -5
  16. package/src/cocoa/presenter.js +13 -9
  17. package/src/cocoa/promotion.js +4 -7
  18. package/src/cocoa/relaunch.js +207 -0
  19. package/src/cocoa/screencolor.js +62 -0
  20. package/src/cocoa/threaded.js +246 -0
  21. package/src/cocoa/window.js +256 -42
  22. package/src/components/Select.js +2 -2
  23. package/src/components/anchor.js +3 -3
  24. package/src/components/native.js +12 -7
  25. package/src/components/theme.js +2 -2
  26. package/src/debug.js +1 -1
  27. package/src/decorations.js +1 -1
  28. package/src/editmenu.js +2 -2
  29. package/src/errors.js +46 -0
  30. package/src/events.js +6 -6
  31. package/src/foreignnodes.js +3 -2
  32. package/src/frames.js +2 -2
  33. package/src/glnodes.js +1 -1
  34. package/src/grid.js +1653 -0
  35. package/src/host.d.ts +230 -0
  36. package/src/host.js +11 -3
  37. package/src/imagesource.js +1 -1
  38. package/src/index.d.ts +21 -4
  39. package/src/index.js +9 -1
  40. package/src/layouts.js +721 -0
  41. package/src/node.d.ts +4 -2
  42. package/src/node.js +19 -21
  43. package/src/nodes/animation.js +644 -0
  44. package/src/nodes/box.js +21 -0
  45. package/src/nodes/boxpaint.js +473 -0
  46. package/src/nodes/canvas.js +269 -0
  47. package/src/nodes/cascade.js +600 -0
  48. package/src/nodes/damage.js +183 -0
  49. package/src/nodes/edithistory.js +124 -0
  50. package/src/nodes/editmenupopup.js +260 -0
  51. package/src/nodes/hittest.js +185 -0
  52. package/src/nodes/image.js +266 -0
  53. package/src/nodes/install.js +75 -0
  54. package/src/nodes/invalidate.js +465 -0
  55. package/src/nodes/kinds.js +31 -0
  56. package/src/nodes/layout.js +439 -0
  57. package/src/nodes/layouthost.js +949 -0
  58. package/src/nodes/node.js +868 -0
  59. package/src/nodes/paint.js +466 -0
  60. package/src/nodes/position.js +366 -0
  61. package/src/nodes/preedit.js +127 -0
  62. package/src/nodes/queries.js +330 -0
  63. package/src/nodes/rects.js +102 -0
  64. package/src/nodes/scrollable.js +891 -0
  65. package/src/nodes/scrollbars.js +138 -0
  66. package/src/nodes/scrollblit.js +1034 -0
  67. package/src/nodes/selectable.js +142 -0
  68. package/src/nodes/styling.js +225 -0
  69. package/src/nodes/text.js +649 -0
  70. package/src/nodes/textarea.js +391 -0
  71. package/src/nodes/textinput.js +1146 -0
  72. package/src/nodes/util.js +17 -0
  73. package/src/nodes/window/anchoring.js +161 -0
  74. package/src/nodes/window/capabilities.js +190 -0
  75. package/src/nodes/window/debugpaint.js +83 -0
  76. package/src/nodes/window/droptarget.js +145 -0
  77. package/src/nodes/window/floors.js +577 -0
  78. package/src/nodes/window/flush.js +334 -0
  79. package/src/nodes/window/hints.js +482 -0
  80. package/src/nodes/window/listeners.js +222 -0
  81. package/src/nodes/window/popup.js +71 -0
  82. package/src/nodes/window/size.js +591 -0
  83. package/src/nodes/window/window.js +945 -0
  84. package/src/palette.js +1 -1
  85. package/src/registry.js +7 -3
  86. package/src/screencolor.js +212 -38
  87. package/src/screencolorhooks.js +6 -2
  88. package/src/styles.js +137 -15
  89. package/src/svgnodes.js +2 -1
  90. package/src/testing/harness.js +2 -2
  91. package/src/textselection.js +5 -3
  92. package/src/trace-registry.js +1 -1
  93. package/src/types/components.d.ts +38 -6
  94. package/src/types/elements.d.ts +11 -1
  95. package/src/types/nodes.d.ts +33 -5
  96. package/src/types/screencolor.d.ts +20 -14
  97. package/src/types/style.d.ts +94 -3
  98. package/src/windowstate.js +1 -1
  99. package/src/yoga.js +1 -1
  100. package/src/nodes.js +0 -13120
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-x11",
3
- "version": "2.10.2",
3
+ "version": "2.12.0",
4
4
  "description": "react renderer with X11 as a target",
5
5
  "main": "./src/index.js",
6
6
  "files": [
@@ -15,6 +15,8 @@
15
15
  "examples:app": "tsx examples/app.jsx",
16
16
  "examples:theming": "tsx examples/theming.jsx",
17
17
  "examples:container-queries": "tsx examples/container-queries.jsx",
18
+ "examples:schedule": "tsx examples/schedule.jsx",
19
+ "examples:custom-layout": "tsx examples/custom-layout.jsx",
18
20
  "examples:appearance": "tsx examples/appearance.jsx",
19
21
  "examples:animation": "tsx examples/animation.jsx",
20
22
  "examples:simple": "tsx examples/simple.jsx",
@@ -74,7 +76,8 @@
74
76
  "docs:build": "npm --prefix website run build",
75
77
  "docs:test": "npm --prefix website test",
76
78
  "bench:presenters": "node --import tsx scripts/bench/presenters.js",
77
- "bench:touched": "node scripts/bench/touched.js"
79
+ "bench:touched": "node scripts/bench/touched.js",
80
+ "bench:grid": "node --import tsx scripts/bench/grid/bench.mjs"
78
81
  },
79
82
  "repository": {
80
83
  "type": "git",
@@ -100,7 +103,7 @@
100
103
  "yoga-layout": "^3.2.1"
101
104
  },
102
105
  "optionalDependencies": {
103
- "@windowkit/appkit": "^0.8.0",
106
+ "@windowkit/appkit": "^0.10.0",
104
107
  "dbus-native": "^0.15.1",
105
108
  "x11-dri": "^0.7.0"
106
109
  },
@@ -206,6 +209,10 @@
206
209
  "./keysyms": {
207
210
  "types": "./src/keysyms.d.ts",
208
211
  "default": "./src/keysyms.js"
212
+ },
213
+ "./cocoa-main": {
214
+ "types": "./src/cocoa/main.d.ts",
215
+ "default": "./src/cocoa/main.js"
209
216
  }
210
217
  },
211
218
  "types": "./src/index.d.ts"
package/src/Reconciler.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // The react-reconciler host config plus the public render entry points.
2
- // Host instances are the retained nodes from nodes.js; only <window> and
2
+ // Host instances are the retained nodes from src/nodes/; only <window> and
3
3
  // <popup> map to real X11 windows (see NEXT_STEPS.md), and those windows
4
4
  // are created top-down in the commit phase (WindowNode.realize) so every
5
5
  // CreateWindow names its actual parent from the start — createInstance
@@ -18,21 +18,19 @@ import {
18
18
  } from './priority.js';
19
19
  import {
20
20
  WindowNode,
21
- PopupNode,
22
- BoxNode,
23
- TextNode,
24
- TextChunkNode,
25
- ImageNode,
26
- CanvasNode,
27
- TextInputNode,
28
- TextAreaNode,
29
- appearanceChanged,
30
21
  beginWindowMaps,
31
22
  flushWindowMaps,
32
23
  flushWindowRestacks,
33
- windowAttributes,
34
- setTextStripBelow,
35
- } from './nodes.js';
24
+ } from './nodes/window/window.js';
25
+ import { PopupNode } from './nodes/window/popup.js';
26
+ import { BoxNode } from './nodes/box.js';
27
+ import { TextNode, TextChunkNode, setTextStripBelow } from './nodes/text.js';
28
+ import { ImageNode } from './nodes/image.js';
29
+ import { CanvasNode } from './nodes/canvas.js';
30
+ import { TextInputNode } from './nodes/textinput.js';
31
+ import { TextAreaNode } from './nodes/textarea.js';
32
+ import { appearanceChanged } from './nodes/cascade.js';
33
+ import { windowAttributes } from './nodes/window/hints.js';
36
34
  import { setFrameRateDefault } from './pacing.js';
37
35
  import { hasDropProps } from './dnd.js';
38
36
  import { AppProvider } from './appcontext.js';
@@ -162,7 +160,7 @@ const HostConfig = {
162
160
 
163
161
  prepareForCommit() {
164
162
  // …so that a <window> realized during the mutation phase waits to be
165
- // mapped until React has finished hiding whatever it hides (nodes.js,
163
+ // mapped until React has finished hiding whatever it hides (nodes/window/window.js,
166
164
  // beginWindowMaps)
167
165
  beginWindowMaps();
168
166
  traceHooks.commitStart?.();
@@ -313,7 +311,7 @@ const HostConfig = {
313
311
  // Under REACT_X11_STRICT_TOKENS every token-styled node asks for one as
314
312
  // well, since a bad token is only *found* once the node is attached —
315
313
  // which is after this ran — and commitMount is the first moment React
316
- // holds that node's own fiber (nodes.js `_tokenProblem`). Gated on the
314
+ // holds that node's own fiber (nodes/cascade.js `_tokenProblem`). Gated on the
317
315
  // flag so the default mount pays nothing for a debugging mode.
318
316
  return (
319
317
  type === 'popup' ||
@@ -328,7 +326,7 @@ const HostConfig = {
328
326
  // first, and before any of the work below: the tree is on its way out.
329
327
  // `false` afterwards marks this instance's one commitMount spent, so a
330
328
  // later re-attach throws at once rather than deferring to a call that
331
- // will never come (nodes.js `_tokenProblem`).
329
+ // will never come (nodes/cascade.js `_tokenProblem`).
332
330
  const tokenError = instance._tokenError;
333
331
  instance._tokenError = false;
334
332
  if (tokenError) throw tokenError;
@@ -793,7 +791,7 @@ export async function createRoot(options = {}) {
793
791
  beginCompose(app, rest.compose);
794
792
 
795
793
  // Under what size a paragraph is painted as a strip of its ink instead
796
- // of as glyphs (nodes.js, `TextNode._paintsStrip`): six logical pixels by
794
+ // of as glyphs (nodes/text.js, `TextNode._paintsStrip`): six logical pixels by
797
795
  // default, 0 for glyphs at every size.
798
796
  setTextStripBelow(app, rest.textStripBelow);
799
797
 
package/src/a11y.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // The accessibility model: standard `role` / `aria-*` props resolved against
2
2
  // the retained node tree, plus the hook slots the renderer polls.
3
3
  //
4
- // This file is the cheap half. It is imported unconditionally by nodes.js,
4
+ // This file is the cheap half. It is imported unconditionally by src/nodes/,
5
5
  // events.js and Reconciler.js, so it must cost nothing when accessibility is
6
6
  // off: no D-Bus, no node builtins, no side effects — the hot paths pay one
7
7
  // property read per hook (`hooks.focus?.(…)`), exactly the trace-registry
@@ -941,7 +941,7 @@ export function a11yAttributes(node) {
941
941
  * **The one thing "activatable" means**: there is a click here to make.
942
942
  *
943
943
  * Three input routes stand on this — the pointer, an AT's `DoAction`, and
944
- * the keyboard's Space/Enter (`Node.defaultKeyDown`, nodes.js) — and they
944
+ * the keyboard's Space/Enter (`Node.defaultKeyDown`, nodes/node.js) — and they
945
945
  * all dispatch the same click, so a control cannot answer one of them and
946
946
  * not another. It lives here, beside the bridge's rule, because the bridge
947
947
  * is the layer that already had to write the rule down.
package/src/anchor.js CHANGED
@@ -8,7 +8,8 @@
8
8
  // `realize()`, between the measurement and `CreateWindow`, which is after
9
9
  // the last moment React could have computed a position for it. So the
10
10
  // window places *itself* from the same functions (`WindowNode._followAnchor`,
11
- // nodes.js), and the two paths agree because they are the same code.
11
+ // nodes/window/anchoring.js), and the two paths agree because they are the
12
+ // same code.
12
13
 
13
14
  import { availableArea } from './screens.js';
14
15
 
@@ -48,7 +49,7 @@ export function screenRect(node) {
48
49
  /** Where the node's owner window is on the screen. Exported for the one
49
50
  * caller that anchors to a *point* rather than to a node's rect — the edit
50
51
  * menu opens at the pointer, whose coordinates arrive window-relative on the
51
- * event (`openEditMenu`, nodes.js). */
52
+ * event (`openEditMenu`, nodes/editmenupopup.js). */
52
53
  export function windowOrigin(node) {
53
54
  const win = node?.root?.window;
54
55
  return win?._screenOrigin ?? { x: win?.x ?? 0, y: win?.y ?? 0 };
@@ -93,9 +94,10 @@ function deviceAt(at, s) {
93
94
 
94
95
  /**
95
96
  * Has the thing this popup points at scrolled out of view? The check paint
96
- * culling uses (`Node._offscreen`), asked about the sub-rect rather than
97
- * about the node: an editor scrolls its own text, so the caret leaves the
98
- * viewport a long time before the editor does.
97
+ * culling uses (`Node._offscreen`), without the pixel paint allows for ink
98
+ * past a box, and asked about the sub-rect rather than about the node: an
99
+ * editor scrolls its own text, so the caret leaves the viewport a long time
100
+ * before the editor does.
99
101
  *
100
102
  * A degenerate rect counts as its own thinnest visible version — a caret is
101
103
  * a line with no width and a `{x, y}` anchor is a point with neither, and
@@ -0,0 +1,14 @@
1
+ // What runs the moment react-x11 is imported, before any of the app's own
2
+ // code: each backend's chance to put the app where its platform wants it.
3
+ // Only the cocoa backend has one — AppKit keeps the process main thread, so
4
+ // an app on macOS moves onto a worker (src/cocoa/relaunch.js), and on that
5
+ // worker the same import sets it up. A Windows backend's UI thread will be
6
+ // the addon's own, and X11 has none, so neither needs this step
7
+ // (docs/windows.md §"Three shapes on Windows"). Imported first by
8
+ // src/index.js, so that it runs before the rest of the package.
9
+ import { isMainThread, workerData } from 'node:worker_threads';
10
+
11
+ import { bootstrapWorker, relaunchOnImport } from './cocoa/relaunch.js';
12
+
13
+ if (isMainThread) relaunchOnImport(import.meta.url);
14
+ else if (workerData?.reactX11State) bootstrapWorker(workerData.reactX11State);
@@ -75,7 +75,7 @@ function atomName(X, id) {
75
75
  * hands it to `dispatch` in arrival order.
76
76
  *
77
77
  * `dispatch` is the caller's, so the priority and the paint stay with the
78
- * other window events in nodes.js; what lives here is the naming and the
78
+ * other window events in nodes/window/; what lives here is the naming and the
79
79
  * ordering it has to preserve.
80
80
  */
81
81
  export function createClientMessages(node, dispatch) {