The session
How a login becomes a running compositor, and where environment variables come from.
Login chain
runit → greetd (VT7) → tuigreet → PAM → atrium-session → atrium --session
greetd starts as a runit service and shows tuigreet. After PAM authenticates, pam_rundir creates /run/user/$UID, and greetd runs the session command from /usr/share/wayland-sessions/atrium.desktop, which is atrium-session.
atrium-session is a short #!/bin/sh wrapper with three jobs:
XDG_RUNTIME_DIRfallback. pam_rundir exports the variable only for the first session of a user. A second login (a TTY already open, or a re-login after the compositor exited) inherits nothing, and the Wayland socket bind fails. The wrapper sets/run/user/$(id -u)when the variable is empty.- D-Bus session bus. If
DBUS_SESSION_BUS_ADDRESSis missing (a raw TTY login), it re-executes itself underdbus-run-session. - Activation environment.
dbus-update-activation-environment --allpushes the base environment to D-Bus before the compositor starts; the compositor pushesWAYLAND_DISPLAY,DISPLAY, and the GPU variables after the socket exists, so portals and D-Bus-activated services find the session.
Then exec atrium --session. There is no login-shell re-exec: the compositor and the programs it spawns do not get your shell’s PATH, so spawn-at-startup entries use full paths for anything in ~/.local/bin.
atrium-session-debug (the “Atrium (debug)” greeter entry) is the same script with -d, raising the log level.
What the compositor sets
With --session, the compositor exports these itself:
| Variable | Source |
|---|---|
XDG_CURRENT_DESKTOP=atrium, XDG_SESSION_TYPE=wayland | fixed |
WAYLAND_DISPLAY, ATRIUM_SOCKET, DISPLAY | after socket creation |
GBM_BACKEND=nvidia-drm, __NV_PRIME_RENDER_OFFLOAD=1, __GLX_VENDOR_LIBRARY_NAME=nvidia | auto-detected when the NVIDIA driver is bound |
XCURSOR_THEME, XCURSOR_SIZE | from the cursor config |
What you set: the environment block
Anything a compositor-spawned program needs goes in config.kdl:
environment {
GTK_THEME "Arc-Dark"
QT_QPA_PLATFORMTHEME "gtk3"
_JAVA_AWT_WM_NONREPARENTING "1"
}
The block applies to every process the compositor launches: spawn-at-startup entries, the shell, the launcher, and anything the launcher spawns. It takes effect at the next login; a live reload only reaches processes spawned after it.
Shell rc files (.zshenv, .bashrc) do not reach these programs. A variable set only there appears to work from a terminal and is silently absent for the same program started from the bar. The usual tell is Java menus mispositioned when a Swing or JavaFX app is launched from the launcher.
Logs
~/.local/state/atrium/atrium.log: the compositor log, always written at info level; the previous five sessions rotate toatrium.log.1throughatrium.log.5. Panics land here with a backtrace.~/.local/state/atrium/atrium-portal.log: the portal’s log.- Compositor stderr goes to the greeter’s VT and is effectively lost; the file is the durable record.