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

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:

  1. XDG_RUNTIME_DIR fallback. 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.
  2. D-Bus session bus. If DBUS_SESSION_BUS_ADDRESS is missing (a raw TTY login), it re-executes itself under dbus-run-session.
  3. Activation environment. dbus-update-activation-environment --all pushes the base environment to D-Bus before the compositor starts; the compositor pushes WAYLAND_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:

VariableSource
XDG_CURRENT_DESKTOP=atrium, XDG_SESSION_TYPE=waylandfixed
WAYLAND_DISPLAY, ATRIUM_SOCKET, DISPLAYafter socket creation
GBM_BACKEND=nvidia-drm, __NV_PRIME_RENDER_OFFLOAD=1, __GLX_VENDOR_LIBRARY_NAME=nvidiaauto-detected when the NVIDIA driver is bound
XCURSOR_THEME, XCURSOR_SIZEfrom 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 to atrium.log.1 through atrium.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.