react-x11 2.51.1 → 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.
Files changed (121) hide show
  1. package/README.md +94 -61
  2. package/docs/README.md +256 -0
  3. package/docs/accessibility.md +575 -0
  4. package/docs/appearance.md +317 -0
  5. package/docs/click-to-component.md +92 -0
  6. package/docs/clipboard.md +262 -0
  7. package/docs/components.md +1231 -0
  8. package/docs/dbus.md +205 -0
  9. package/docs/debugging.md +371 -0
  10. package/docs/desktop-calendar.md +247 -0
  11. package/docs/desktop.md +523 -0
  12. package/docs/devtools.md +133 -0
  13. package/docs/drag-and-drop.md +585 -0
  14. package/docs/ecosystem/animation.md +360 -0
  15. package/docs/ecosystem/data-fetching.md +186 -0
  16. package/docs/ecosystem/dev-tooling.md +393 -0
  17. package/docs/ecosystem/forms.md +277 -0
  18. package/docs/ecosystem/headless.md +194 -0
  19. package/docs/ecosystem/i18n.md +86 -0
  20. package/docs/ecosystem/icons.md +377 -0
  21. package/docs/ecosystem/layout.md +206 -0
  22. package/docs/ecosystem/routing.md +135 -0
  23. package/docs/ecosystem/state.md +344 -0
  24. package/docs/ecosystem/testing.md +474 -0
  25. package/docs/ecosystem/theming.md +494 -0
  26. package/docs/ecosystem.md +439 -0
  27. package/docs/elements.md +2079 -0
  28. package/docs/embedding.md +239 -0
  29. package/docs/events.md +742 -0
  30. package/docs/extending.md +1700 -0
  31. package/docs/eyedropper.md +164 -0
  32. package/docs/filedialog.md +222 -0
  33. package/docs/frame.md +436 -0
  34. package/docs/gl.md +173 -0
  35. package/docs/globalmenu.md +195 -0
  36. package/docs/macos.md +592 -0
  37. package/docs/notifications.md +150 -0
  38. package/docs/packaging.md +468 -0
  39. package/docs/permissions.md +143 -0
  40. package/docs/react-features.md +405 -0
  41. package/docs/remote.md +179 -0
  42. package/docs/scale.md +225 -0
  43. package/docs/security.md +132 -0
  44. package/docs/styling.md +1710 -0
  45. package/docs/system.md +519 -0
  46. package/docs/testing.md +494 -0
  47. package/docs/typescript.md +75 -0
  48. package/docs/uri-schemes.md +340 -0
  49. package/docs/wayland-backend.md +332 -0
  50. package/docs/windows-integrations.md +177 -0
  51. package/docs/windows.md +380 -0
  52. package/package.json +11 -3
  53. package/src/Reconciler.js +2 -2
  54. package/src/a11y.js +1 -1
  55. package/src/backend/context2d.js +3 -3
  56. package/src/bootstrap.js +1 -1
  57. package/src/bus.js +39 -26
  58. package/src/cli/create.d.ts +43 -0
  59. package/src/cli/create.js +305 -0
  60. package/src/cli/env.js +484 -0
  61. package/src/cli/index.js +29 -2
  62. package/src/cli/templates/AGENTS.template.md +195 -0
  63. package/src/cli/templates/DESIGN.template.md +269 -0
  64. package/src/cocoa/app.js +6 -6
  65. package/src/cocoa/bezels.js +1 -1
  66. package/src/cocoa/fonts.js +1 -1
  67. package/src/cocoa/globalmenu.js +1 -1
  68. package/src/cocoa/keymap.js +1 -1
  69. package/src/cocoa/panewindow.js +1 -1
  70. package/src/cocoa/player.js +1 -1
  71. package/src/cocoa/presenter.js +2 -2
  72. package/src/cocoa/promotion.js +1 -1
  73. package/src/cocoa/relaunch.js +1 -1
  74. package/src/cocoa/threaded.js +1 -1
  75. package/src/cocoa/video.js +1 -1
  76. package/src/cocoa/window.js +4 -4
  77. package/src/components/Menu.js +7 -2
  78. package/src/components/Switch.js +1 -1
  79. package/src/components/native.js +1 -1
  80. package/src/desktopintegration.js +2 -1
  81. package/src/desktopsettings.js +193 -24
  82. package/src/dnd.js +2 -2
  83. package/src/filedialog.js +3 -3
  84. package/src/glnodes.js +1 -1
  85. package/src/grid.js +1 -1
  86. package/src/keyboardstate.js +28 -0
  87. package/src/layouts.js +1 -1
  88. package/src/node.d.ts +10 -10
  89. package/src/nodes/animation.js +1 -1
  90. package/src/nodes/invalidate.js +1 -1
  91. package/src/nodes/layouthost.js +1 -1
  92. package/src/nodes/video.js +19 -8
  93. package/src/nodes/window/droptarget.js +1 -1
  94. package/src/pacing.js +1 -1
  95. package/src/portal.js +31 -0
  96. package/src/refresh/index.js +2 -1
  97. package/src/screencolor.js +5 -10
  98. package/src/types/system.d.ts +8 -6
  99. package/src/types/video.d.ts +5 -2
  100. package/src/videobackend.js +28 -0
  101. package/src/videoframes.js +29 -16
  102. package/src/wayland/app.js +86 -0
  103. package/src/wayland/clipboard.js +14 -7
  104. package/src/wayland/connection.js +3 -0
  105. package/src/wayland/context2d.js +129 -10
  106. package/src/wayland/protocols/index.json +6 -0
  107. package/src/wayland/protocols/xdg-foreign-unstable-v2.json +1 -0
  108. package/src/wayland/seat.js +28 -1
  109. package/src/wayland/swapchain.js +23 -0
  110. package/src/wayland/video.js +376 -0
  111. package/src/wayland/xkb.js +137 -0
  112. package/src/win32/a11y.js +1 -1
  113. package/src/win32/app.js +2 -2
  114. package/src/win32/fonts.js +1 -1
  115. package/src/win32/glarea.js +4 -4
  116. package/src/win32/overlay.js +1 -1
  117. package/src/win32/panewindow.js +3 -3
  118. package/src/win32/shell.js +1 -1
  119. package/src/win32/window.js +2 -2
  120. package/src/windowid.js +1 -1
  121. package/src/xvideo.js +189 -0
