Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

IPC

The compositor listens on a Unix socket, $XDG_RUNTIME_DIR/atrium.<DISPLAY>.<PID>.sock, exported as $ATRIUM_SOCKET. The protocol is JSON, one message per line: send a Request, get a Reply; request EventStream to receive Event messages for as long as the connection lives. It is niri’s protocol with Atrium’s workspace and layout state added.

atrium msg

atrium msg workspaces          # every workspace with its layout state
atrium msg windows
atrium msg outputs
atrium msg focused-window
atrium msg pick-window         # click a window, print its details
atrium msg event-stream        # follow events
atrium msg action focus-workspace 3
atrium msg action close-window
atrium msg action --help       # every bindable action
atrium msg -j workspaces       # JSON

Subcommands: outputs, workspaces, windows, layers, keyboard-layouts, focused-output, focused-window, pick-window, pick-color, action, output, event-stream, version, overview-state, casts.

Workspace fields

{
  "id": 3, "idx": 3, "name": "3", "output": "HDMI-A-1",
  "label": "Terminal", "icon": "/usr/share/atrium/icons/heroicons/o-command-line.svg",
  "show_label": true, "show_icon": true,
  "is_active": true, "is_focused": true, "is_urgent": false,
  "active_window_id": 42,
  "layout": "master-stack", "master_ratio": 0.55, "master_count": 1, "flipped": false
}

Windows carry is_iconified alongside the usual id, title, app id, workspace, and focus fields.

Events

A consumer connects, receives a full snapshot (workspaces, windows, layout), then a stream of changes: WorkspacesChanged, WorkspaceActivated, WindowOpenedOrChanged, WindowClosed, WindowFocusChanged, WindowUrgencyChanged, KeyboardLayoutsChanged, CastStartedOrChanged, and the rest. Consumers filter client-side. A layout change (algorithm, ratio, flip) emits WorkspacesChanged.

The consumer pattern

atrium-shell’s Services/AtriumIpc.qml is the reference consumer: it runs atrium msg -j event-stream as a child process, restarts it if it exits, and on any event debounces into one authoritative re-pull of atrium msg -j workspaces rather than modelling each event. Bars written for other compositors adapt the same way: a process reading the stream, a full re-query on change.

Screencast requests

Request::StartCast creates a PipeWire stream for an output or window and answers with session and stream ids; CastStartedOrChanged then carries the pw_node_id. This is how atrium-portal hands a node to xdg-desktop-portal without any Mutter-compatible D-Bus surface.