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.
Discover live capabilities
Section titled “Discover live capabilities”aqueousctl shell capabilities --jsonaqueousctl shell snapshot --jsonaqueousctl shell watch --jsonCapabilities 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.
Persistent socket IPC
Section titled “Persistent socket IPC”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.sockThis 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.
Connect and negotiate
Section titled “Connect and negotiate”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. |
State, completion, and recovery
Section titled “State, completion, and recovery”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.
Window icons and unmanaged surfaces
Section titled “Window icons and unmanaged surfaces”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.
Input activity
Section titled “Input activity”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.
Isolated window capture
Section titled “Isolated window capture”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.
Screen sharing and portals
Section titled “Screen sharing and portals”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:
dms ipc call plugins enable aqueousPortalEscape, 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.
Troubleshooting the picker
Section titled “Troubleshooting the picker”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:
$XDG_CONFIG_HOME/xdg-desktop-portal-aqueous/Aqueous$XDG_CONFIG_HOME/xdg-desktop-portal-aqueous/config/etc/xdg/xdg-desktop-portal-aqueous/Aqueous/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.
