A minimal login greeter for greetd that matches the look and feel of Noctalia Shell.
Noctalia Greeter is the screen you see before your desktop session starts. It lets you pick a user, enter your password, choose a Wayland session, and pick a color scheme - with the same visual language as Noctalia Shell.
It is built for greetd: greetd starts the bundled wlroots compositor (noctalia-greeter-compositor), and the greeter runs inside that session.
Pair it with Noctalia v5 if you want wallpaper and palette synced from the shell settings (optional).
Install everything below on the machine where greetd will run. Each list covers build tools and libraries, plus greetd and D-Bus (used by noctalia-greeter-session). You still need your desktop sessions separately (niri, Hyprland, and so on).
sudo pacman -S meson gcc just \
greetd dbus \
wayland wayland-protocols wlroots0.20 \
libglvnd freetype2 fontconfig \
cairo pango harfbuzz \
libxkbcommon glib2 \
libwebp librsvgsudo dnf install meson gcc-c++ just \
greetd dbus \
wayland-devel wayland-protocols-devel wlroots-devel \
libEGL-devel mesa-libGLES-devel \
freetype-devel fontconfig-devel \
cairo-devel pango-devel harfbuzz-devel \
libxkbcommon-devel glib2-devel \
libwebp-devel librsvg2-develsudo apt install meson g++ just \
greetd dbus \
libwayland-dev wayland-protocols libwlroots-0.20-dev \
libegl-dev libgles-dev \
libfreetype-dev libfontconfig-dev \
libcairo2-dev libpango1.0-dev libharfbuzz-dev \
libxkbcommon-dev libglib2.0-dev \
libwebp-dev librsvg2-devsudo xbps-install meson ninja pkg-config git \
greetd dbus \
wayland-devel wayland-protocols wlroots-devel libepoxy-devel \
MesaLib-devel libglvnd-devel cairo-devel \
pango-devel fontconfig-devel freetype-devel harfbuzz-devel \
libxkbcommon-devel libwebp-devel librsvg-develVendored dependencies, with no system package needed: nlohmann/json, stb, and Wuffs.
Build requires wlroots-0.20 and wayland-server development packages (see distro lists above).
libwebp handles WebP wallpapers when syncing appearance from the shell. Wuffs handles other raster image formats.
On Void Linux, libepoxy-devel is used when EGL/GLES pkg-config modules are not available.
A flake and NixOS module are provided.
Add the input to your flake.nix:
inputs = {
noctalia-greeter = {
url = "github:noctalia-dev/noctalia-greeter";
inputs.nixpkgs.follows = "nixpkgs";
};
};Import the module and enable the greeter in your configuration:
imports = [
inputs.noctalia-greeter.nixosModules.default
];
programs.noctalia-greeter = {
enable = true;
package = inputs.noctalia-greeter.packages.${pkgs.stdenv.hostPlatform.system}.default;
# Optional configuration
greeter-args = "";
settings = {
cursor = {
theme = "Adwaita";
size = 24;
};
keyboard = {
layout = "us";
};
};
};The module enables greetd and sets the session command automatically.
greeter-args passes extra flags to noctalia-greeter-session, for example
--session <name> to set a default session. Run noctalia-greeter sessions
to list valid names.
settings accepts a Nix attrset, a raw TOML string, or a path to a .toml file,
and is copied to /var/lib/noctalia-greeter/greeter.toml on boot.
just configure-release
just build-release
sudo meson install -C build-release
sudo ./scripts/setup_greeter_system.shPass a prefix when configuring to install somewhere other than /usr/local:
meson setup build-release --prefix="$HOME/.local" --buildtype=release --reconfigure
just build-release
sudo meson install -C build-release
sudo ./scripts/setup_greeter_system.shjust build
sudo just installjust install runs the same system setup scripts after Meson install.
Meson installs the greeter binary, session launcher and assets. With the default prefix that is under /usr/local; distro packages (e.g. AUR) usually install to /usr/bin instead.
<prefix>/bin/noctalia-greeter
<prefix>/bin/noctalia-greeter-compositor
<prefix>/bin/noctalia-greeter-session
<prefix>/bin/noctalia-greeter-apply-appearance
<prefix>/share/noctalia-greeter/assets/...
The greeter needs the shipped assets/ tree at runtime. Copying only the noctalia-greeter binary is not enough.
Point greetd at the installed session wrapper. Use the path on your system — do not assume /usr/local if you installed from a package:
which noctalia-greeter-sessionExample for a manual install to /usr/local (replace the path if which shows something else, e.g. /usr/bin/noctalia-greeter-session):
[default_session]
command = "/usr/local/bin/noctalia-greeter-session"
user = "greeter"Use the user value that matches your greetd config. setup_greeter_system.sh prints a ready-to-paste config.toml block with the path it finds. It also prepares /var/lib/noctalia-greeter/ for that account.
Optional default session (must match a name from the session picker, e.g. niri):
command = "/usr/bin/noctalia-greeter-session -- --session niri"List valid session names:
noctalia-greeter sessionsSessions come from wayland-sessions .desktop files under /usr/share, each path in XDG_DATA_DIRS, and on NixOS /run/current-system/sw/share.
By default the greeter is mirrored on every connected monitor (same UI on each display, sized to the primary output). To pin it to a single connector, set [output].name in /var/lib/noctalia-greeter/greeter.toml:
[output]
name = "DP-2"The compositor disables the other connectors at the KMS level when [output].name is set. If it names a disconnected connector, the greeter falls back to mirroring on all outputs.
When using multiple monitors, set [output].layout manually or sync from Noctalia Shell (see Matching Noctalia Shell). Without it, outputs are placed left-to-right by connector name. List connector names with noctalia-greeter outputs:
[output]
layout = "DP-1:0,0; HDMI-A-1:1920,0; DP-2:3840,0"Coordinates are logical pixels from your desktop compositor. The greeter uses them for order and row grouping, then places outputs edge-to-edge at its own scale so the cursor can move between monitors.
Test locally with:
just runOn high-DPI panels (for example 4K), the greeter compositor applies fractional output scaling from the monitor's physical size when EDID reports it, otherwise from resolution. 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 in greeter.toml (read by the compositor):
[output]
scale = 1.5If [output].scale is missing or invalid, the compositor falls back to auto scaling.
List connector names from a running Wayland session:
noctalia-greeter outputsRestart greetd:
sudo systemctl restart greetdOn runit:
sudo sv restart greetdCreate log files once if needed:
just setup-log-dirLogs: /var/log/noctalia-greeter.log and /var/lib/noctalia-greeter/greeter.log.
With Noctalia v5 installed, open Settings → Shell → Security → Noctalia Greeter → Sync Now. The shell copies your wallpaper, palette, and multi-monitor layout (when available) to the greeter (you may be prompted for admin credentials). After syncing, log out or restart greetd to see the changes on the login screen.
The greeter adds a Synced color scheme when sync data is present. Session and scheme choices you make on the login screen are remembered in /var/lib/noctalia-greeter/greeter.toml.
Admin-only settings in greeter.toml (set by you, not the UI):
[session].default- session selected when the greeter opens (overrides last-used unless you pass--sessionon the command line)[user].default- username to select on startup; opens the password step immediately (--useron the command line wins)[output].name- Wayland connector name (see Multi-monitor)[output].layout- multi-monitor positions asNAME:X,Y; ...in logical pixels (see Multi-monitor)[output].scale- manual compositor scale factor (e.g.1.5); invalid or missing → auto scale[cursor].theme- cursor theme name (e.g.Adwaita); missing → wlroots default cursor[cursor].size- cursor size in pixels (e.g.24); missing →24[cursor].path- colon-separated theme search path (setsXCURSOR_PATH)[keyboard].layout/.variant/.options- XKB keymap (compositor)[appearance].password_style- password mask style:default(filled circles) orrandom(cycled glyph shapes, same as Noctalia shell)
The greeter updates [session].last and [appearance].scheme when you change them in the UI.
The compositor resolves the cursor theme, size and search path in this order:
[cursor].theme/[cursor].size/[cursor].pathingreeter.toml(above)- The
XCURSOR_THEME,XCURSOR_SIZEandXCURSOR_PATHenvironment variables - The wlroots defaults (built-in cursor at size
24)
greetd starts greeters with an empty environment, so to use the environment
variables set them 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"If the theme is not under the default search path, also set
XCURSOR_PATH (or cursor.path) to the directory that contains it.
The greeter works without a mouse.
The compositor builds an XKB keymap in this precedence order:
greeter.toml:[keyboard].layout/.variant/.optionsXKB_DEFAULT_LAYOUT/XKB_DEFAULT_VARIANT/XKB_DEFAULT_OPTIONS(environment)- The system default keymap
Example:
[keyboard]
layout = "cz"Multiple layouts:
[keyboard]
layout = "us,cz"
options = "grp:alt_shift_toggle"Use standard XKB layout codes (de, fr, ru, …).
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"| Key | Action |
|---|---|
Tab / Shift+Tab |
Move focus |
↑ / ↓ |
Move focus, or move in an open menu |
Enter |
Submit password / activate / confirm menu |
Space |
Activate focused control |
Esc |
Close menu or leave password step |
F3 |
Session picker |
F7 |
Color scheme picker |
Ctrl+Alt+F1–F12 |
Switch to virtual terminal (TTY) |
- Blank screen - Check
/var/log/noctalia-greeter.logand/var/lib/noctalia-greeter/greeter.log. Runjust setup-log-dirif they are missing. Failed to spawn client/ wrong path in greetd config -commandmust be the full path fromwhich noctalia-greeter-session(often/usr/bin/...on packaged installs, not/usr/local/bin/...).WAYLAND_DISPLAY is not set- greetd must usenoctalia-greeter-session(it startsnoctalia-greeter-compositor). Fixcommandin/etc/greetd/config.toml.- Black screen after reboot - logs survive under
/var/log/noctalia-greeter.logand/var/lib/noctalia-greeter/greeter.log(runjust setup-log-dironce). Session output also goes there when writable. - Wrong session on startup - If
[session].defaultis set ingreeter.toml, it wins over last-used[session].last. Runnoctalia-greeter sessionsfor exact Name spelling. - Synced look missing - Install shell v5 and greeter; run Sync Now in shell settings again; restart greetd or log out once.
Stuck display over SSH:
just recoverNoctalia Greeter is a display/login greeter for greetd. It handles user/session selection and authentication UI.
It is not a desktop shell or compositor replacement.
Contributions are welcome: fixes, polish, docs, or UX improvements.
- Open an issue for bugs and regressions
- Open a PR for improvements
Distributed under the MIT License. See LICENSE for details.