Troubleshooting
NVIDIA EGL/dmabuf, cursor theme, nested-under-Hyprland quirks, screen sharing and the portal env, spawn latency — the things that bite first.
On this page
Practical fixes for the things that actually come up. When in doubt, read the
session log first: a real session redirects stderr to
$XDG_STATE_HOME/atlaswm/session.log (~/.local/state/atlaswm/session.log,
plus .old for the previous run). Turn on debug { trace #true } for an action
trace when a keybind misbehaves.
NVIDIA
atlaswm's DRM backend is developed and daily-driven on a GeForce RTX 3080
(Ampere) on the nvidia-open open kernel modules — that path works on that exact
card. A few things to know:
EGL is provided by the system driver. NVIDIA's EGL comes from
/run/opengl-driver (the NixOS driver path) via GLVND; the session needs no
nixGL wrapping. nvidia-drm.modeset=1 must be set — it already is if you run
any Wayland compositor today.
dmabuf + explicit sync go together. atlaswm advertises
zwp_linux_dmabuf_v1 together with wp_linux_drm_syncobj_manager_v1
(explicit sync). On NVIDIA these are a pair: NVIDIA's egl-wayland reads its render
device from the dmabuf global and then takes the dmabuf + explicit-sync path —
advertising dmabuf without explicit sync makes NVIDIA client EGL init fail with
EGL_BAD_ALLOC / "failed to allocate resources", and GL clients (kitty, …) won't
spawn. atlaswm ships both, so this is handled; it's listed here because if you
ever see those EGL allocation errors in session.log, this is the area to look
at.
Benign warnings. MESA-LOADER / libEGL … fd -1 warnings are Mesa's loader
probing and failing before NVIDIA's EGL succeeds — they're noise, not a failure.
The Unable to become drm master warning under logind is also benign (it only
gates VT-switch master handoff; a modern kernel grants modeset).
A hard GPU freeze is usually a firmware fault, not atlaswm. A frozen screen
that needs a reboot on this hardware has been an NVIDIA GPU firmware fault (Xid 62
GSP/PMU halt), not a compositor bug. atlaswm has GPU-hang resilience: a sustained
render failure drops you cleanly back to your greeter within ~5 s (with a clear
session.log error) instead of holding a silently-broken frozen session. It
can't un-wedge the GPU — that needs a reboot — but you won't sit on a black
screen wondering.
Cursor looks like a plain X arrow
The DRM backend draws its own cursor and loads the XCursor theme from
XCURSOR_THEME / XCURSOR_SIZE. If you get the default arrow, set those env
vars to your theme (e.g. a catppuccin cursor) in your session environment. (The
nested backend lets the host draw the cursor, so this only affects the real
session.)
Nested under Hyprland (and other hosts)
Running nested is the dev path, with a couple of quirks:
Modis Alt nested.mod "auto"resolves to Alt while nested so it never fights the host's Super binds. If a bind seems dead, check whether the host compositor grabbed that chord first.- Some host binds win. A chord the host compositor has bound globally may never reach atlaswm. Pick binds the host doesn't use, or test the conflicting ones in a real session.
- Keyboard layout. Nested follows
XKB_DEFAULT_LAYOUTuntil you setinput { xkb-layout "fr" }in the config. Don't test azerty binds with bare qwerty assumptions.
Screen sharing
atlaswm captures the screen via wlr-screencopy (shm and dmabuf zero-copy paths, cursor exclusion honored). For the desktop-portal flow (Google Meet, Discord, OBS PipeWire capture), it rides xdg-desktop-portal-wlr (xdpw), which does the D-Bus portal, the picker and the PipeWire stream.
Install and route xdpw (NixOS):
xdg.portal.wlr.enable = true;
xdg.portal.config.atlaswm."org.freedesktop.impl.portal.ScreenCast" = [ "wlr" ];
The activation-environment gotcha. xdg-desktop-portal is started by
D-Bus/systemd with its own environment. For the portal to route ScreenCast to the
wlr backend it must see XDG_CURRENT_DESKTOP=atlaswm in that environment — and on
a real session atlaswm pushes it there (dbus-update-activation-environment),
exactly like sway/Hyprland sessions do. If a share still fails with
"must be authorized to share your screen" even after you allow it, the
ScreenCast interface probably wasn't exposed because that env wasn't set — make
sure you're on a freshly-rebuilt session (a stale running compositor from before
a rebuild is the usual culprit; relogin, or reboot if relogin doesn't kill it).
Two monitors. Full-monitor capture works; the portal picker (a slurp/dmenu
chooser via xdpw) selects which monitor.
If xdpw won't start with Compositor supports neither ext_image_copy_capture or wlr_screencopy!, it needs both zwlr_screencopy_manager_v1 and
zwp_linux_dmabuf_v1 — atlaswm advertises both, so this points at an old binary;
clear the systemd failure with systemctl --user reset-failed xdg-desktop-portal-wlr and relogin into the current build.
Self-driven tools confirm the path independently: grim (full-output and
-g "x,y wxh" region), grim -o DP-1 (one monitor), and wf-recorder all
capture correctly oriented frames.
GL clients are slow to spawn
A noticeable delay opening each GL client (a terminal, a browser) on NVIDIA is the Mesa EGL probe failing before NVIDIA's EGL succeeds (~300 ms/client). It's cosmetic — the client does start. (A glvnd pin that skips the Mesa probe was tried and reverted because it broke EGL after a bundled rebuild; it's a known trade-off, not a bug to fix in the config.)
A config change didn't apply
Config is live-reloaded within a second of saving — if it parses. A typo, an
unknown verb or a broken regex makes the whole reload fail, the error is logged,
and the previous config keeps running. So if a change seems ignored, check
session.log (or run atlasctl default-config to confirm exact syntax) — you've
probably got a parse error keeping the last-good config alive. Fix and save to
re-apply.
XWayland app issues
atlaswm runs X11 apps (Steam, Discord, older toolkits) via XWayland — no extra
setup. echo $DISPLAY in a terminal should print :N. Tiled X11 windows ignore
client-side move/resize (the layout owns tiled geometry, same as Wayland);
float them (Mod+space or a float #true rule) to drag/resize freely.
Override-redirect surfaces (some menus/tooltips) are best-effort positioned when
the plane is panned/zoomed.