From 29f6c62008d3e4685ab0b94713f426adfea70780 Mon Sep 17 00:00:00 2001 From: The_miro Date: Sat, 4 Jul 2026 03:16:12 +0200 Subject: [PATCH] feat(greeter): switch to greetd+ReGreet (Wayland), fix FIDO/scaling/wallpaper Replace the Xorg lightdm-gtk-greeter with a wlroots-native greetd + ReGreet greeter (inside a cage kiosk), fixing three issues rooted in running an X greeter on a multi-monitor / HiDPI / Wayland box: a blank output, tiny scaling, and the Xorg->Wayland VT/seat handover race that left the Hyprland session with dead keyboard/mouse. - etc-greetd/: greetd config, ReGreet config (cyberqueer GTK4 theme, larger font, wallpaper background), cage session launcher, and a password + FIDO PAM stack (no securetty/OATH, which a graphical greeter cannot drive). - greetd-regreet.sh: install/enable module, mutually exclusive with the lightdm and ly greeter modules. - Greeter background tracks the desktop wallpaper: a root systemd .path unit mirrors the picker's choice to a greeter-readable path (the user's home is 0700, so the unprivileged greeter cannot read it directly). The LightDM path is kept as a dormant alternative and hardened en route: pam_u2f (FIDO) added to its PAM stack, a HiDPI + multi-monitor display-setup.sh, a larger greeter font, and the same wallpaper-sync units. Co-Authored-By: Claude Opus 4.8 --- etc-greetd/config.toml | 17 +++ etc-greetd/pam.d-greetd | 16 +++ etc-greetd/regreet-session.sh | 16 +++ etc-greetd/regreet.toml | 42 ++++++++ etc-lightdm/display-setup.sh | 56 ++++++++++ etc-lightdm/lightdm-greeter-wallpaper | 41 +++++++ etc-lightdm/lightdm-greeter-wallpaper.path | 11 ++ etc-lightdm/lightdm-greeter-wallpaper.service | 10 ++ etc-lightdm/lightdm-gtk-greeter.conf | 15 ++- .../optional-Modules/apps/greetd-regreet.sh | 101 ++++++++++++++++++ .../modules/optional-Modules/apps/lightdm.sh | 72 +++++++++++++ 11 files changed, 395 insertions(+), 2 deletions(-) create mode 100644 etc-greetd/config.toml create mode 100644 etc-greetd/pam.d-greetd create mode 100644 etc-greetd/regreet-session.sh create mode 100644 etc-greetd/regreet.toml create mode 100644 etc-lightdm/display-setup.sh create mode 100644 etc-lightdm/lightdm-greeter-wallpaper create mode 100644 etc-lightdm/lightdm-greeter-wallpaper.path create mode 100644 etc-lightdm/lightdm-greeter-wallpaper.service create mode 100644 setup/modules/optional-Modules/apps/greetd-regreet.sh diff --git a/etc-greetd/config.toml b/etc-greetd/config.toml new file mode 100644 index 0000000..452fbab --- /dev/null +++ b/etc-greetd/config.toml @@ -0,0 +1,17 @@ +# greetd config — Wayland-native cyberqueer greeter (ReGreet inside cage). +# +# Deployed to /etc/greetd/config.toml by +# setup/modules/optional-Modules/apps/greetd-regreet.sh. +# +# Replaces the LightDM/lightdm-gtk-greeter (Xorg) path: a wlroots greeter drives +# every monitor natively (no blank output) and hands input straight to the +# Wayland session — no Xorg→Wayland VT handover race. + +[terminal] +# Own tty1 (the getty there is disabled by the greeter module). +vt = 1 + +[default_session] +# regreet-session.sh sets greeter env, then execs `cage -s -- regreet`. +command = "/etc/greetd/regreet-session.sh" +user = "greeter" diff --git a/etc-greetd/pam.d-greetd b/etc-greetd/pam.d-greetd new file mode 100644 index 0000000..5e5abf6 --- /dev/null +++ b/etc-greetd/pam.d-greetd @@ -0,0 +1,16 @@ +#%PAM-1.0 +# PAM stack for the greetd/ReGreet greeter. +# +# Deployed to /etc/pam.d/greetd by greetd-regreet.sh (@HOST@ → this machine's +# hostname at install time). Mirrors the working lightdm stack: password via +# system-login plus a required FIDO/U2F touch. `nouserok` lets users without an +# enrolled key log in with their password alone. +# +# NOTE: intentionally simpler than a tuigreet multi-factor stack — no +# pam_securetty / pam_oath, which a graphical greeter's single password field +# cannot drive cleanly. +auth include system-login +auth required pam_u2f.so nouserok cue origin=pam://@HOST@ appid=pam://@HOST@ +account include system-login +password include system-login +session include system-login diff --git a/etc-greetd/regreet-session.sh b/etc-greetd/regreet-session.sh new file mode 100644 index 0000000..06e1a00 --- /dev/null +++ b/etc-greetd/regreet-session.sh @@ -0,0 +1,16 @@ +#!/bin/sh +# regreet-session.sh — greetd session command: run ReGreet inside a cage kiosk. +# +# greetd runs this as the unprivileged `greeter` user. cage is a minimal +# wlroots/Wayland compositor; `-s` allows VT switching (so Ctrl+Alt+F-keys still +# reach a console). Env here tunes the greeter's look before ReGreet starts. +# +# Scaling: cage renders at output scale 1. Bump XCURSOR_SIZE for a larger cursor; +# uncomment GDK_SCALE to integer-scale the whole greeter (careful on mixed-DPI +# multi-monitor — it scales every output). Prefer regreet.toml's font_name for +# finer control. + +export XCURSOR_SIZE=32 +# export GDK_SCALE=2 + +exec cage -s -- regreet diff --git a/etc-greetd/regreet.toml b/etc-greetd/regreet.toml new file mode 100644 index 0000000..e028e33 --- /dev/null +++ b/etc-greetd/regreet.toml @@ -0,0 +1,42 @@ +# regreet.toml — cyberqueer-themed ReGreet greeter for greetd (Wayland-native) +# +# Deployed to /etc/greetd/regreet.toml by +# setup/modules/optional-Modules/apps/greetd-regreet.sh. +# +# ReGreet is GTK4, so it reuses the cyberqueer GTK theme's gtk-4.0 assets +# (/usr/share/themes/cyberqueer) — matching the desktop without hardcoded colours +# here. Being a wlroots/Wayland greeter it drives every monitor natively (no +# blank outputs) and hands input straight to the Wayland session with no +# Xorg→Wayland VT handover. + +# Remember the last user + session and skip the pickers. +skip_selection = false + +[background] +# Tracks the user's current desktop wallpaper: the picker writes +# ~/.config/hypr/usr/wallpaper.conf and the lightdm-greeter-wallpaper.path unit +# copies the chosen image here (a path the unprivileged greeter can read). +path = "/usr/share/backgrounds/lightdm-greeter-bg.png" +fit = "Cover" + +[GTK] +application_prefer_dark_theme = true +cursor_theme_name = "Adwaita" +cursor_blink = true +# Bumped well above the 11pt the old greeter used, so the greeter reads large on +# the 4K panel. Tune here (or via GDK_SCALE in regreet-session.sh) to taste. +font_name = "JetBrains Mono 16" +icon_theme_name = "Adwaita" +theme_name = "cyberqueer" + +[commands] +reboot = ["systemctl", "reboot"] +poweroff = ["systemctl", "poweroff"] + +[appearance] +greeting_msg = "Welcome back" + +[widget.clock] +format = "%H:%M" +resolution = "1s" +label_width = 150 diff --git a/etc-lightdm/display-setup.sh b/etc-lightdm/display-setup.sh new file mode 100644 index 0000000..168927c --- /dev/null +++ b/etc-lightdm/display-setup.sh @@ -0,0 +1,56 @@ +#!/bin/sh +# display-setup.sh — LightDM greeter display + HiDPI setup +# +# Runs as root on the greeter's X server BEFORE the greeter starts (wired up via +# `display-setup-script=` in /etc/lightdm/lightdm.conf). +# +# Why this exists: lightdm-gtk-greeter is an Xorg client. On a multi-monitor box +# a bare X server may leave some outputs disabled (a "blank" monitor at the login +# screen) and drops the login form onto whichever output it picks as primary — +# often a small side panel. It also defaults to 96 DPI, so on a 4K panel the +# whole greeter is tiny. +# +# So, name-agnostically (survives GPU/cable/port changes): +# 1. Enable every connected output at its preferred mode, laid out left→right. +# 2. Make the widest active output primary, so the login form lands on the main +# (here: 4K) monitor instead of a small one. +# 3. Raise the DPI so text, icons, form and cursor are legibly large. GTK reads +# Xft.dpi from the X resource database; `xrandr --dpi` covers anything that +# reads the server core DPI instead. +# +# Tuning: bump/lower the 144 DPI (96 = 1.0x, 144 = 1.5x, 192 = 2.0x) to taste. + +LOG=/var/log/lightdm/display-setup.log +exec >>"$LOG" 2>&1 +echo "=== display-setup $(date) ===" + +[ -x /usr/bin/xrandr ] || { echo "xrandr missing — skipping"; exit 0; } + +# 1. Enable + position every connected output, left to right in connection order. +prev="" +for out in $(xrandr --query | awk '/ connected/{print $1}'); do + if [ -z "$prev" ]; then + xrandr --output "$out" --auto --pos 0x0 + else + xrandr --output "$out" --auto --right-of "$prev" + fi + prev="$out" +done + +# 2. Primary = widest currently-active output (parse the WxH+X+Y geometry). +best_out=$(xrandr --query | awk ' + / connected/{o=$1} + match($0, /[0-9]+x[0-9]+\+[0-9]+\+[0-9]+/){ + split(substr($0, RSTART, RLENGTH), a, /[x+]/) + if (a[1]+0 > best){ best=a[1]+0; bo=o } + } + END{ print bo }') +[ -n "$best_out" ] && xrandr --output "$best_out" --primary + +# 3. HiDPI scaling for the greeter. +xrandr --dpi 144 +if [ -n "$DISPLAY" ] && command -v xrdb >/dev/null 2>&1; then + printf 'Xft.dpi: 144\nXcursor.size: 36\n' | xrdb -merge +fi + +echo "primary=${best_out:-} dpi=144" diff --git a/etc-lightdm/lightdm-greeter-wallpaper b/etc-lightdm/lightdm-greeter-wallpaper new file mode 100644 index 0000000..d561f60 --- /dev/null +++ b/etc-lightdm/lightdm-greeter-wallpaper @@ -0,0 +1,41 @@ +#!/bin/sh +# lightdm-greeter-wallpaper — mirror the user's desktop wallpaper to the greeter. +# +# The wallpaper picker (~/.config/scripts/wallpaper-picker) writes the chosen +# per-monitor wallpapers to ~/.config/hypr/usr/wallpaper.conf. This helper copies +# the wallpaper of the greeter's main monitor to a world-readable system path so +# the LightDM greeter — which runs as the unprivileged 'lightdm' user and cannot +# read a 0700 home — can use it as its background. +# +# Run as root (it needs to read the user's home) via lightdm-greeter-wallpaper.path, +# which fires whenever wallpaper.conf changes. Usage: +# lightdm-greeter-wallpaper +# +# Monitor choice: prefer $PREFERRED_MONITOR (the main/4K panel that hosts the +# login form); fall back to the first wallpaper entry. Set PREFERRED_MONITOR in +# the environment (the .service does) to match your primary output. + +set -eu + +USER_NAME="${1:?usage: lightdm-greeter-wallpaper }" +PREFERRED="${PREFERRED_MONITOR:-}" +DEST="/usr/share/backgrounds/lightdm-greeter-bg.png" + +HOME_DIR="$(getent passwd "$USER_NAME" | cut -d: -f6)" +[ -n "$HOME_DIR" ] || { echo "no home for $USER_NAME" >&2; exit 0; } +STATE="$HOME_DIR/.config/hypr/usr/wallpaper.conf" +[ -r "$STATE" ] || { echo "no wallpaper state at $STATE" >&2; exit 0; } + +# Path for the preferred monitor, else the first wallpaper path in the file. +src="" +if [ -n "$PREFERRED" ]; then + src="$(awk -v m="$PREFERRED" ' + $1=="monitor" && $3==m { want=1; next } + want && $1=="path" { print $3; exit }' "$STATE")" +fi +[ -n "$src" ] || src="$(awk '$1=="path"{print $3; exit}' "$STATE")" + +[ -n "$src" ] && [ -r "$src" ] || { echo "no readable wallpaper resolved" >&2; exit 0; } + +install -Dm644 "$src" "$DEST" +echo "greeter background <- $src" diff --git a/etc-lightdm/lightdm-greeter-wallpaper.path b/etc-lightdm/lightdm-greeter-wallpaper.path new file mode 100644 index 0000000..55a2f5a --- /dev/null +++ b/etc-lightdm/lightdm-greeter-wallpaper.path @@ -0,0 +1,11 @@ +# Watch the wallpaper picker's state file; refresh the greeter background on change. +# @USER@ is filled in at install time by lightdm.sh. +[Unit] +Description=Watch @USER@'s wallpaper selection for the LightDM greeter + +[Path] +PathModified=/home/@USER@/.config/hypr/usr/wallpaper.conf +Unit=lightdm-greeter-wallpaper.service + +[Install] +WantedBy=multi-user.target diff --git a/etc-lightdm/lightdm-greeter-wallpaper.service b/etc-lightdm/lightdm-greeter-wallpaper.service new file mode 100644 index 0000000..3c657f7 --- /dev/null +++ b/etc-lightdm/lightdm-greeter-wallpaper.service @@ -0,0 +1,10 @@ +# Mirror the user's current desktop wallpaper to the LightDM greeter background. +# Triggered by lightdm-greeter-wallpaper.path when wallpaper.conf changes. +# @USER@ / @PREFERRED_MONITOR@ are filled in at install time by lightdm.sh. +[Unit] +Description=Sync LightDM greeter background to @USER@'s desktop wallpaper + +[Service] +Type=oneshot +Environment=PREFERRED_MONITOR=@PREFERRED_MONITOR@ +ExecStart=/usr/local/bin/lightdm-greeter-wallpaper @USER@ diff --git a/etc-lightdm/lightdm-gtk-greeter.conf b/etc-lightdm/lightdm-gtk-greeter.conf index ec93b05..df70f8c 100644 --- a/etc-lightdm/lightdm-gtk-greeter.conf +++ b/etc-lightdm/lightdm-gtk-greeter.conf @@ -6,11 +6,22 @@ # Colours are inherited from the cyberqueer GTK theme (installed to # /usr/share/themes/cyberqueer), which is an apply-theme.sh SYS_FILES target — # so there are no hardcoded palette hex values to keep in sync here. +# +# Scaling: the greeter is enlarged mainly via the X DPI set in display-setup.sh +# (Xft.dpi 144). font-name is kept modest because point sizes already scale with +# that DPI; bump the DPI in display-setup.sh to make everything bigger still. +# +# Background: tracks the user's current desktop wallpaper. The picker writes +# ~/.config/hypr/usr/wallpaper.conf; a root .path unit +# (lightdm-greeter-wallpaper.path) copies the chosen wallpaper to the path below, +# which the greeter (running as the unprivileged 'lightdm' user, unable to read a +# 0700 home) can read. cyberqueer-skull.png is the first-boot fallback, seeded by +# lightdm.sh if no wallpaper has been chosen yet. [greeter] theme-name = cyberqueer icon-theme-name = Papirus-Dark -background = /usr/share/backgrounds/cyberqueer-skull.png -font-name = JetBrains Mono 11 +background = /usr/share/backgrounds/lightdm-greeter-bg.png +font-name = JetBrains Mono 12 xft-antialias = true xft-hintstyle = hintfull indicators = ~host;~spacer;~clock;~spacer;~session;~power diff --git a/setup/modules/optional-Modules/apps/greetd-regreet.sh b/setup/modules/optional-Modules/apps/greetd-regreet.sh new file mode 100644 index 0000000..df60e24 --- /dev/null +++ b/setup/modules/optional-Modules/apps/greetd-regreet.sh @@ -0,0 +1,101 @@ +#!/bin/bash +# greetd-regreet.sh — greetd + ReGreet (cyberqueer-themed, Wayland-native greeter) +# +# The Wayland-native alternative to the lightdm module. lightdm-gtk-greeter is an +# Xorg client, which on this multi-monitor / HiDPI / Wayland box means: a monitor +# can come up blank, the greeter renders tiny, and the Xorg→Wayland VT handover +# can race so the Hyprland session starts with dead input. ReGreet runs on +# wlroots (inside a cage kiosk), so it drives every output natively and hands +# input straight to the Wayland session — none of those failure modes. +# +# It reuses the cyberqueer GTK theme (gtk-4.0 assets) and the greeter-background +# sync (the wallpaper picker's choice, mirrored to a greeter-readable path by the +# lightdm-greeter-wallpaper.path unit — shared, greeter-agnostic despite the name). +# +# Mutually exclusive with the lightdm and ly greeter modules: enabling greetd +# here disables the others and the tty1 getty so exactly one greeter runs. + +set -euo pipefail +source "$(dirname "${BASH_SOURCE[0]}")/../../lib/logging.sh" + +# apps/ → optional-Modules → modules → setup → repo root (four levels up). +DOTFILES_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." && pwd)" +ETC_GREETD="$DOTFILES_DIR/etc-greetd" +ETC_LIGHTDM="$DOTFILES_DIR/etc-lightdm" # shared wallpaper-sync helper + units + +log "Installing greetd + ReGreet + cage..." +sudo pacman -S --noconfirm --needed greetd greetd-regreet cage + +# ── cyberqueer GTK theme (ReGreet is GTK4 → needs the gtk-4.0 assets) ────────── +GTK_THEME_SRC="$DOTFILES_DIR/gtk-themes/cyberqueer" +if [[ -d "$GTK_THEME_SRC" ]]; then + log "Installing cyberqueer GTK theme to /usr/share/themes..." + sudo cp -r "$GTK_THEME_SRC" /usr/share/themes/ +else + warn "cyberqueer GTK theme not found at $GTK_THEME_SRC — greeter uses the default GTK theme." +fi + +# ── Skull fallback background (used until a wallpaper is picked) ─────────────── +SKULL_SRC="$DOTFILES_DIR/resources/bg-skull.svg" +SKULL_DST="/usr/share/backgrounds/cyberqueer-skull.png" +if [[ -f "$SKULL_SRC" ]]; then + command -v rsvg-convert &>/dev/null || sudo pacman -S --noconfirm --needed librsvg + TMP_BG="$(mktemp /tmp/greeter-skull.XXXXXX.png)" + trap 'rm -f "$TMP_BG"' EXIT + rsvg-convert -w 1920 "$SKULL_SRC" -o "$TMP_BG" + sudo install -Dm644 "$TMP_BG" "$SKULL_DST" +fi + +# ── Deploy greetd + ReGreet configuration ───────────────────────────────────── +log "Deploying greetd config, ReGreet config, and session launcher..." +sudo install -Dm644 "$ETC_GREETD/config.toml" /etc/greetd/config.toml +sudo install -Dm644 "$ETC_GREETD/regreet.toml" /etc/greetd/regreet.toml +sudo install -Dm755 "$ETC_GREETD/regreet-session.sh" /etc/greetd/regreet-session.sh + +# ── PAM: password (system-login) + required FIDO/U2F touch ──────────────────── +# Replace any pre-existing greetd stack (e.g. a tuigreet securetty+oath one that +# a graphical greeter cannot drive), keeping a timestamped backup. +U2F_HOST="$(hostnamectl --static hostname 2>/dev/null || hostname)" +if [[ -f "$ETC_GREETD/pam.d-greetd" ]]; then + [[ -f /etc/pam.d/greetd ]] && sudo cp -a /etc/pam.d/greetd "/etc/pam.d/greetd.bak-$(date +%s)" + log "Deploying /etc/pam.d/greetd (password + FIDO, origin pam://${U2F_HOST})..." + tmp="$(mktemp)" + sed "s|@HOST@|${U2F_HOST}|g" "$ETC_GREETD/pam.d-greetd" > "$tmp" + sudo install -Dm644 "$tmp" /etc/pam.d/greetd + rm -f "$tmp" +else + warn "PAM template not found — leaving /etc/pam.d/greetd as-is (FIDO may not work)." +fi + +# ── Greeter background tracks the user's desktop wallpaper (shared units) ────── +TARGET_USER="${SUDO_USER:-$(id -un)}" +PREF_MON="${LIGHTDM_GREETER_MONITOR:-}" +WP_HELPER_SRC="$ETC_LIGHTDM/lightdm-greeter-wallpaper" +if [[ -f "$WP_HELPER_SRC" ]]; then + log "Installing greeter wallpaper-sync helper + units (user: $TARGET_USER)..." + sudo install -Dm755 "$WP_HELPER_SRC" /usr/local/bin/lightdm-greeter-wallpaper + for unit in lightdm-greeter-wallpaper.service lightdm-greeter-wallpaper.path; do + tmp="$(mktemp)" + sed -e "s|@USER@|${TARGET_USER}|g" -e "s|@PREFERRED_MONITOR@|${PREF_MON}|g" \ + "$ETC_LIGHTDM/$unit" > "$tmp" + sudo install -Dm644 "$tmp" "/etc/systemd/system/$unit" + rm -f "$tmp" + done + sudo systemctl daemon-reload + enable_service lightdm-greeter-wallpaper.path + sudo PREFERRED_MONITOR="$PREF_MON" /usr/local/bin/lightdm-greeter-wallpaper "$TARGET_USER" || true + if [[ ! -f /usr/share/backgrounds/lightdm-greeter-bg.png && -f "$SKULL_DST" ]]; then + sudo install -Dm644 "$SKULL_DST" /usr/share/backgrounds/lightdm-greeter-bg.png + fi +else + warn "Wallpaper-sync helper not found — greeter background will not track the wallpaper." + [[ -f "$SKULL_DST" ]] && sudo install -Dm644 "$SKULL_DST" /usr/share/backgrounds/lightdm-greeter-bg.png +fi + +# ── Make greetd the sole display manager ────────────────────────────────────── +sudo systemctl disable getty@tty1.service || true +disable_service lightdm.service +disable_service ly@tty1.service +enable_service greetd.service + +log "greetd + ReGreet installed and enabled. The Wayland greeter starts on next boot." diff --git a/setup/modules/optional-Modules/apps/lightdm.sh b/setup/modules/optional-Modules/apps/lightdm.sh index 385d5a1..4578eeb 100755 --- a/setup/modules/optional-Modules/apps/lightdm.sh +++ b/setup/modules/optional-Modules/apps/lightdm.sh @@ -60,6 +60,78 @@ else warn "Greeter config not found at $GREETER_CONF_SRC — LightDM will use greeter defaults." fi +# ── HiDPI + multi-monitor display setup ─────────────────────────────────────── +# lightdm-gtk-greeter is an Xorg client; on a multi-monitor / HiDPI box X must be +# told to enable every output and scale up, or a monitor stays blank at the login +# screen and the greeter is tiny. display-setup.sh (root, before the greeter) +# handles both. Wire it into lightdm.conf's [Seat:*] idempotently. +DISPLAY_SETUP_SRC="$DOTFILES_DIR/etc-lightdm/display-setup.sh" +if [[ -f "$DISPLAY_SETUP_SRC" ]]; then + log "Deploying greeter display-setup script..." + sudo install -Dm755 "$DISPLAY_SETUP_SRC" /etc/lightdm/display-setup.sh + # xrandr/xrdb are needed by the script at greeter time. + sudo pacman -S --noconfirm --needed xorg-xrandr xorg-xrdb + # Match only the real setting form (#display-setup-script=), never the + # "# display-setup-script = " documentation comment (note the + # space after '#') — otherwise the doc line gets turned into a stray active + # setting under [LightDM]. + if grep -qE '^\s*display-setup-script\s*=\s*/etc/lightdm/display-setup.sh' /etc/lightdm/lightdm.conf; then + skip "display-setup-script already wired in lightdm.conf" + elif grep -qE '^\s*#?display-setup-script\s*=' /etc/lightdm/lightdm.conf; then + sudo sed -i -E 's|^\s*#?display-setup-script\s*=.*|display-setup-script=/etc/lightdm/display-setup.sh|' /etc/lightdm/lightdm.conf + log "Wired display-setup-script into lightdm.conf" + else + sudo sed -i '/^\[Seat:\*\]/a display-setup-script=/etc/lightdm/display-setup.sh' /etc/lightdm/lightdm.conf + log "Added display-setup-script to [Seat:*] in lightdm.conf" + fi +else + warn "display-setup.sh not found at $DISPLAY_SETUP_SRC — greeter monitors/scaling unmanaged." +fi + +# ── FIDO / U2F login at the greeter ─────────────────────────────────────────── +# LightDM's PAM stack only `include`s system-login, which has no pam_u2f — so +# hardware-key login (supported by the other greeters here) would not work. Add +# it, matching this machine's origin/appid (pam://$hostname, the pam_u2f default +# used at enrolment). `nouserok` lets users without an enrolled key still log in +# with their password alone. +PAM_LIGHTDM=/etc/pam.d/lightdm +if [[ -f "$PAM_LIGHTDM" ]] && ! grep -q pam_u2f "$PAM_LIGHTDM"; then + U2F_HOST="$(hostnamectl --static hostname 2>/dev/null || hostname)" + log "Enabling pam_u2f (FIDO) for the LightDM greeter..." + sudo sed -i "/^auth\s\+include\s\+system-login/a auth required pam_u2f.so nouserok cue origin=pam://${U2F_HOST} appid=pam://${U2F_HOST}" "$PAM_LIGHTDM" +else + skip "pam_u2f already present in $PAM_LIGHTDM (or file missing)" +fi + +# ── Greeter background tracks the user's desktop wallpaper ───────────────────── +# The wallpaper picker writes ~/.config/hypr/usr/wallpaper.conf; a root .path unit +# copies the chosen wallpaper to a system path the greeter can read (the user's +# home is 0700). Install the helper + units with the target user substituted in. +TARGET_USER="${SUDO_USER:-$(id -un)}" +PREF_MON="${LIGHTDM_GREETER_MONITOR:-}" +WP_HELPER_SRC="$DOTFILES_DIR/etc-lightdm/lightdm-greeter-wallpaper" +if [[ -f "$WP_HELPER_SRC" ]]; then + log "Installing greeter wallpaper-sync helper + units (user: $TARGET_USER)..." + sudo install -Dm755 "$WP_HELPER_SRC" /usr/local/bin/lightdm-greeter-wallpaper + for unit in lightdm-greeter-wallpaper.service lightdm-greeter-wallpaper.path; do + tmp="$(mktemp)" + sed -e "s|@USER@|${TARGET_USER}|g" -e "s|@PREFERRED_MONITOR@|${PREF_MON}|g" \ + "$DOTFILES_DIR/etc-lightdm/$unit" > "$tmp" + sudo install -Dm644 "$tmp" "/etc/systemd/system/$unit" + rm -f "$tmp" + done + sudo systemctl daemon-reload + enable_service lightdm-greeter-wallpaper.path + # Seed the greeter background now: user's current wallpaper if set, else skull. + sudo PREFERRED_MONITOR="$PREF_MON" /usr/local/bin/lightdm-greeter-wallpaper "$TARGET_USER" || true + if [[ ! -f /usr/share/backgrounds/lightdm-greeter-bg.png && -f "$SKULL_DST" ]]; then + sudo install -Dm644 "$SKULL_DST" /usr/share/backgrounds/lightdm-greeter-bg.png + fi +else + warn "Wallpaper-sync helper not found — greeter background will not track the desktop wallpaper." + [[ -f "$SKULL_DST" ]] && sudo install -Dm644 "$SKULL_DST" /usr/share/backgrounds/lightdm-greeter-bg.png +fi + # ── Make LightDM the sole display manager ───────────────────────────────────── # LightDM manages its own VT; free tty1 and disable the competing greeters so # nothing else races it.