#!/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. # # The CyberQueer login look is a self-contained stylesheet (regreet.css, loaded # by ReGreet over an Adwaita-dark base) — picked per-DE from # desktopenvs//greetd-regreet/ (see resolve_de_dir below), so hyprdrive's # glowy "Cosmonaut Shell" skin doesn't get applied on a hyprlua machine (or # vice versa). The greeter background tracks 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" # shared infra: config.toml, session script ETC_LIGHTDM="$DOTFILES_DIR/etc-lightdm" # shared wallpaper-sync helper + units # The greeter's VISUAL skin (regreet.toml + regreet.css) is per-DE — hyprdrive's # "Cosmonaut Shell" (translucent glass, glow, scanlines) and hyprlua's plain # flat skin are different files under desktopenvs//greetd-regreet/. Resolve # which DE this machine is actually running the same way sysupdate.sh's # _de_source_dir() does: the installed config-updater's SOURCE_BASE is the # authoritative marker (set by each DE's installer), with a running-session # fallback for a machine that hasn't installed config-updater yet. resolve_de_dir() { local conf="${XDG_CONFIG_HOME:-$HOME/.config}/config-updater/updater.conf" if [[ -f "$conf" ]]; then local src src=$(awk -F'[[:space:]]*=[[:space:]]*' '/^SOURCE_BASE/{print $2; exit}' "$conf") src="${src/#\~/$HOME}" [[ -d "${src:-}" ]] && { printf '%s' "$src"; return; } fi if [[ -n "${HYPRLAND_INSTANCE_SIGNATURE:-}" ]] && pgrep -x niri &>/dev/null; then printf '%s' "$DOTFILES_DIR/desktopenvs/niri" elif pgrep -x Hyprland &>/dev/null || [[ -n "${HYPRLAND_INSTANCE_SIGNATURE:-}" ]]; then printf '%s' "$DOTFILES_DIR/desktopenvs/hyprlua" fi } DE_DIR="$(resolve_de_dir)" if [[ -n "$DE_DIR" && -d "$DE_DIR/greetd-regreet" ]]; then GREETER_SKIN="$DE_DIR/greetd-regreet" log "Using ${GREETER_SKIN#$DOTFILES_DIR/} for the greeter skin (detected DE: $(basename "$DE_DIR"))." else # No DE-specific skin (niri/sway/legacy hyprland) — fall back to # hyprdrive's, the original/default look this module has always shipped. GREETER_SKIN="$DOTFILES_DIR/desktopenvs/hyprdrive/greetd-regreet" warn "No greeter skin for detected DE (${DE_DIR:-unknown}) — falling back to hyprdrive's." fi log "Installing greetd + ReGreet + cage..." sudo pacman -S --noconfirm --needed greetd greetd-regreet cage # ── cyberqueer GTK theme (optional) ─────────────────────────────────────────── # The greeter's look is driven by regreet.css over an Adwaita base, so this is no # longer required — but we still ship it so flipping regreet.toml's theme_name # back to "cyberqueer" works, and so the theme exists on a greeter-only install. 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 "$GREETER_SKIN/regreet.toml" /etc/greetd/regreet.toml sudo install -Dm644 "$GREETER_SKIN/regreet.css" /etc/greetd/regreet.css 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."