Skip to content

Shell Integration and IPC

Aqueous owns window and workspace policy in the compositor. Desktop shells can use standard layer-shell, workspace, and foreign-toplevel protocols, plus the versioned Aqueous shell interface for richer state and typed runtime actions. Component desktops select Pearl, DMS, Noctalia, or no shell through Welcome. See Desktop selection and Installation.

Terminal window
aqueousctl shell capabilities --json
aqueousctl shell snapshot --json
aqueousctl shell watch --json

Capabilities describe what the installed compositor supports. Snapshots and deltas expose outputs, workspaces, windows, seats, keyboard groups/devices, and session state. IDs belong to a compositor session; workspace IDs are distinct from the numbered workspace shortcuts in wm.toml.

The CLI uses aqueous_shell_manager_v1 on Wayland. Its typed commands can activate or close windows, set window states, move windows, activate or rename workspaces, switch keyboard layouts, control overview, reload configuration, and request session exit. See Command-line tools.

Aqueous exports an absolute AQUEOUS_SOCKET path to session children and services before startup. It points to a private per-instance endpoint:

$XDG_RUNTIME_DIR/aqueous/<instance>/ipc.sock

This socket serves capability discovery, snapshots, acknowledged state deltas, and typed commands without launching a process for each action. It shares the compositor’s state and command backend with the Wayland shell protocol.

Use an AF_UNIX stream connection to the inherited path. Each frame is one UTF-8 JSON object followed by LF; reads can split or combine frames. Every connection begins with:

{ "ipc": 1, "id": "1", "op": "hello", "params": {} }

The response includes the session token, schema, capabilities, and resource limits. Every subsequent request includes that returned token as a top-level session field. Request IDs are increasing decimal strings, at most 20 digits; entity IDs and sequence/delivery values also remain strings.

Use one persistent connection for queries and commands and another for subscriptions and acknowledgements. Allow only one outstanding request per connection. The runtime operations are:

Operation Purpose
hello Negotiate capabilities and session identity.
snapshot Read a complete current state batch.
subscribe Receive an initial snapshot followed by state deltas.
ack Acknowledge the exact delivery ID after installing a batch.
command Run a typed action with validated fields.

Install each batch atomically. A snapshot has base_sequence: null; a delta’s base_sequence must match the last installed sequence. Delta upserts replace complete entities. Only one batch is unacknowledged at a time, and subscribed connections accept only acknowledgements after subscribing.

Command status applied means the operation committed. accepted is reserved for close and exit requests; it does not prove a client has terminated. Commands fail explicitly for stale sessions, invalid targets, lock state, unsupported actions, and resource limits. The socket exposes typed runtime actions, not arbitrary command execution or configuration writes.

After disconnect, discard old state and queued mutations, reconnect with bounded backoff, and install a fresh subscription snapshot. Never automatically replay a command sent without a reply: its outcome is unknown. Both connections must agree on session identity before the shell uses their state.

The socket is a same-user desktop interface, with a private directory and peer UID checks. Session tokens detect stale identity; they are not authentication secrets. Use the inherited endpoint and do not expose it to untrusted application sandboxes or discover endpoints by scanning other sessions.

For exact fields, limits, schemas, and recovery rules, use the source IPC v1 contract and Wayland shell contract.

Negotiate icon_metadata and icon_fetch before requesting per-window icons. The read-only window.icon socket operation accepts the current window ID, icon revision, logical size, and scale, and returns bounded base64 PNG data. Use the request connection, not the subscription connection, and compare the reply’s revision against current state before displaying it. Name-only icons can be resolved through the frontend’s icon theme.

The unmanaged_windows capability exposes mapped X11 override-redirect surfaces, including Steam notification bubbles, menus, and tooltips. Socket clients opt in with {"include_unmanaged": true} in snapshot/subscribe parameters. Updated CLI snapshots and watches select the corresponding Wayland subscription automatically. Older/default subscriptions retain managed-only behavior.

Unmanaged records report type, class/title, geometry, owner, output, opacity, and rule effects. They are not taskbar/workspace members or valid targets for managed-window commands. See popup rules.

aqueous-input-activity-v1 provides authorized consumers with keyboard activity, mouse-button activity, or both. It reports fresh physical presses on the default seat, including compositor shortcuts. It does not expose keys, button identities, text, coordinates, timestamps, or counts. Repeats, motion, scrolling, touch, tablets, and virtual devices do not count.

The packaged Pearl service obtains authorization through aqueous-activity-launch on its existing Wayland connection. Same-user socket access alone does not grant activity access. Notifications are bounded and acknowledged; silence does not establish idle state. Activity is not included in general shell snapshots or outputd.sock.

Integration details are in the input-activity contract.

Foreign-toplevel scene capture renders the target window independently of windows covering it. The destination defaults to SDR sRGB/BT.709 primaries, gamma 2.2, and nominal 80 cd/m² white. Supported Vulkan SHM and DMA-BUF paths carry destination-color metadata through aqueous-capture-color-v1.

These are SDR exports, including supported input-color conversion; source HDR metadata is not copied onto converted SDR frames. Pixman reports metadata only for supported SDR inputs and reports unavailable when conversion is required. Consumers must wait for successful frame completion and valid color metadata. Unknown paths remain unavailable. Session lock or window unmapping denies capture. Output warming affects composed output captures, not this isolated source.

See the capture-color contract for format support and export conversion requirements.

Packages include a private namespaced build of xdg-desktop-portal-wlr as xdg-desktop-portal-aqueous. It handles ScreenCast and Screenshot, while GTK handles the remaining portal interfaces. Component desktops route the source chooser through aqueous-shell-action using the active session choice: DMS uses its portal bridge, Noctalia uses its menu, and Pearl/Nothing use the standalone GTK picker supplied by Welcome. Installing another shell alone does not change the active selection. Explicit custom chooser overrides are retained.

DMS sharing uses the independent Aqueous Screen Sharing (aqueousPortal) daemon plugin. It works independently of the retired settings UI and needs no DankBar widget. The bridge waits for discovery and enables this portal plugin on the first request unless it has been explicitly disabled. Re-enable it through DMS Settings → Plugins or:

Terminal window
dms ipc call plugins enable aqueousPortal

Escape, Cancel, or closing the picker produces no selection. A second picker request is rejected while one is active. The chooser does not start another shell or silently select a screen.

Terminal window
journalctl --user -u xdg-desktop-portal-aqueous.service -b
Error Meaning
PluginDisabled The portal plugin was explicitly disabled.
PluginNotReady DMS or the portal plugin did not become ready.
PluginSettingsInvalid DMS plugin settings are malformed.
ChooserBusy Another picker is active.

Backend configuration uses the first readable file, without merging:

  1. $XDG_CONFIG_HOME/xdg-desktop-portal-aqueous/Aqueous
  2. $XDG_CONFIG_HOME/xdg-desktop-portal-aqueous/config
  3. /etc/xdg/xdg-desktop-portal-aqueous/Aqueous
  4. /etc/xdg/xdg-desktop-portal-aqueous/config

XDG_CONFIG_HOME defaults to ~/.config. An existing override can mask the new package’s chooser settings. Review it and any .pacnew file when changing shell variants, then log out and back in to load the backend configuration.

© 2026 Seafoam LabsShelly Chel