react-x11 2.15.2 → 2.16.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 +37 -0
- package/package.json +4 -3
- package/src/Reconciler.js +85 -22
- package/src/anchor.js +60 -18
- package/src/application.js +25 -1
- package/src/capabilities.js +349 -0
- package/src/cocoa/app.js +28 -9
- package/src/cocoa/context2d.js +139 -6
- package/src/cocoa/fonts.js +78 -0
- package/src/cocoa/presenter.js +17 -0
- package/src/cocoa/promotion.js +20 -0
- package/src/cocoa/relaunch.js +8 -3
- package/src/cocoa/symbols.js +64 -0
- package/src/cocoa/threaded.js +24 -4
- package/src/cocoa/window.js +362 -139
- package/src/components/ProgressBar.js +1 -1
- package/src/components/Slider.js +72 -39
- package/src/components/anchor.js +7 -2
- package/src/components/index.js +1 -0
- package/src/components/theme.js +32 -28
- package/src/dbusmenuexport.js +243 -0
- package/src/desktopcapabilityhooks.js +160 -0
- package/src/filedialoghooks.js +3 -5
- package/src/frame/childmain.js +8 -20
- package/src/frame/env.js +2 -10
- package/src/globalmenu.js +3 -205
- package/src/icontheme.js +240 -0
- package/src/imagesource.js +98 -3
- package/src/index.d.ts +1 -0
- package/src/index.js +11 -2
- package/src/launcher.js +235 -32
- package/src/launcherhooks.js +47 -28
- package/src/node.d.ts +7 -0
- package/src/nodes/animation.js +17 -47
- package/src/nodes/cascade.js +17 -2
- package/src/nodes/image.js +65 -2
- package/src/nodes/kinds.js +12 -0
- package/src/nodes/layout.js +5 -1
- package/src/nodes/node.js +17 -3
- package/src/nodes/paint.js +117 -0
- package/src/nodes/scope.js +259 -0
- package/src/nodes/scrollable.js +53 -6
- package/src/nodes/text.js +2 -0
- package/src/nodes/textarea.js +1 -1
- package/src/nodes/textinput.js +1 -1
- package/src/nodes/window/anchoring.js +45 -18
- package/src/nodes/window/flush.js +6 -5
- package/src/nodes/window/popup.js +10 -0
- package/src/nodes/window/size.js +40 -2
- package/src/nodes/window/window.js +41 -14
- package/src/registry.js +2 -1
- package/src/settings.js +332 -0
- package/src/statusnotifier.js +752 -0
- package/src/styles.js +212 -8
- package/src/symbols.js +200 -0
- package/src/testing/mock-app.js +10 -0
- package/src/trayhooks.js +193 -29
- package/src/types/capabilities.d.ts +139 -0
- package/src/types/components.d.ts +33 -0
- package/src/types/elements.d.ts +57 -6
- package/src/types/launcher.d.ts +50 -4
- package/src/types/style.d.ts +57 -0
- package/src/types/system.d.ts +104 -0
- package/src/types/tray.d.ts +64 -6
package/src/types/style.d.ts
CHANGED
|
@@ -305,6 +305,14 @@ export interface PaintStyle {
|
|
|
305
305
|
outlineColor?: Color;
|
|
306
306
|
/** The gap between the border box and the ring. Default 1. */
|
|
307
307
|
outlineOffset?: number;
|
|
308
|
+
/**
|
|
309
|
+
* How opaque the node is **with everything inside it**, from 0 to 1: the
|
|
310
|
+
* subtree is drawn once and composited at this alpha, so a card, its
|
|
311
|
+
* border, its icon and its text fade as one. A paint property — legal in a
|
|
312
|
+
* state block, and it transitions and loops. `0` draws nothing and is
|
|
313
|
+
* still hit; values outside 0..1 are clamped.
|
|
314
|
+
*/
|
|
315
|
+
opacity?: number;
|
|
308
316
|
}
|
|
309
317
|
|
|
310
318
|
/**
|
|
@@ -327,6 +335,34 @@ export type TextOverflow = 'clip' | 'ellipsis';
|
|
|
327
335
|
export type TextRendering =
|
|
328
336
|
'auto' | 'optimizeSpeed' | 'optimizeLegibility' | 'geometricPrecision';
|
|
329
337
|
|
|
338
|
+
/** One `fontVariantNumeric` keyword, and the OpenType feature it turns on. */
|
|
339
|
+
export type NumericVariant =
|
|
340
|
+
| 'lining-nums' // lnum
|
|
341
|
+
| 'oldstyle-nums' // onum
|
|
342
|
+
| 'proportional-nums' // pnum
|
|
343
|
+
| 'tabular-nums' // tnum
|
|
344
|
+
| 'diagonal-fractions' // frac
|
|
345
|
+
| 'stacked-fractions' // afrc
|
|
346
|
+
| 'ordinal' // ordn
|
|
347
|
+
| 'slashed-zero'; // zero
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* CSS's `font-variant-numeric`: `'normal'`, or keywords separated by spaces,
|
|
351
|
+
* at most one of each pair that contradicts — lining or oldstyle,
|
|
352
|
+
* proportional or tabular, diagonal or stacked fractions. Typed as a first
|
|
353
|
+
* keyword and whatever follows; the rest is checked when the style is.
|
|
354
|
+
*/
|
|
355
|
+
export type FontVariantNumeric =
|
|
356
|
+
'normal' | NumericVariant | `${NumericVariant} ${string}`;
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* CSS's `font-feature-settings`, by OpenType tag: the tags to turn on,
|
|
360
|
+
* `['tnum', 'ss01']`, or tag → on or off, or the alternate a feature picks,
|
|
361
|
+
* `{ liga: false, salt: 2 }`.
|
|
362
|
+
*/
|
|
363
|
+
export type FontFeatureSettings =
|
|
364
|
+
readonly string[] | Readonly<Record<string, boolean | number>>;
|
|
365
|
+
|
|
330
366
|
/** Text properties. All affect measurement except `color`. */
|
|
331
367
|
export interface TextStyle {
|
|
332
368
|
color?: Color;
|
|
@@ -346,6 +382,19 @@ export interface TextStyle {
|
|
|
346
382
|
* at any size. `'auto'` (default) lets size decide. Changing it repaints
|
|
347
383
|
* without reflowing: it cannot move anything. */
|
|
348
384
|
textRendering?: TextRendering;
|
|
385
|
+
/** CSS's `letter-spacing`, in pixels: added after every character, the
|
|
386
|
+
* last on a line included, and negative to tighten. Spaced text drops the
|
|
387
|
+
* optional ligatures (`liga`, `clig`, `dlig`, `hlig`) unless
|
|
388
|
+
* `fontFeatureSettings` names them. Inherits. */
|
|
389
|
+
letterSpacing?: number;
|
|
390
|
+
/** Which figures: `'tabular-nums'` gives every digit one width, so a
|
|
391
|
+
* number that changes holds its width while it does. The friendly names
|
|
392
|
+
* for features `fontFeatureSettings` can also set by tag, and it wins
|
|
393
|
+
* where the two meet. Inherits, apart from `fontFeatureSettings`. */
|
|
394
|
+
fontVariantNumeric?: FontVariantNumeric;
|
|
395
|
+
/** Any OpenType feature, by tag. A feature the face does not have is
|
|
396
|
+
* ignored. Compared by value, so an object literal is fine. Inherits. */
|
|
397
|
+
fontFeatureSettings?: FontFeatureSettings;
|
|
349
398
|
textAlign?: TextAlign;
|
|
350
399
|
lineHeight?: number;
|
|
351
400
|
/** CSS's `text-wrap`. `'nowrap'` measures the text at unbounded width, so
|
|
@@ -436,6 +485,14 @@ export interface AnimationSpec {
|
|
|
436
485
|
easing?: Easing;
|
|
437
486
|
/** Turn around at each end instead of wrapping back to `from`. */
|
|
438
487
|
alternate?: boolean;
|
|
488
|
+
/**
|
|
489
|
+
* When the loop's own time starts, in ms — CSS's `animation-delay`. A
|
|
490
|
+
* positive delay holds `from` that long before the first crossing; a
|
|
491
|
+
* negative one starts the loop that far in. Default `0`. What staggers
|
|
492
|
+
* loops of one duration: three dots at `0`, `-150` and `-300` never move
|
|
493
|
+
* together.
|
|
494
|
+
*/
|
|
495
|
+
delay?: number;
|
|
439
496
|
}
|
|
440
497
|
|
|
441
498
|
/**
|
package/src/types/system.d.ts
CHANGED
|
@@ -267,6 +267,110 @@ export interface DesktopSettings {
|
|
|
267
267
|
*/
|
|
268
268
|
export function useDesktopSettings(): DesktopSettings;
|
|
269
269
|
|
|
270
|
+
// --------------------------------------------------------------------------
|
|
271
|
+
// The app's own settings
|
|
272
|
+
// --------------------------------------------------------------------------
|
|
273
|
+
|
|
274
|
+
/** A value a settings store can keep: what JSON can. */
|
|
275
|
+
export type SettingValue =
|
|
276
|
+
| string
|
|
277
|
+
| number
|
|
278
|
+
| boolean
|
|
279
|
+
| null
|
|
280
|
+
| readonly SettingValue[]
|
|
281
|
+
| { readonly [key: string]: SettingValue };
|
|
282
|
+
|
|
283
|
+
export interface SettingsOptions<T extends Record<string, SettingValue>> {
|
|
284
|
+
/**
|
|
285
|
+
* A reverse-DNS name no other app uses, like `'com.example.myapp'`: the
|
|
286
|
+
* name of the app's settings directory. Nothing is registered with it.
|
|
287
|
+
*/
|
|
288
|
+
appId: string;
|
|
289
|
+
/** Each setting's value when nothing was saved. */
|
|
290
|
+
defaults?: T;
|
|
291
|
+
/** Where `settings.json` goes instead of the per-user directory for the
|
|
292
|
+
* app — for a portable install, or a test. */
|
|
293
|
+
directory?: string;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/** A value's kind: `false` as `boolean`, `'brown'` as `string`, so a
|
|
297
|
+
* default does not narrow what the setting may be set to. */
|
|
298
|
+
export type SettingKind<V> = V extends boolean
|
|
299
|
+
? boolean
|
|
300
|
+
: V extends string
|
|
301
|
+
? string
|
|
302
|
+
: V extends number
|
|
303
|
+
? number
|
|
304
|
+
: V;
|
|
305
|
+
|
|
306
|
+
/** A setting's type: its default's kind, for a key the defaults name, else
|
|
307
|
+
* the fallback's. */
|
|
308
|
+
export type SettingOf<T, K, V> = SettingKind<K extends keyof T ? T[K] : V>;
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* What an app remembers between launches, kept in `settings.json` in its
|
|
312
|
+
* per-user directory, written atomically and coalesced.
|
|
313
|
+
*/
|
|
314
|
+
export interface Settings<T extends Record<string, SettingValue>> {
|
|
315
|
+
/** The file the values are kept in. */
|
|
316
|
+
readonly path: string;
|
|
317
|
+
/** `[value, setValue]` for one setting, like `useState`; every component
|
|
318
|
+
* using the key sees the same value, and a change is saved. A key with no
|
|
319
|
+
* default takes a fallback. */
|
|
320
|
+
use<K extends string, V extends SettingValue = never>(
|
|
321
|
+
key: K,
|
|
322
|
+
fallback?: V,
|
|
323
|
+
): [
|
|
324
|
+
SettingOf<T, K, V>,
|
|
325
|
+
(
|
|
326
|
+
value:
|
|
327
|
+
| SettingOf<T, K, V>
|
|
328
|
+
| ((previous: SettingOf<T, K, V>) => SettingOf<T, K, V>),
|
|
329
|
+
) => void,
|
|
330
|
+
];
|
|
331
|
+
get<K extends string, V extends SettingValue = never>(
|
|
332
|
+
key: K,
|
|
333
|
+
fallback?: V,
|
|
334
|
+
): K extends keyof T ? SettingOf<T, K, V> : SettingOf<T, K, V> | undefined;
|
|
335
|
+
/** Change a setting now, and save it a moment later — a quarter second
|
|
336
|
+
* after the last change, and at least once a second while they keep
|
|
337
|
+
* coming. Throws a `TypeError` for a value JSON cannot keep. */
|
|
338
|
+
set<K extends string>(
|
|
339
|
+
key: K,
|
|
340
|
+
value: K extends keyof T ? SettingOf<T, K, never> : SettingValue,
|
|
341
|
+
): void;
|
|
342
|
+
/** Forget what was saved for a setting: its default again. */
|
|
343
|
+
reset(key: string): void;
|
|
344
|
+
/** Save what is waiting now. Resolves when it is on disk. */
|
|
345
|
+
flush(): Promise<void>;
|
|
346
|
+
/** Hear every change; returns the unsubscribe. */
|
|
347
|
+
subscribe(listener: () => void): () => void;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* The settings store for an app — one per file in the process, so every call
|
|
352
|
+
* with the same `appId` shares values.
|
|
353
|
+
*
|
|
354
|
+
* ```tsx
|
|
355
|
+
* const settings = createSettings({
|
|
356
|
+
* appId: 'com.example.Hush',
|
|
357
|
+
* defaults: { volume: 0.5, dark: false },
|
|
358
|
+
* });
|
|
359
|
+
* function Volume() {
|
|
360
|
+
* const [volume, setVolume] = settings.use('volume');
|
|
361
|
+
* return <Slider value={volume} onChange={setVolume} />;
|
|
362
|
+
* }
|
|
363
|
+
* ```
|
|
364
|
+
*
|
|
365
|
+
* It lives in `~/Library/Application Support/<appId>/settings.json` on macOS
|
|
366
|
+
* and `$XDG_CONFIG_HOME/<appId>/settings.json` elsewhere, and is read the
|
|
367
|
+
* first time a value is asked for. What is still unsaved when the process
|
|
368
|
+
* exits is written then.
|
|
369
|
+
*/
|
|
370
|
+
export function createSettings<T extends Record<string, SettingValue>>(
|
|
371
|
+
options: SettingsOptions<T>,
|
|
372
|
+
): Settings<T>;
|
|
373
|
+
|
|
270
374
|
// --------------------------------------------------------------------------
|
|
271
375
|
// Locale
|
|
272
376
|
// --------------------------------------------------------------------------
|
package/src/types/tray.d.ts
CHANGED
|
@@ -3,16 +3,26 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import type { MenuItem } from './components.js';
|
|
6
|
+
import type { DesktopBackend, TrayFeatures } from './capabilities.js';
|
|
6
7
|
|
|
7
8
|
export interface TrayClickEvent {
|
|
8
9
|
button: 'left' | 'right' | 'middle';
|
|
9
|
-
/**
|
|
10
|
-
*
|
|
10
|
+
/** Where the click was: global top-left screen coordinates in **logical
|
|
11
|
+
* pixels**, the unit a `<popup>`'s `x`/`y` and `anchor={{ rect }}` take —
|
|
12
|
+
* the anchor for a popup of your own. The freedesktop protocol names no
|
|
13
|
+
* unit for its point and hosts differ, so there it is read against the
|
|
14
|
+
* monitors and the pointer; docs/desktop.md "The tray" says where that
|
|
15
|
+
* cannot tell. */
|
|
11
16
|
x: number;
|
|
12
17
|
y: number;
|
|
18
|
+
/** The item's rect. `0` on the freedesktop rung, whose protocol has none —
|
|
19
|
+
* read `features.clickRect` rather than testing for zero. */
|
|
13
20
|
width: number;
|
|
14
21
|
height: number;
|
|
22
|
+
/** `1` on the freedesktop rung, which does not count clicks. */
|
|
15
23
|
clickCount: number;
|
|
24
|
+
/** All `false` on the freedesktop rung, which carries no modifier state.
|
|
25
|
+
* `features.clickModifiers` is the honest answer. */
|
|
16
26
|
shift: boolean;
|
|
17
27
|
control: boolean;
|
|
18
28
|
option: boolean;
|
|
@@ -20,9 +30,27 @@ export interface TrayClickEvent {
|
|
|
20
30
|
}
|
|
21
31
|
|
|
22
32
|
export interface TrayOptions {
|
|
23
|
-
/**
|
|
24
|
-
*
|
|
33
|
+
/** A themed icon name — an SF Symbol on the cocoa rung (`'bell.badge'`),
|
|
34
|
+
* an icon-theme name on a freedesktop one (`'mail-unread'`) — or the bytes
|
|
35
|
+
* of a PNG. On the cocoa rung bytes are drawn as a template image so they
|
|
36
|
+
* follow the bar's light and dark. */
|
|
25
37
|
icon?: string | Uint8Array | null;
|
|
38
|
+
/** Shown instead of `icon` while `attention` is set. Freedesktop only. */
|
|
39
|
+
attentionIcon?: string | Uint8Array | null;
|
|
40
|
+
/** A small badge drawn over the icon. Freedesktop only. */
|
|
41
|
+
overlayIcon?: string | Uint8Array | null;
|
|
42
|
+
/** Ask the panel to mark the item — `Status = NeedsAttention`.
|
|
43
|
+
* Freedesktop only; `features.attention` says so. */
|
|
44
|
+
attention?: boolean;
|
|
45
|
+
/** The spec's item category: `'ApplicationStatus'` (default),
|
|
46
|
+
* `'Communications'`, `'SystemServices'` or `'Hardware'`. Freedesktop
|
|
47
|
+
* only, and mostly affects where a panel sorts the icon. */
|
|
48
|
+
category?: string;
|
|
49
|
+
/** A directory to look `icon` up in, for icons shipped beside the app
|
|
50
|
+
* rather than installed in a theme. Freedesktop only. */
|
|
51
|
+
iconThemePath?: string;
|
|
52
|
+
/** A scroll over the icon. Freedesktop only. */
|
|
53
|
+
onScroll?: (event: { delta: number; orientation: string }) => void;
|
|
26
54
|
/** Text beside the icon, or alone. */
|
|
27
55
|
title?: string | null;
|
|
28
56
|
tooltip?: string | null;
|
|
@@ -40,8 +68,33 @@ export interface TrayOptions {
|
|
|
40
68
|
}
|
|
41
69
|
|
|
42
70
|
export interface TrayState {
|
|
43
|
-
/**
|
|
71
|
+
/**
|
|
72
|
+
* Whether **this item** was taken by a tray.
|
|
73
|
+
*
|
|
74
|
+
* A measurement, not a prediction: the hook tried. It **settles** — false
|
|
75
|
+
* on the first frame, true a tick later if a host is there — so render the
|
|
76
|
+
* fallback first and upgrade. It follows the host, so a panel that exits
|
|
77
|
+
* flips it back.
|
|
78
|
+
*/
|
|
44
79
|
available: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Whether `available` is an answer yet: true on the first frame on macOS,
|
|
82
|
+
* where the status item is made there and then, and for `null` options;
|
|
83
|
+
* on the freedesktop tray, once the host has taken or refused the item. An
|
|
84
|
+
* app whose whole UI is its tray renders nothing until this, instead of a
|
|
85
|
+
* fallback window that flashes on every start.
|
|
86
|
+
*/
|
|
87
|
+
settled: boolean;
|
|
88
|
+
/** Which mechanism took it, or null. */
|
|
89
|
+
backend: DesktopBackend | null;
|
|
90
|
+
/** What that mechanism can do. Empty until `available` settles. */
|
|
91
|
+
features: Partial<TrayFeatures>;
|
|
92
|
+
/**
|
|
93
|
+
* A tray that answered and then **refused**, which is a different fact from
|
|
94
|
+
* a desktop with no tray — and the only one of the two with a fix. Null
|
|
95
|
+
* when there is simply no tray.
|
|
96
|
+
*/
|
|
97
|
+
error: Error | null;
|
|
45
98
|
/** Reserved. */
|
|
46
99
|
rect: null;
|
|
47
100
|
}
|
|
@@ -49,6 +102,11 @@ export interface TrayState {
|
|
|
49
102
|
/**
|
|
50
103
|
* An icon in the system tray while this component is mounted; every field
|
|
51
104
|
* follows its value, and the item is removed on unmount. `null` means no
|
|
52
|
-
* item.
|
|
105
|
+
* item.
|
|
106
|
+
*
|
|
107
|
+
* `NSStatusItem` on the cocoa backend; `org.kde.StatusNotifierItem` over
|
|
108
|
+
* D-Bus on a freedesktop session, which needs something hosting a tray —
|
|
109
|
+
* Plasma and most panels do, GNOME needs an AppIndicator extension. Where
|
|
110
|
+
* neither answers, `available` stays false and nothing is logged.
|
|
53
111
|
*/
|
|
54
112
|
export declare function useTray(options: TrayOptions | null): TrayState;
|