Skip to content

Configuration

Configure everything in /var/lib/noctalia-greeter/greeter.toml (Nix: programs.noctalia-greeter.settings, overwritten with tmpfiles C+). Sync and the login UI never write that file.

PathRole
/var/lib/noctalia-greeter/greeter.tomlFull declarative config (scheme, palette, wallpaper, output, cursor, …). Wins over Sync when set
/var/lib/noctalia-greeter/sync.tomlSync + UI mutable (palette, wallpaper refs, session actions, last session/scheme, layout/transforms). Loses to greeter.toml
/var/lib/noctalia-greeter/wallpaper*Sync-installed wallpaper image files

The Synced scheme uses a complete [appearance.palette] from greeter.toml when present, otherwise the same keys from sync.toml. (Legacy live appearance.json is migrated into sync.toml once.)

If greeter.toml is missing, the greeter uses built-in defaults. Setup ensures /var/lib/noctalia-greeter/ exists and is owned by the greetd session user.


When you change session or color scheme on the login screen, the greeter writes sync.toml (unless greeter.toml already pins [appearance].scheme):

KeyPurpose
[session].lastLast Wayland session you picked (by Name from the session picker)
[appearance].schemeLast color scheme you picked

Sync stages a sync.toml fragment (and optional layout/transforms files); apply merges that into live sync.toml.


Set these in greeter.toml. The greeter UI and Sync do not change them. When the same key exists in sync.toml, greeter.toml wins.

KeyPurpose
[session].defaultSession selected when the greeter opens. Overrides last-used [session].last unless you pass --session on the greetd command line.
[user].defaultUsername to select on startup. Opens the password step immediately. --user on the greetd command line wins.
[appearance].schemeColor scheme (Synced, builtin name such as Noctalia, …). Overrides last UI pick in sync.toml.
[appearance].password_stylePassword mask: default or random
[appearance].hide_logoHide the Noctalia brand logo (true / false)
[appearance].theme_modeTheme mode string for Synced look (e.g. dark)
[appearance].corner_radius_scaleCorner radius scale for Synced look
[appearance].font_familyFont family for Synced look
[appearance.palette]Full palette (same keys Sync writes under [appearance.palette]). When complete, wins over Sync for the Synced scheme
[appearance.wallpaper]Default wallpaper path / fill_mode / fill_color
[appearance.wallpapers.<connector>]Per-output wallpaper override
[output].nameWayland connector to pin the greeter on
[output].layoutMulti-monitor positions; overrides Sync layout in sync.toml
[output].width / .heightPreferred DRM mode size
[output].transformsPer-connector DRM transform; overrides Sync transforms
[output].scaleManual UI scale factor
[idle].timeoutSeconds before blanking outputs; 0 disables
[cursor].theme / .size / .pathCursor theme
[keyboard].layout / .variant / .options / .numlockXKB keymap
[auth].allow_empty_passwordEmpty password submit for fprintd/smartcard PAM

Copy to /var/lib/noctalia-greeter/greeter.toml and drop any lines you do not need. Same file in the greeter repo: examples/greeter.toml.

