Integration
Bars and panels via wlr-layer-shell, the atlas-submap / atlas-plane waybar modules, and scripting atlaswm over IPC with atlasctl.
On this page
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).hyprpaperneeds 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:
| event | payload |
|---|---|
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.