@domicile-desktop/sdk 0.0.0-alpha-e612f0697e41 → 0.0.0-alpha-ab2d2f0e2a24
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 +51 -26
- package/dist/app.d.ts +5 -6
- package/dist/desktop/app-desktop.js +1 -1
- package/dist/desktop/capture.d.ts +1 -1
- package/dist/desktop/dbus.d.ts +1 -1
- package/dist/desktop/desktop.js +1 -1
- package/dist/desktop/displays.d.ts +1 -1
- package/dist/desktop/files.d.ts +1 -1
- package/dist/desktop/keyboard.d.ts +1 -1
- package/dist/desktop/layer.d.ts +2 -0
- package/dist/desktop/layer.js +5 -0
- package/dist/desktop/portal-wire.d.ts +34 -0
- package/dist/desktop/portal-wire.js +717 -0
- package/dist/desktop/portals.js +1 -1
- package/dist/desktop/processes.d.ts +1 -1
- package/dist/desktop/session.d.ts +1 -1
- package/dist/desktop/shell.d.ts +1 -1
- package/dist/desktop/system-calls.d.ts +104 -0
- package/dist/desktop/system-calls.js +534 -0
- package/dist/desktop/windows.d.ts +1 -1
- package/dist/portal.d.ts +0 -32
- package/dist/portal.js +0 -713
- package/dist/shell.d.ts +3 -2
- package/dist/system.d.ts +0 -101
- package/dist/system.js +3 -532
- package/package.json +2 -6
- package/dist/appearance.d.ts +0 -10
- package/dist/appearance.js +0 -18
package/README.md
CHANGED
|
@@ -16,29 +16,34 @@ import type { Shell as ShellModule } from "@domicile-desktop/sdk/shell";
|
|
|
16
16
|
|
|
17
17
|
export const Shell: ShellModule = (root, domicile) => {
|
|
18
18
|
const show = () => {
|
|
19
|
-
// Render `domicile.windows` as `<app app-id="…">` elements into
|
|
19
|
+
// Render `domicile.windows.list` as `<app app-id="…">` elements into
|
|
20
|
+
// `root`.
|
|
20
21
|
};
|
|
21
22
|
show();
|
|
22
|
-
domicile.
|
|
23
|
+
domicile.windows.on("change", show);
|
|
23
24
|
};
|
|
24
25
|
```
|
|
25
26
|
|
|
26
27
|
- Domicile calls `Shell(root, domicile)` once. `domicile` is the only copy of
|
|
27
28
|
the desktop; there is no global.
|
|
29
|
+
- `domicile` is a `Domicile`: one typed object with a namespace per subject
|
|
30
|
+
(`windows`, `displays`, `keyboard`, `session`, `portals`, `files`, …).
|
|
28
31
|
- Nothing to await. The first call on `domicile` binds the channel.
|
|
29
|
-
- State is readonly attributes (`windows`, `
|
|
30
|
-
`theme`, …),
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
- `
|
|
34
|
-
|
|
32
|
+
- State is readonly attributes (`windows.list`, `displays.list`,
|
|
33
|
+
`theme.current`, …), `undefined` until the compositor says. Each
|
|
34
|
+
namespace's `on(type, listener)` says when they change and returns a
|
|
35
|
+
function that stops listening. Read, then listen.
|
|
36
|
+
- Moments (`keyboard.on("shortcut")`, `windows.on("focusrequest")`, …) are
|
|
37
|
+
events too. The engine holds each until its first listener exists.
|
|
38
|
+
- A call the compositor answers resolves a `Result`. A newer `files.search`
|
|
39
|
+
rejects the older with an `AbortError`.
|
|
35
40
|
- Only Domicile calls a shell. Develop against the real desktop with
|
|
36
41
|
`packages/dev-shell/bin/dev-shell.sh <shell>`.
|
|
37
42
|
- Render `<app app-id="…">` and `<webview window="…">` as normal DOM. CSS
|
|
38
43
|
(rounding, blur, transforms, z-index) applies to the live surface.
|
|
39
44
|
- The engine sends the pointer, wheel and keys over an `<app>` to its client,
|
|
40
|
-
through every CSS transform. `domicile.
|
|
41
|
-
`domicile.
|
|
45
|
+
through every CSS transform. `domicile.windows.focus(appId)` and
|
|
46
|
+
`domicile.windows.focusShell()` move the keyboard without a click.
|
|
42
47
|
- Both tags are the engine's built-in elements. In React, bind their events on
|
|
43
48
|
a ref; React does not bind `on…` props for unknown events.
|
|
44
49
|
- Errors follow [ERRORS.md](/docs/guidelines/ERRORS.md): bugs throw, absence
|
|
@@ -51,22 +56,21 @@ See [docs/ELEMENTS.md](docs/ELEMENTS.md) for `<app>` input and focus, and the
|
|
|
51
56
|
|
|
52
57
|
| Module | What it is |
|
|
53
58
|
| --- | --- |
|
|
54
|
-
| `./desktop/desktop` | `
|
|
55
|
-
| `./desktop/app-desktop` | `
|
|
56
|
-
| `./domicile-host` | `DomicileHost`: the
|
|
59
|
+
| `./desktop/desktop` | `Domicile`, the type of the desktop `Shell` is handed: one typed object, a namespace per subject (`windows`, `browser`, `keyboard`, `files`, `portals`, …). State is attributes with events through `on`; a call that can fail resolves a `Result`. Each namespace's types are in `./desktop/<namespace>`. `desktop(host)` builds one over a host, as the engine does; see [The desktop layer](#the-desktop-layer). |
|
|
60
|
+
| `./desktop/app-desktop` | `AppDomicile`, the desktop an app module's `main` is handed: its `files`, `processes` and `dbus`. |
|
|
61
|
+
| `./domicile-host` | `DomicileHost`: the engine's host under the desktop. Generated from the engine's IDL; see [Generated types](#generated-types). |
|
|
57
62
|
| `./config` | Types for the config file's sections, for a TypeScript config module. Generated; see [Generated types](#generated-types). `./config.schema.json` is the JSON Schema they come from. |
|
|
58
|
-
| `./shell` | `Shell`: the export a shell module must provide. Domicile calls it once with the element to draw in
|
|
59
|
-
| `./app` | `AppMain
|
|
63
|
+
| `./shell` | `Shell`: the export a shell module must provide. Domicile calls it once with the element to draw in and the `Domicile`. |
|
|
64
|
+
| `./app` | `AppMain`: an app module's `main`, which Domicile calls with the element to draw in and the `AppDomicile`. See [APP-MODULES.md](../../docs/architecture/APP-MODULES.md). |
|
|
60
65
|
| `./app-element`, `./webview-element` | Types and event names for `<app>` and `<webview>`. |
|
|
61
66
|
| `./bind-keys` | `bindKeys`: grab a shell's own chords by name and handle them by mode. `./key-action` and `./own-keybindings` are its parts. |
|
|
62
|
-
| `./fake-host` | `FakeDomicileHost`: a desktop for a shell's tests. |
|
|
67
|
+
| `./fake-host` | `FakeDomicileHost`: a desktop for a shell's tests. Hand its `domicile` to the shell. |
|
|
63
68
|
| `./file-preview` | `previewFile(domicile, path)`: a launcher's preview of a path, read through `domicile.files`: a directory's entries, a song's tags and cover, or the start of a text file. |
|
|
64
69
|
| `./dbusmenu` | `watchMenu(domicile, { bus, path })`: a tray item's `com.canonical.dbusmenu` menu, read again on each change, with `click` and `aboutToShow`. Hidden entries are left out; labels lose their mnemonic underscore, and `mnemonic` says where it was. `icon-data` comes as a PNG `data:` URL. See [SYSTEM-TRAY.md](/docs/architecture/SYSTEM-TRAY.md). |
|
|
65
|
-
| `./system` |
|
|
66
|
-
| `./portal` |
|
|
70
|
+
| `./system` | The types of the compositor's system calls: `SystemError`, `FileType`, `Listening`, … The calls are the desktop's `files`, `processes`, `dbus` and the rest; the compositor refuses most while the desktop is locked. See [SHELL-SYSTEM-ACCESS.md](/docs/SHELL-SYSTEM-ACCESS.md). |
|
|
71
|
+
| `./portal` | The types of application dialogs from `xdg-desktop-portal` (`PortalRequest`, `PortalAnswer`, …) and of running sessions that record the screen or control or capture input (`Capturing`). The desktop's `portals` lists and answers them; `<PortalDialogs />` in component-library draws them. See [PORTALS.md](/docs/PORTALS.md). |
|
|
67
72
|
| `./global-shortcuts` | `fireGlobalShortcuts`: grab the chords applications hold through the GlobalShortcuts portal and report each press and release. `<PortalDialogs />` calls it. |
|
|
68
73
|
| `./options` | `defineOptions` and `option`: the options a shell declares as its `options` export, which the Settings app edits. `watchShellOptions` reads the config's values of them, live. See [WRITING-A-SHELL.md](/docs/WRITING-A-SHELL.md#options). |
|
|
69
|
-
| `./appearance` | `watchAppearance`: the config's accent color, contrast and reduced motion, which the Settings portal also serves applications. See [SHELL-CONFIG.md](/docs/SHELL-CONFIG.md#theme). |
|
|
70
74
|
| `./icon-theme` | `readIconTheme(domicile)`: the config's `theme.icon_theme`, read from the compositor's Settings portal, or `None` for `hicolor` only. `watchIconTheme` reads it and follows `SettingChanged`. `@domicile-desktop/system-apps/app-icons` takes it. |
|
|
71
75
|
| `./extension`, `./tray`, `./notification`, `./theme`, `./display-transform` | Data types and Zod schemas for what the desktop holds. |
|
|
72
76
|
|
|
@@ -78,19 +82,40 @@ speaks it.
|
|
|
78
82
|
|
|
79
83
|
## Design
|
|
80
84
|
|
|
81
|
-
- **
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
- **
|
|
85
|
+
- **One typed object, a namespace per subject.** If the desktop has it, it is
|
|
86
|
+
a member of `domicile`. SDK functions are for policy and composition
|
|
87
|
+
(`bindKeys`, `watchShellOptions`), not for reaching the desktop.
|
|
88
|
+
- **State is attributes with a bare change event**, over events that carry
|
|
89
|
+
the value. The attribute is the one source of truth, and a late listener
|
|
90
|
+
misses nothing (`navigator.onLine` with `online` works the same).
|
|
91
|
+
- **The engine holds moments** (`focusrequest`, `shortcut`) until the first
|
|
85
92
|
listener of their type. Only the engine knows whether a listener exists.
|
|
86
|
-
- **Asks return promises.** A newer `
|
|
93
|
+
- **Asks return promises.** A newer `files.search` rejects the older.
|
|
87
94
|
- **The desktop is handed to `Shell`**, not found on a global. There is no
|
|
88
95
|
`navigator.domicile` or `window.domicile`; the shell's copy is the only one.
|
|
89
96
|
- **The engine reports the desktop's size and density**, and `<app>` routes
|
|
90
97
|
its own input ([docs/ELEMENTS.md](docs/ELEMENTS.md)). Chords are resolved by
|
|
91
98
|
the engine ([KEYBINDINGS.md](/docs/architecture/KEYBINDINGS.md)).
|
|
92
|
-
- **The SDK is
|
|
93
|
-
IDL, below.
|
|
99
|
+
- **The SDK is the desktop's types, the layer that builds it, and pure
|
|
100
|
+
helpers.** The host types under it are generated from the IDL, below.
|
|
101
|
+
|
|
102
|
+
## The desktop layer
|
|
103
|
+
|
|
104
|
+
The engine hands a shell the `Domicile` that `src/desktop/desktop.ts`'s
|
|
105
|
+
`desktop(host)` builds, and an app the `AppDomicile` of `appDesktop(host)`.
|
|
106
|
+
It does not build them itself: `codegen/generate-engine-layer.ts` bundles
|
|
107
|
+
`src/desktop/layer.ts` into the engine as `domicile_layer.js`, which the
|
|
108
|
+
engine evaluates on each shell and app page.
|
|
109
|
+
|
|
110
|
+
```sh
|
|
111
|
+
bun run generate # after changing anything under src/desktop/
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
- A change to the layer is an engine change: it needs an engine release
|
|
115
|
+
([RELEASES.md](/packages/domicile-engine/docs/RELEASES.md)).
|
|
116
|
+
- `scripts/test-engine-layer-is-the-sdks.sh` fails when the file is stale.
|
|
117
|
+
- The engine's guards export `HostShell` instead of `Shell` to be handed the
|
|
118
|
+
host itself; see [GUARDS.md](/packages/domicile-engine/docs/GUARDS.md).
|
|
94
119
|
|
|
95
120
|
## Generated types
|
|
96
121
|
|
package/dist/app.d.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export type {
|
|
1
|
+
import type { AppDomicile } from "./desktop/app-desktop";
|
|
2
|
+
export type { AppDomicile } from "./desktop/app-desktop";
|
|
3
3
|
/**
|
|
4
4
|
* The function an app module exports as `main`.
|
|
5
5
|
*
|
|
6
6
|
* `domicile run-app <module>` opens an app window, and Domicile calls this
|
|
7
|
-
* with the window's root element and the app's
|
|
8
|
-
*
|
|
9
|
-
* D-Bus, and fails anything else with `permission_denied`.
|
|
7
|
+
* with the window's root element and the app's desktop: files, processes and
|
|
8
|
+
* D-Bus. The compositor fails anything else with `permission_denied`.
|
|
10
9
|
*/
|
|
11
|
-
export type AppMain = (root: HTMLElement,
|
|
10
|
+
export type AppMain = (root: HTMLElement, domicile: AppDomicile) => void | Promise<void>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// The desktop an app module is handed: the shell's system access without its
|
|
2
2
|
// window manager. See docs/architecture/APP-MODULES.md.
|
|
3
|
-
import { system } from "../system";
|
|
4
3
|
import { dbus } from "./dbus";
|
|
5
4
|
import { fileCalls } from "./files";
|
|
6
5
|
import { processCalls } from "./processes";
|
|
6
|
+
import { system } from "./system-calls";
|
|
7
7
|
/** The desktop an app's `host` reaches. Build one per host. */
|
|
8
8
|
export const appDesktop = (host) => {
|
|
9
9
|
const calls = system(host);
|
package/dist/desktop/dbus.d.ts
CHANGED
package/dist/desktop/desktop.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
// The desktop a shell is handed, typed and grouped by what it is about. See
|
|
2
2
|
// docs/WRITING-A-SHELL.md.
|
|
3
|
-
import { system } from "../system";
|
|
4
3
|
import { appearance } from "./appearance";
|
|
5
4
|
import { browser } from "./browser";
|
|
6
5
|
import { capture } from "./capture";
|
|
@@ -18,6 +17,7 @@ import { processes } from "./processes";
|
|
|
18
17
|
import { session } from "./session";
|
|
19
18
|
import { shell } from "./shell";
|
|
20
19
|
import { hostEvent, on } from "./subscribe";
|
|
20
|
+
import { system } from "./system-calls";
|
|
21
21
|
import { theme } from "./theme";
|
|
22
22
|
import { tray } from "./tray";
|
|
23
23
|
import { windows } from "./windows";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { DisplayTransform } from "../display-transform";
|
|
2
2
|
import type { DomicileDisplay, DomicileHost } from "../domicile-host";
|
|
3
|
-
import type { System } from "../system";
|
|
4
3
|
import type { On } from "./subscribe";
|
|
4
|
+
import type { System } from "./system-calls";
|
|
5
5
|
/** One screen. Sizes are whole CSS pixels; see `DomicileDisplay`. */
|
|
6
6
|
export type Display = Omit<DomicileDisplay, "transform"> & {
|
|
7
7
|
readonly transform: DisplayTransform;
|
package/dist/desktop/files.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DomicileFileSearch, DomicileHost } from "../domicile-host";
|
|
2
|
-
import type { System } from "
|
|
2
|
+
import type { System } from "./system-calls";
|
|
3
3
|
export type FileSearch = DomicileFileSearch;
|
|
4
4
|
/** A relative path starts at the home. Refused while the desktop is locked. */
|
|
5
5
|
export type Files = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { DomicileHost } from "../domicile-host";
|
|
2
|
-
import type { System } from "../system";
|
|
3
2
|
import type { On } from "./subscribe";
|
|
3
|
+
import type { System } from "./system-calls";
|
|
4
4
|
/** A grabbed chord, pressed or let go. `keycode` is an evdev code. */
|
|
5
5
|
export type Shortcut = {
|
|
6
6
|
chord: string;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// What the engine evaluates to build the desktop it hands a shell's `Shell` or
|
|
2
|
+
// an app's `main`. `codegen/generate-engine-layer.ts` bundles it into the
|
|
3
|
+
// engine; see "The desktop layer" in packages/chrome-sdk/README.md.
|
|
4
|
+
export { appDesktop } from "./app-desktop";
|
|
5
|
+
export { desktop } from "./desktop";
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { DomicileHost } from "../domicile-host";
|
|
2
|
+
import type { BoundShortcut, PortalWallpaper } from "../portal";
|
|
3
|
+
import { Capturing, PortalAnswer, PortalRequest } from "../portal";
|
|
4
|
+
/** What the portal functions need of the desktop `Shell` is handed. */
|
|
5
|
+
export type PortalHost = Pick<DomicileHost, "answerPortalRequest"> & {
|
|
6
|
+
addEventListener: (type: "portalrequests", listener: (event: MessageEvent<string>) => void) => void;
|
|
7
|
+
removeEventListener: (type: "portalrequests", listener: (event: MessageEvent<string>) => void) => void;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Call `listener` with every unanswered request, oldest first, on each change.
|
|
11
|
+
* Returns a function that stops listening. Throws on a request of a known kind
|
|
12
|
+
* whose body does not parse: the compositor and this SDK disagree.
|
|
13
|
+
*/
|
|
14
|
+
export declare const watchPortalRequests: (host: PortalHost, listener: (requests: readonly PortalRequest[]) => void) => (() => void);
|
|
15
|
+
/**
|
|
16
|
+
* Call `listener` with every chord applications hold through the
|
|
17
|
+
* GlobalShortcuts portal, on each push. Returns a function that stops
|
|
18
|
+
* listening.
|
|
19
|
+
*/
|
|
20
|
+
export declare const watchBoundShortcuts: (host: PortalHost, listener: (shortcuts: readonly BoundShortcut[]) => void) => (() => void);
|
|
21
|
+
/**
|
|
22
|
+
* Call `listener` with every session that controls or captures input, on each
|
|
23
|
+
* change. Returns a function that stops listening.
|
|
24
|
+
*/
|
|
25
|
+
export declare const watchCapturing: (host: PortalHost, listener: (sessions: readonly Capturing[]) => void) => (() => void);
|
|
26
|
+
/**
|
|
27
|
+
* Call `listener` with the pictures applications set through the Wallpaper
|
|
28
|
+
* portal, on each push. Returns a function that stops listening.
|
|
29
|
+
*/
|
|
30
|
+
export declare const watchPortalWallpaper: (host: PortalHost, listener: (wallpaper: PortalWallpaper) => void) => (() => void);
|
|
31
|
+
/** Answer request `id`. The first answer to reach the compositor wins. */
|
|
32
|
+
export declare const answerPortalRequest: (host: PortalHost, id: number, answer: PortalAnswer) => void;
|
|
33
|
+
/** End capturing session `id`. */
|
|
34
|
+
export declare const stopCapturing: (host: PortalHost, id: number) => void;
|