# noctalia-greeter - full greeter.toml example (declarative / Nix-safe)
#
# Install as /var/lib/noctalia-greeter/greeter.toml (owned by the greetd user).
# On NixOS: programs.noctalia-greeter.settings = { ... }; (tmpfiles C+ overwrite)
#
# This file is the full admin config. Sync and the login UI never write it.
# Mutable Sync/UI data lives in sync.toml (lower priority when both set).
# Sync merges palette/wallpaper/session into sync.toml; a complete [appearance.palette] here wins.
#
# Omit any key for the built-in default.
# Docs: https://docs.noctalia.dev/v5/greeter/configuration/
[session]
# Exact Name= from the session .desktop (same as `noctalia-greeter sessions` / the picker).
# Not the .desktop basename — e.g. "Hyprland (uwsm-managed)", not "hyprland-uwsm".
default = "niri"
[user]
# Opens the password step for this account on startup.
default = "lysec"
[appearance]
# Color scheme name: "Synced" (palette below or Sync sync.toml), or a builtin
# like "Noctalia", "Catppuccin", .... Overrides last UI pick in sync.toml when set.
scheme = "Synced"
# Password mask: "default" (filled circles) or "random" (cycled glyph shapes).
password_style = "random"
# Hide the Noctalia brand logo on the login screen.
hide_logo = false
theme_mode = "dark"
corner_radius_scale = 1.0
# Optional; empty / omit keeps the greeter default font.
font_family = "Inter"
# Required for a declarative Synced look (same keys Sync writes under [appearance.palette]).
# When complete, this wins over Sync's sync.toml appearance.
[appearance.palette]
primary = "#fff59b"
on_primary = "#0e0e43"
secondary = "#a9aefe"
on_secondary = "#0e0e43"
tertiary = "#9BFECE"
on_tertiary = "#0e0e43"
error = "#FD4663"
on_error = "#0e0e43"
surface = "#070722"
on_surface = "#f3edf7"
surface_variant = "#11112d"
on_surface_variant = "#7c80b4"
outline = "#21215F"
shadow = "#070722"
hover = "#9BFECE"
on_hover = "#0e0e43"
[appearance.wallpaper]
# Absolute path, or color:#RRGGBB. fill_mode: center | crop | fit | stretch | repeat
path = "/var/lib/noctalia-greeter/wallpaper.webp"
fill_mode = "crop"
# fill_color = "#070722"
# Optional per-connector wallpapers (overrides [appearance.wallpaper] for that output):
# [appearance.wallpapers.DP-1]
# path = "/var/lib/noctalia-greeter/wallpaper-DP-1.webp"
# fill_mode = "crop"
[output]
# Pin the greeter to one connector; omit to mirror on every monitor.
# List names with: noctalia-greeter outputs
name = "DP-2"
# Multi-monitor positions (logical pixels). Overrides Sync layout in sync.toml when set.
layout = "DP-1:0,0; DP-2:2560,0"
# Preferred DRM mode size in pixels (both required if set).
width = 5120
height = 2160
# Per-connector DRM transform. Overrides Sync transforms in sync.toml when set.
# Tokens: normal/0/none, 90, 180, 270, flipped, flipped-90, flipped-180, flipped-270
transforms = "DP-1:normal; DP-2:normal"
# Manual UI scale; omit or invalid -> auto from display geometry.
scale = 1.5
[idle]
# Seconds with no input before blanking outputs; 0 disables (range 0-86400).
timeout = 300
[cursor]
theme = "Adwaita"
size = 24
# Colon-separated search path when the theme is not under the default icon dirs.
path = "/usr/share/icons"
[keyboard]
# Comma-separated for multiple layouts.
layout = "us,cz"
variant = ",qwertz"
options = "grp:alt_shift_toggle"
# Start with Num Lock locked (default true if omitted).
numlock = true
[auth]
# Allow empty password submit (fprintd / smartcard PAM). Default false.
allow_empty_password = false

The greeter runs inside the bundled wlroots compositor (noctalia-greeter-compositor). By default it shows the same login UI on every connected monitor, with each display sized to its own resolution and scale.

To pin the greeter to a single connector:

[output]
name = "DP-2"

When [output].name is set, the compositor disables the other connectors at the KMS level. If it is missing, empty, or names a disconnected connector, the greeter falls back to showing on all outputs.

On multiple monitors, cursor movement follows [output].layout. Without it, the greeter places outputs left-to-right by connector name, which often does not match your desk.

Sync from Noctalia: When you use Settings → Security → Noctalia Greeter → Sync Now, Noctalia copies monitor positions from your desktop compositor (via xdg-output) into [output].layout, and copies each connector’s output transform into [output].transforms. Sync skips layout when only one monitor is connected, xdg-output is unavailable, outputs are still enumerating, or all monitors report the same origin. Transforms sync whenever at least one ready output is available (including a single portrait panel).

Set positions manually if needed:

[output]
layout = "DP-1:0,0; DP-2:2560,0"

Coordinates are logical pixels from your desktop compositor. The greeter compositor uses them for order and row grouping, then places outputs edge-to-edge using its own output scale (so cursor movement stays continuous).

List connector names from a running Wayland session:

Terminal window
noctalia-greeter outputs