@@ -0,0 +1,195 @@
1
+ # The global menu
2
+
3
+ Some desktops put an application's menu bar in their own panel rather than in
4
+ its window — Unity's design, still shipped by KDE Plasma's Application Menu
5
+ widget, by `vala-panel-appmenu`, and by several GNOME extensions. On one of
6
+ those, an app that draws its own menu bar is drawing a second one.
7
+
8
+ react-x11 notices and hands the menu over. There is **nothing to configure and
9
+ nothing to call**:
10
+
11
+ ```jsx
12
+ import { MenuBar } from 'react-x11';
13
+
14
+ <MenuBar
15
+ menus={[
16
+ {
17
+ label: 'File',
18
+ items: [
19
+ { label: 'New', shortcut: [['Control', 'N']], onSelect: newFile },
20
+ { type: 'separator' },
21
+ { label: 'Save As…', enabled: false },
22
+ ],
23
+ },
24
+ ]}
25
+ />;
26
+ ```
27
+
28
+ Where the platform has somewhere to put a menu, `MenuBar` renders nothing and
29
+ the platform shows this one; where it does not, `MenuBar` draws the bar itself.
30
+
31
+ | where the menu goes | when |
32
+ | ------------------------------------------------------ | ------------------------------------------------------------------------------------- |
33
+ | **the macOS menu bar**, at the top of the screen | the Cocoa backend, always |
34
+ | **the desktop's panel**, over `com.canonical.dbusmenu` | a panel is running one of the applets above |
35
+ | **the window**, drawn by `MenuBar` | everything else — a stock GNOME session, XQuartz, an ssh session, a bare `startx`, CI |
36
+
37
+ On macOS the menu bar takes the menu as soon as `MenuBar` mounts and the drawn
38
+ fallback never renders; see
39
+ [macos.md §Menus](macos.md#menus-the-global-menu-finally-at-home).
40
+
41
+ On Linux the panel row is decided live. The menu leaves the window only once a
42
+ **running** owner of `com.canonical.AppMenu.Registrar` has accepted it (a
43
+ registrar that is merely D-Bus-activatable, as Ubuntu ships it, does not
44
+ count), and it moves into the panel when one starts and back into the window
45
+ when one exits, with no re-render on the app's part. KDE's
46
+ `_KDE_NET_WM_APPMENU_*` window properties are written as well. Design notes:
47
+ [design/globalmenu.md](../design/globalmenu.md).
48
+
49
+ ## The item vocabulary is the protocol's
50
+
51
+ `menus` is a plain data prop rather than JSX children, and its item shape is
52
+ `com.canonical.dbusmenu`'s: **the identical array serialises**, so the drawn
53
+ menu and the exported one cannot drift apart.
54
+
55
+ | property | meaning |
56
+ | -------------------------- | ----------------------------------------------------------- |
57
+ | `label` | the row's text |
58
+ | `type` | `'separator'` draws a rule; absent means an ordinary row |
59
+ | `items` | a submenu |
60
+ | `enabled` | defaults to `true`; `false` dims the row and makes it inert |
61
+ | `visible` | defaults to `true`; `false` removes it |
62
+ | `shortcut` | `[['Control', 'S']]` — drawn, exported **and bound** |
63
+ | `toggleType`/`toggleState` | `'checkmark'` or `'radio'`, and `0` / `1` / `-1` |
64
+ | `iconName` | an icon-theme name, for the panel's menu |
65
+ | `iconData` | raw PNG bytes, for an icon that is not in a theme |
66
+ | `disposition` | `'normal'`, `'informative'`, `'warning'`, `'alert'` |
67
+ | `onSelect(item)` | runs whichever menu the click came from |
68
+ | `key` | identity, when the label is not stable |
69
+
70
+ `toggleState` has **three** values, not two: `-1` is _indeterminate_ — a "Bold"
71
+ that is on for part of the selection — and draws as a dash rather than as
72
+ unchecked.
73
+
74
+ `icon` is the one thing that does not cross the bus: it is a react-x11 drawing
75
+ callback ([components.md](components.md#menubar--contextmenu)), so an item that
76
+ wants an icon in both menus carries `icon` for ours and `iconName` for the
77
+ panel's.
78
+
79
+ Building `menus` inline on every render is fine: only what changed is sent to
80
+ the panel, and item identity (the path of `key ?? label`) survives re-renders.
81
+
82
+ ### Shortcuts are a list, not a string
83
+
84
+ ```js
85
+ shortcut: [['Control', 'S']];
86
+ ```
87
+
88
+ The outer array is a list of _alternatives_; each inner one is modifier tokens
89
+ (`Control`, `Alt`, `Shift`, `Super`) ending in the key. Only the first is
90
+ drawn — a row has one shortcut column.
91
+
92
+ **On macOS, `Control` means ⌘** — the primary modifier — so `[['Control', 'S']]`
93
+ becomes ⌘S in the menu bar. `Super` maps there too; `Shift` and `Alt` are
94
+ themselves. A chord the `NSMenu` spelling cannot express is not printed beside
95
+ the item, but the binding still fires (the app's window answers it, below).
96
+ The text controls' chords, the edit menu that prints them
97
+ ([events.md](events.md#primary-modifier)) and the window's own bindings
98
+ (`useAccelerator`, a drawn `MenuBar` or `ContextMenu`, which prints `⌘S` beside
99
+ the row — [events.md](events.md#the-chord)) follow the same rule.
100
+
101
+ The key is named the way GDK names it, so `plus` rather than `+` and `Prior`
102
+ rather than `PgUp`, because that is what a panel's importer parses. Menus print
103
+ the friendly form: `[['Control', 'plus']]` draws as `Ctrl++`.
104
+
105
+ **It is a binding**, and the app writes it once. A mounted `MenuBar` answers
106
+ its own items' chords: Ctrl+S fires the item's `onSelect` without the menu
107
+ being opened, gated by that item's own `enabled` and `visible`
108
+ ([events.md](events.md#accelerators)).
109
+
110
+ When the panel draws the menu, the **panel does not deliver the key**, so
111
+ `MenuBar` keeps its bindings when it stops drawing. `accelerators={false}`
112
+ turns them off for an application with a dispatcher of its own.
113
+
114
+ The macOS menu bar is the one delegate that **does** deliver keys: it runs an
115
+ item on the ⌘ chord installed as its key equivalent, after the window has seen
116
+ the key. So there `MenuBar` reserves those chords — no binding in the window
117
+ answers them, its own included, and the item runs once — and keeps answering
118
+ the chords no `NSMenu` key equivalent can spell
119
+ ([events.md](events.md#the-macos-menu-bar)).
120
+
121
+ ## Seeing it work, without a desktop that has one
122
+
123
+ In a checkout of this repo, a stand-in panel prints every menu handed to it:
124
+
125
+ ```bash
126
+ npm run globalmenu:host
127
+ ```
128
+
129
+ In another terminal:
130
+
131
+ ```bash
132
+ npm run examples:menu
133
+ ```
134
+
135
+ The window's own menu bar disappears and the menu appears in the host. Type an
136
+ item's id and press Enter to activate it; Ctrl-C the host and the bar returns
137
+ to the window. On a machine with a real panel,
138
+ `npm run globalmenu:host -- --watch` attaches to the live registrar instead.
139
+
140
+ ## Turning it off
141
+
142
+ ```jsx
143
+ <MenuBar menus={menus} globalMenu={false} />
144
+ ```
145
+
146
+ ```bash
147
+ REACT_X11_NO_GLOBAL_MENU=1
148
+ ```
149
+
150
+ ```jsx
151
+ await createRoot({ desktop: { globalMenu: false } });
152
+ ```
153
+
154
+ The prop is for one bar. The other two are process-wide: the environment
155
+ variable needs no application change (for a user working around a panel that
156
+ renders something badly), and the `createRoot` option is the one an embedder
157
+ can set without it leaking to child processes — see
158
+ [desktop.md](desktop.md#turning-the-desktop-off), where `desktop: false` turns
159
+ this off along with the other session-bus integrations.
160
+
161
+ ## Drawing your own bar
162
+
163
+ `MenuBar` does all of this itself. A component that draws its own can have the
164
+ same behaviour:
165
+
166
+ ```jsx
167
+ import { useGlobalMenu } from 'react-x11';
168
+
169
+ function Bar({ menus }) {
170
+ const exported = useGlobalMenu(menus, { onSelect });
171
+ if (exported) return null; // the panel has it
172
+ return; /* … your bar … */
173
+ }
174
+ ```
175
+
176
+ ## Known limits, so they are not rediscovered as bugs
177
+
178
+ - **Stock GNOME has no global menu bar at all**, so the in-window bar stays.
179
+ The extensions that add one work.
180
+ - **`ContextMenu` is not exported** — a right-click menu belongs where the
181
+ pointer is.
182
+ - **One menu per window.** A second `MenuBar` in a window that already has one
183
+ stays drawn in the window until the first unmounts or turns `globalMenu`
184
+ off, and only then takes the panel. A bar remounted with a new `key`, or
185
+ switched off and on again, waits the same way for the one it replaces to
186
+ finish leaving (a round trip or two).
187
+ - **A lazily-built submenu fills in one round trip late.** `onAboutToShow`
188
+ runs when the panel opens the submenu, and the new items reach the panel
189
+ once they have rendered.
190
+ - **`org.gtk.Menus`/`org.gtk.Actions` is not exported**; Plasma and the GNOME
191
+ extensions consume dbusmenu.
192
+ - **No bus is a first-class configuration.** Everything here degrades to
193
+ "draw the bar" without logging: no `dbus-native` (Node 20), no
194
+ `$DBUS_SESSION_BUS_ADDRESS`, a connection that fails. See
195
+ [dbus.md](dbus.md).