Integration

Bars and panels via wlr-layer-shell, the atlas-submap / atlas-plane waybar modules, and scripting atlaswm over IPC with atlasctl.

atlaswm plays with the standard Wayland ecosystem. Bars, panels and launchers anchor via wlr-layer-shell; everything stateful is queryable and streamable over a JSON IPC socket, so a bar or script always knows what the compositor is doing.

Bars and panels (wlr-layer-shell)

atlaswm implements wlr-layer-shell (zwlr_layer_shell_v1), so bars, panels and launchers — waybar, eww, fuzzel, wofi, … — anchor to a monitor edge, reserve space (exclusive zones shrink the tiling area so windows don't sit under the bar), draw in the right z-order, and take pointer/keyboard input. Layer surfaces belong to the output, not the plane, so a bar never pans or zooms with the canvas.

Launch your bar and wallpaper at session start with spawn-at-startup:

spawn-at-startup "waybar"
spawn-at-startup "swaybg" "-i" "/path/to/wallpaper.png"

Wallpaper: use swaybg (or any layer-shell wallpaper tool). hyprpaper needs Hyprland's IPC and won't work here.

waybar

waybar's built-in modules (clock, network, pulseaudio, tray, battery, …) work as-is. The Hyprland-specific modules (hyprland/workspaces, hyprland/submap, hyprland/window) don't — they need Hyprland's IPC. The repo ships replacements in contrib/waybar/ that use atlaswm's own IPC.

atlas-submap — active submap indicator

Shows which modal submap is active (resize / planes / pan / …) so you never get stuck in one unaware — filling the gap left by the disabled hyprland/submap. Blank when no submap is active. It's event-driven via atlasctl subscribe (no polling, reconnects if atlaswm restarts).

Requirements: atlasctl on PATH and jq. Copy the script somewhere executable and add a continuous custom module — note: no interval, it streams:

"custom/atlas-submap": {
    "exec": "/home/you/.config/waybar/atlas-submap",
    "return-type": "json"
}

Put "custom/atlas-submap" in a modules-* list (e.g. modules-left, where hyprland/submap used to be). Optional style.css:

#custom-atlas-submap.active { color: @peach; font-weight: bold; }

atlas-plane — plane indicator

Renders the whole plane pool (e.g. 0 1 2 3) and highlights the plane the monitor is currently showing — a workspace indicator for planes. Also event-driven. With no argument it follows the active monitor's plane (right for a single shared bar); pass a connector name (atlas-plane DP-1) and run one bar per output for per-monitor indicators.

"custom/atlas-plane": {
    "exec": "/home/you/.config/waybar/atlas-plane",
    "return-type": "json"
}

Both scripts have full setup notes in contrib/waybar/README.md.

IPC: atlasctl

The compositor listens on a Unix socket (newline-delimited JSON, one object per line) and exports the full path as ATLASWM_SOCKET to everything it spawns — so atlasctl just works from any terminal inside the session, and from outside after export ATLASWM_SOCKET=…. Three verbs:

atlasctl action submap:resize   # dispatch any bindable action string
atlasctl query windows | jq     # one-shot query
atlasctl subscribe              # stream events, one JSON object per line

action

Takes the same vocabulary as config binds — anything bindable is invocable. atlasctl action tag-toggle:work, atlasctl action plane-switch:3, atlasctl action overview-toggle, etc. This is how you script the compositor or wire it to external tools.

query

One-shot state. Available queries:

windows  focused  viewport  submap  mod  planes  tags
gather   summon   overview  anchors marks version

atlasctl query windows | jq gives you each window with its id, app_id, title, plane, tags, and float/fullscreen flags — enough to group, count or target windows from a script.

subscribe

A live event stream. Its first line is always a snapshot of the current state ({"event":"snapshot","submap":null,"mod":"super","focused":3,"active_plane":0,…}), so a bar starts correct with no query-then-subscribe dance. After that, events stream as they happen:

eventpayload
submap{"state":"enter","name":"resize"} / {"state":"exit"}
focus{"id":3} / {"id":null}
window{"id":3,"change":…}mapped, closed, float-on/-off, fullscreen-on/-off
plane{"change":…,"id":N}switch, created, closed
tag{"id":N,"tag":"work","change":…}added, removed
gather{"tag":"work","change":…}enter, dismiss
summon{"tag":"comms","change":…}enter, dismiss
overview{"change":…}enter, exit
config{"change":"reloaded"}

No client can hurt the session: a subscriber that stops reading is disconnected, a garbage line gets an {"error":…} reply on a still-open connection, and the compositor never blocks on IPC. Exit codes: 0 ok, 1 error response from the compositor, 2 usage / connection error.

atlasctl default-config prints the annotated default config — pipe it into ~/.config/atlaswm/config.kdl to start from a documented baseline.

Diagnostics: the action trace

When something behaves oddly, turn on the trace and reproduce it:

debug { trace #true }

Every bind (with its submap context), resize outcome, grab, submap enter/exit, window map/close and config reload is appended to ~/.local/state/atlaswm/trace.log (fresh per session). It's the fastest way to see what action a key actually fired and what it targeted — share the file when reporting a bug.