Restart greetd after changing [output].name or [output].width / [output].height:

Terminal window
sudo systemctl restart greetd

By default the greeter compositor modesets each connector using the EDID preferred resolution, then the highest refresh rate available at that size. On some setups that mode differs from your desktop session (resolution and/or refresh), so login flashes or modesets when the session starts.

To pin the greeter to a specific resolution, set both [output].width and [output].height:

[output]
name = "DP-2"
width = 5120
height = 2160

When both values are set, the compositor uses that size and still picks the highest-refresh advertised mode for it. If no mode of that size is advertised, it logs a warning and falls back to the preferred-resolution path above.

Both keys are required. If only one is set, the greeter ignores the partial override and uses the preferred-resolution path. Invalid (non-positive) values are also ignored.

Match these values to the mode your desktop session uses if you want a seamless greeter → session transition.


Portrait panels often need a DRM transform so the greeter UI is upright. Set [output].transforms to a semicolon-separated list of CONNECTOR:TOKEN entries:

[output]
# optional: pin greeter to the portrait panel only
# name = "HDMI-A-1"
transforms = "HDMI-A-1:270"

Supported tokens: normal / 0 / none, 90, 180, 270, flipped, flipped-90, flipped-180, flipped-270.

Multiple connectors:

[output]
transforms = "DP-1:normal; HDMI-A-1:90"

Noctalia Sync Now also writes [output].transforms into sync.toml from your desktop compositor’s reported output transforms (including normal). Setting [output].transforms in greeter.toml (or via your Nix module) overrides Sync. Restart greetd after changes:

Terminal window
sudo systemctl restart greetd

List connector names from a running Wayland session:

Terminal window
noctalia-greeter outputs

Settings → Security → Noctalia Greeter → Sync Now installs wallpaper image files under /var/lib/noctalia-greeter/ and merges wallpaper references into sync.toml (not into declarative greeter.toml).

With a current Noctalia shell and greeter:

On disk / in configPurpose
wallpaper / wallpaper.<ext> + [appearance.wallpaper] in sync.tomlDefault single image (always written by Sync as a fallback)
wallpaper-<connector>.* + [appearance.wallpapers.<connector>] in sync.tomlPer-connector map (DP-2, HDMI-A-1, …)

Each greeter view picks the image for its bound connector name. If that connector has no entry, it uses the single [appearance.wallpaper] fallback.

If you pin the greeter with [output].name = "DP-2", you see the DP-2 wallpaper when that map entry exists (and only that connector is shown).

You do not need extra greeter.toml keys for Sync wallpapers — only Sync Now (and optional pin as above). To set wallpapers declaratively instead of (or on top of) Sync, use the same keys in greeter.toml:

[appearance.wallpaper]
path = "/var/lib/noctalia-greeter/wallpaper.webp"
fill_mode = "crop"
[appearance.wallpapers.DP-2]
path = "/var/lib/noctalia-greeter/wallpaper-DP-2.webp"
fill_mode = "crop"

When greeter.toml provides a complete [appearance.palette] (declarative Synced look), that whole appearance — including wallpaper keys — is used and Sync’s sync.toml appearance is not. Set wallpaper tables in greeter.toml in that case, or omit the complete palette so Sync’s wallpapers apply.

Legacy live appearance.json is migrated into sync.toml once if present; Sync no longer leaves a live appearance.json as the source of truth.


By default the greeter never blanks the screen. To turn off active DRM outputs after a period with no input, set [idle].timeout in seconds:

[idle]
timeout = 300

0 or omitting the key disables blanking. Valid values are 0-86400 (24 hours).

While blanked, the greeter client stays running. Any key press, mouse button press, or touch wakes the displays and restarts the idle timer. Pointer motion and scroll only wake a blanked screen - they do not reset the timer while the screen is on (wireless mice often emit motion noise that would otherwise prevent blanking).

Optional environment override (wins when set), useful because greetd starts greeters with an empty environment. Put it on the greetd session command (not only as a bare shell assignment):

[default_session]
command = "env NOCTALIA_GREETER_IDLE_TIMEOUT=300 /usr/bin/noctalia-greeter-session"

On NixOS, set the same value through the module (it is written into greeter.toml; the module does not wrap the greetd command with NOCTALIA_GREETER_IDLE_TIMEOUT):

programs.noctalia-greeter.settings = {
idle.timeout = 300;
};

Restart greetd after changing the timeout:

Terminal window
sudo systemctl restart greetd

On high-DPI panels (for example 4K without fractional scaling), the compositor scales output from the monitor’s physical size when EDID reports it, otherwise from resolution. Scale uses the selected DRM mode size (not the pre-modeset wlr_output size), so cold boot and post-logout match. Scale is capped at 2×. The greeter client lays out at logical size and renders HiDPI buffers via Wayland fractional scale.

To override auto scaling, set [output].scale:

[output]
scale = 1.5

If [output].scale is missing or invalid (not a positive number), the compositor falls back to auto scaling.


The compositor resolves the cursor theme, size, and search path in this order:

  1. [cursor].theme / [cursor].size / [cursor].path in greeter.toml
  2. The XCURSOR_THEME, XCURSOR_SIZE, and XCURSOR_PATH environment variables
  3. The wlroots defaults (built-in cursor at size 24)

Set the keys in greeter.toml:

[cursor]
theme = "Adwaita"
size = 24

If the theme is not under the default search path (~/.icons:/usr/share/icons:/usr/share/pixmaps), also set [cursor].path to the directory that contains it:

[cursor]
path = "/usr/share/icons"

greetd starts greeters with an empty environment, so the XCURSOR_* variables must be set in the greetd session command rather than the service environment, for example in /etc/greetd/config.toml:

[default_session]
command = "env XCURSOR_THEME=Adwaita XCURSOR_SIZE=24 /usr/bin/noctalia-greeter-session"

The module option programs.noctalia-greeter.settings writes /var/lib/noctalia-greeter/greeter.toml (Nix attrset, TOML string, or path). Cursor keys become [cursor] in that file. The module does not inject XCURSOR_* into the greetd session command and there is no package option. Point path at the theme package’s share/icons instead:

programs.noctalia-greeter.settings = {
cursor = {
theme = "Bibata-Modern-Ice";
size = 24;
path = "${pkgs.bibata-cursors}/share/icons";
};
};
KeyWritten to
theme[cursor].theme
size[cursor].size
path[cursor].path (compositor sets XCURSOR_PATH from this)

Prefer settings.cursor over wrapping the greetd command with env XCURSOR_* when using the module.


The compositor loads the XKB keymap in this order:

  1. [keyboard].layout / [keyboard].variant / [keyboard].options in greeter.toml
  2. The XKB_DEFAULT_LAYOUT, XKB_DEFAULT_VARIANT, and XKB_DEFAULT_OPTIONS environment variables
  3. The system default keymap

Example for Czech QWERTZ:

[keyboard]
layout = "cz"

Multiple layouts (cycle with [keyboard].options, e.g. grp:alt_shift_toggle):

[keyboard]
layout = "us,cz"
options = "grp:alt_shift_toggle"

Use standard XKB layout codes (de, fr, ru, …). List layouts on your system with localectl list-x11-keymap-layouts or check /usr/share/X11/xkb/rules/base.lst.

The compositor locks Num Lock on startup so numeric keypads work without extra setup. If your keyboard misbehaves with Num Lock enabled (for example, the 0 digit key producing incorrect characters), disable it:

[keyboard]
numlock = false

The default is true (Num Lock locked). This setting has no effect when Num Lock is not available on the keymap.

greetd starts greeters with an empty environment, so set layout in greeter.toml or prefix the greetd session command:

[default_session]
command = "env XKB_DEFAULT_LAYOUT=cz /usr/bin/noctalia-greeter-session"

Terminal window
noctalia-greeter sessions # list Name= values for [session].default / --session (not .desktop basenames)
noctalia-greeter outputs # list Wayland connector names for [output].name

Sessions come from wayland-sessions .desktop files under /usr/share, each path in XDG_DATA_DIRS, and on NixOS /run/current-system/sw/share. Matching uses each entry’s Name= field (case-insensitive), which is what the picker displays — not the file stem such as hyprland-uwsm.desktop.