From d1e5f765aa25bf3a7efa99b72f6dd8cf696a16d7 Mon Sep 17 00:00:00 2001 From: The_miro Date: Sat, 4 Jul 2026 01:53:37 +0200 Subject: [PATCH] feat(greeter): switch HyprLua to LightDM, fix Plymouth splash, extract ly module Plymouth: bg-skull.svg is a 1920x1080 transparent composition but was rendered at 300px and treated as a small centred logo, so the skull all but vanished and the spinner (positioned off the logo height) landed on the monitor artwork. Now render at native 1920px, scale to fill the screen, and pin the spinner at a fixed 0.93 of screen height. Also fix DOTFILES_DIR (was off by one level, so the bundled SVG never resolved and it fell back to a transparent placeholder) and the dead ../plymouth.sh paths in plymouth-custom.sh and install-modules.sh. Greeter: HyprLua now uses LightDM + lightdm-gtk-greeter, themed with the existing cyberqueer GTK theme and a rendered skull background, via a new self-contained lightdm module. ly is extracted from the DE scripts into its own module so it stays installable; niri and legacy hyprland keep their inline ly. Both greeters are registered in modules.conf as mutually exclusive, and the generated installer/answerfile/docs regions were rebuilt from it. install-modules.sh guards the 'ly' token with a padded match so it can't substring-hit 'p(ly)mouth'. Add setup/tools/migrate-to-lightdm.sh to move an existing install (ly / greetd / GDM / SDDM / LXDM) onto the Plymouth + LightDM setup: it disables the old DM for the next boot only (never stops the running session) and delegates install + theming to the module scripts. Supports --dry-run / --no-plymouth / --yes. Co-Authored-By: Claude Opus 4.8 --- docs/md/modules.md | 2 + etc-lightdm/lightdm-gtk-greeter.conf | 17 ++ setup/install-modules.sh | 12 +- setup/modules.conf | 2 + setup/modules/Desktop-Environments/hyprlua.sh | 26 +-- .../modules/optional-Modules/apps/lightdm.sh | 71 +++++++ setup/modules/optional-Modules/apps/ly.sh | 43 ++++ .../optional-Modules/apps/plymouth-custom.sh | 2 +- .../modules/optional-Modules/apps/plymouth.sh | 37 ++-- setup/tools/generate-answerfile.sh | 4 +- setup/tools/migrate-to-lightdm.sh | 193 ++++++++++++++++++ setup/tui-install.sh | 22 ++ 12 files changed, 398 insertions(+), 33 deletions(-) create mode 100644 etc-lightdm/lightdm-gtk-greeter.conf create mode 100755 setup/modules/optional-Modules/apps/lightdm.sh create mode 100755 setup/modules/optional-Modules/apps/ly.sh create mode 100755 setup/tools/migrate-to-lightdm.sh diff --git a/docs/md/modules.md b/docs/md/modules.md index 3ea5e68..3b834bc 100644 --- a/docs/md/modules.md +++ b/docs/md/modules.md @@ -135,6 +135,8 @@ bash ~/Dotfiles/setup/install-modules.sh | `wprs` | Wayland proxy for remote sessions (wprs-git, AUR) | | `plymouth` | boot splash — bundled skull logo and spinner | | `plymouth-custom` | boot splash with a user-supplied image | +| `lightdm` | LightDM GTK greeter, cyberqueer-themed (HyprLua default) | +| `ly` | ly TUI display manager, cyberqueer-themed | ### Gaming diff --git a/etc-lightdm/lightdm-gtk-greeter.conf b/etc-lightdm/lightdm-gtk-greeter.conf new file mode 100644 index 0000000..ec93b05 --- /dev/null +++ b/etc-lightdm/lightdm-gtk-greeter.conf @@ -0,0 +1,17 @@ +# lightdm-gtk-greeter.conf — cyberqueer-themed LightDM greeter +# +# Deployed to /etc/lightdm/lightdm-gtk-greeter.conf by +# setup/modules/optional-Modules/apps/lightdm.sh. +# +# 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. +[greeter] +theme-name = cyberqueer +icon-theme-name = Papirus-Dark +background = /usr/share/backgrounds/cyberqueer-skull.png +font-name = JetBrains Mono 11 +xft-antialias = true +xft-hintstyle = hintfull +indicators = ~host;~spacer;~clock;~spacer;~session;~power +clock-format = %H:%M diff --git a/setup/install-modules.sh b/setup/install-modules.sh index 090dac8..1eae7c1 100755 --- a/setup/install-modules.sh +++ b/setup/install-modules.sh @@ -113,6 +113,9 @@ count_steps() { [[ "$sel" == *"butter"* ]] && TOTAL=$(( TOTAL + 1 )) [[ "$sel" == *"plymouth"* ]] && TOTAL=$(( TOTAL + 1 )) [[ "$sel" == *"plymouth-custom"* ]] && TOTAL=$(( TOTAL + 1 )) + [[ "$sel" == *"lightdm"* ]] && TOTAL=$(( TOTAL + 1 )) + # 'ly' is padded/quote-stripped so it doesn't substring-match 'p(ly)mouth'. + [[ " ${sel//\"/} " == *" ly "* ]] && TOTAL=$(( TOTAL + 1 )) [[ "$sel" == *"tlp"* ]] && TOTAL=$(( TOTAL + 1 )) [[ "$sel" == *"steam"* ]] && TOTAL=$(( TOTAL + 1 )) [[ "$sel" == *"vesktop"* ]] && TOTAL=$(( TOTAL + 1 )) @@ -211,6 +214,8 @@ SELECTED=$(dialog --backtitle "$BACKTITLE" \ "butter" "butter btrfs snapshot backup (AUR)" off \ "plymouth" "Plymouth boot splash — skull logo + spinner" off \ "plymouth-custom" "Plymouth (custom) boot splash — supply your own image" off \ + "lightdm" "LightDM GTK greeter, cyberqueer-themed" off \ + "ly" "ly TUI display manager, cyberqueer" off \ "tlp" "TLP laptop power management" off \ \ "steam" "Steam gaming platform" off \ @@ -304,6 +309,8 @@ SUMMARY="" [[ "$SELECTED" == *"localtunnel"* ]] && SUMMARY+=" ✦ LocalTunnel\n" [[ "$SELECTED" == *"butter"* ]] && SUMMARY+=" ✦ butter (btrfs backup)\n" [[ "$SELECTED" == *"plymouth"* ]] && SUMMARY+=" ✦ Plymouth boot splash\n" +[[ "$SELECTED" == *"lightdm"* ]] && SUMMARY+=" ✦ LightDM greeter\n" +[[ " ${SELECTED//\"/} " == *" ly "* ]] && SUMMARY+=" ✦ ly greeter\n" if [[ "$SELECTED" == *"plymouth-custom"* ]]; then if [[ -n "$PLYMOUTH_LOGO_SRC" ]]; then SUMMARY+=" ✦ Plymouth (custom logo: $PLYMOUTH_LOGO_SRC)\n" @@ -384,11 +391,14 @@ DE_DIR="$MODULES/Desktop-Environments" [[ "$SELECTED" == *"ffmpeg"* ]] && run_module "FFmpeg extras" "$APPS/ffmpeg.sh" [[ "$SELECTED" == *"localtunnel"* ]] && run_module "LocalTunnel" "$APPS/localtunnel.sh" [[ "$SELECTED" == *"butter"* ]] && run_module "butter" "$APPS/butter.sh" -[[ "$SELECTED" == *"plymouth"* ]] && run_module "Plymouth" "$MODULES/optional-Modules/plymouth.sh" +[[ "$SELECTED" == *"plymouth"* ]] && run_module "Plymouth" "$APPS/plymouth.sh" if [[ "$SELECTED" == *"plymouth-custom"* ]]; then export PLYMOUTH_LOGO_SRC run_module "Plymouth (custom)" "$APPS/plymouth-custom.sh" fi +[[ "$SELECTED" == *"lightdm"* ]] && run_module "LightDM greeter" "$APPS/lightdm.sh" +# 'ly' is padded/quote-stripped so it doesn't substring-match 'p(ly)mouth'. +[[ " ${SELECTED//\"/} " == *" ly "* ]] && run_module "ly greeter" "$APPS/ly.sh" [[ "$SELECTED" == *"tlp"* ]] && run_module "TLP" "$APPS/tlp.sh" [[ "$SELECTED" == *"steam"* ]] && run_module "Steam" "$APPS/steam.sh" [[ "$SELECTED" == *"vesktop"* ]] && run_module "Vesktop" "$APPS/vesktop.sh" diff --git a/setup/modules.conf b/setup/modules.conf index 69c34b9..e07da11 100644 --- a/setup/modules.conf +++ b/setup/modules.conf @@ -51,6 +51,8 @@ zfs|system|zfs-dkms kernel module|off| wprs|system|Wayland proxy for remote sessions (wprs-git, AUR)|off| plymouth|system|boot splash — bundled skull logo and spinner|on|plymouth-custom plymouth-custom|system|boot splash with a user-supplied image|off|plymouth +lightdm|system|LightDM GTK greeter, cyberqueer-themed (HyprLua default)|off|ly +ly|system|ly TUI display manager, cyberqueer-themed|off|lightdm # ── Gaming ──────────────────────────────────────────────────────────────────── steam|gaming|Steam gaming platform|off| diff --git a/setup/modules/Desktop-Environments/hyprlua.sh b/setup/modules/Desktop-Environments/hyprlua.sh index 6ad7c48..cd1ad44 100755 --- a/setup/modules/Desktop-Environments/hyprlua.sh +++ b/setup/modules/Desktop-Environments/hyprlua.sh @@ -25,7 +25,7 @@ # 3. systemd service enablement # 4. AUR packages via yay # 5. EWW bar (form-factor selection + Rust compilation) -# 6. Themes, ly config, terminal symlink, SSH askpass, dark-mode preference +# 6. Themes, terminal symlink, SSH askpass, dark-mode preference # 7. Nordzy left-hand cursor theme # 8. Bluetooth / iwd services # 9. Config file deployment (hyprlua source tree) @@ -133,7 +133,6 @@ HYPRLUA_PACKAGES=( hyprpicker # colour picker outputting hex/rgb/hsl values pcmanfm-qt # Qt file manager (kept as fallback / alternative) udisks2 # D-Bus daemon for querying and managing storage devices - ly # minimal TUI display manager (takes over tty1 from getty) kew # terminal-based music player hyprpolkitagent # Hyprland-native Polkit authentication agent @@ -155,18 +154,13 @@ log "Enabling essential services..." # NetworkManager: manages all network connections (wired, Wi-Fi, VPN). enable_service NetworkManager.service -# Disable the default getty login prompt on tty1 so ly can own that TTY. -# '|| true' prevents abort if the unit is already disabled. -sudo systemctl disable getty@tty1.service || true - -# Disable greetd, which core.sh enables by default for every install. hyprlua -# uses ly as its greeter, so leaving greetd enabled means two display managers -# both race to claim tty1 — and the stale greetd/tuigreet greeter can win, -# showing the old text login instead of ly. Disable it so ly is the sole greeter. -disable_service greetd.service - -# ly: TUI display manager that presents the login screen on tty1. -enable_service ly@tty1.service +# Greeter: HyprLua uses LightDM with the cyberqueer GTK greeter. The lightdm +# module installs LightDM, deploys its themed config + skull background, disables +# the competing greeters (greetd from core.sh, ly, and the tty1 getty) and +# enables lightdm.service — so exactly one display manager owns the login screen. +# ly remains available as a standalone module (optional-Modules/apps/ly.sh) for +# anyone who prefers it. +bash "$(dirname "${BASH_SOURCE[0]}")/../optional-Modules/apps/lightdm.sh" # udisks2: D-Bus block-device service required by udiskie for auto-mounting. enable_service udisks2.service @@ -273,8 +267,8 @@ sudo cp -r ~/Dotfiles/gtk-themes/cyberqueer /usr/share/themes # Install the matching btop resource-monitor colour theme. sudo cp ~/Dotfiles/desktopenvs/hyprlua/btop/themes/cyberqueer.theme /usr/share/btop/themes -# Deploy the ly display-manager configuration (login screen appearance). -sudo cp -f ~/Dotfiles/etc-ly-config.ini /etc/ly/config.ini +# (The login greeter — LightDM + cyberqueer GTK greeter — is set up in step 3 +# via the lightdm module, which also deploys the greeter theme and background.) # Register kitty as the system terminal for xdg-terminal-exec so file managers # and scripts that open "a terminal here" consistently launch kitty. diff --git a/setup/modules/optional-Modules/apps/lightdm.sh b/setup/modules/optional-Modules/apps/lightdm.sh new file mode 100755 index 0000000..385d5a1 --- /dev/null +++ b/setup/modules/optional-Modules/apps/lightdm.sh @@ -0,0 +1,71 @@ +#!/bin/bash +# lightdm.sh — LightDM + GTK greeter (cyberqueer-themed) +# +# The default greeter for HyprLua. LightDM's GTK greeter reuses the cyberqueer +# GTK theme shipped in this repo (gtk-themes/cyberqueer), so it matches the rest +# of the desktop, and it is driven by a single trivial INI file +# (/etc/lightdm/lightdm-gtk-greeter.conf) — the simplest config of the +# LightDM/LXDM/GDM options. +# +# This module is self-contained (installs the theme + skull background itself) +# so it can also be selected on its own from modules.conf. It is mutually +# exclusive with the ly greeter module. Enabling LightDM here disables the other +# greeters (greetd, ly) and the tty1 getty so exactly one display manager 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)" + +log "Installing LightDM + GTK greeter..." +sudo pacman -S --noconfirm --needed lightdm lightdm-gtk-greeter + +# ── Ensure the cyberqueer GTK theme is present system-wide ──────────────────── +# The greeter runs as the 'lightdm' user and reads themes from /usr/share/themes. +# DE modules already install this, but copy it here too so LightDM can be chosen +# standalone. (Papirus-Dark icons are pulled in by the desktop modules.) +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 will use the default GTK theme." +fi + +# ── Render the skull background from the bundled SVG ─────────────────────────── +# lightdm-gtk-greeter needs a raster background; convert the 1920x1080 SVG. +SKULL_SRC="$DOTFILES_DIR/resources/bg-skull.svg" +SKULL_DST="/usr/share/backgrounds/cyberqueer-skull.png" +if [[ -f "$SKULL_SRC" ]]; then + if ! command -v rsvg-convert &>/dev/null; then + log "Installing librsvg (rsvg-convert) for SVG→PNG conversion..." + sudo pacman -S --noconfirm --needed librsvg + fi + log "Rendering skull background → $SKULL_DST..." + TMP_BG="$(mktemp /tmp/lightdm-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" +else + warn "Skull SVG not found at $SKULL_SRC — greeter will fall back to a solid background." +fi + +# ── Deploy the greeter configuration ────────────────────────────────────────── +GREETER_CONF_SRC="$DOTFILES_DIR/etc-lightdm/lightdm-gtk-greeter.conf" +if [[ -f "$GREETER_CONF_SRC" ]]; then + log "Deploying lightdm-gtk-greeter.conf..." + sudo install -Dm644 "$GREETER_CONF_SRC" /etc/lightdm/lightdm-gtk-greeter.conf +else + warn "Greeter config not found at $GREETER_CONF_SRC — LightDM will use greeter defaults." +fi + +# ── Make LightDM the sole display manager ───────────────────────────────────── +# LightDM manages its own VT; free tty1 and disable the competing greeters so +# nothing else races it. +sudo systemctl disable getty@tty1.service || true +disable_service greetd.service +disable_service ly@tty1.service +enable_service lightdm.service + +log "LightDM installed and enabled. The cyberqueer GTK greeter starts on next boot." diff --git a/setup/modules/optional-Modules/apps/ly.sh b/setup/modules/optional-Modules/apps/ly.sh new file mode 100755 index 0000000..31c7af2 --- /dev/null +++ b/setup/modules/optional-Modules/apps/ly.sh @@ -0,0 +1,43 @@ +#!/bin/bash +# ly.sh — ly TUI display manager (cyberqueer-themed) +# +# ly is a minimal, animated TUI login manager that takes over tty1 from getty. +# Its cyberqueer theming (colormix / doom animation colours) lives in the repo's +# etc-ly-config.ini, which is also an apply-theme.sh SYS_FILES target so the +# palette stays in sync. +# +# This module was extracted from the Desktop-Environment scripts so ly can be +# installed independently of any particular DE. It is mutually exclusive with +# the lightdm greeter module (see modules.conf). Enabling ly here disables the +# other greeters (greetd, lightdm) and the tty1 getty so exactly one display +# manager owns tty1. + +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)" + +log "Installing ly display manager..." +sudo pacman -S --noconfirm --needed ly + +# ── Deploy the cyberqueer ly configuration ──────────────────────────────────── +LY_CONF_SRC="$DOTFILES_DIR/etc-ly-config.ini" +if [[ -f "$LY_CONF_SRC" ]]; then + log "Deploying ly config to /etc/ly/config.ini..." + sudo mkdir -p /etc/ly + sudo cp -f "$LY_CONF_SRC" /etc/ly/config.ini +else + warn "ly config not found at $LY_CONF_SRC — leaving ly defaults in place." +fi + +# ── Make ly the sole greeter on tty1 ────────────────────────────────────────── +# Free tty1 from the getty login prompt so ly can own it. +sudo systemctl disable getty@tty1.service || true +# Turn off the other display managers so two greeters don't race for tty1. +disable_service greetd.service +disable_service lightdm.service +# ly presents the login screen on tty1. +enable_service ly@tty1.service + +log "ly display manager installed and enabled. It takes over tty1 on next boot." diff --git a/setup/modules/optional-Modules/apps/plymouth-custom.sh b/setup/modules/optional-Modules/apps/plymouth-custom.sh index e84957d..faa3a48 100644 --- a/setup/modules/optional-Modules/apps/plymouth-custom.sh +++ b/setup/modules/optional-Modules/apps/plymouth-custom.sh @@ -19,4 +19,4 @@ fi log "Custom Plymouth logo: $PLYMOUTH_LOGO_SRC" export PLYMOUTH_LOGO_SRC -exec bash "$(dirname "${BASH_SOURCE[0]}")/../plymouth.sh" +exec bash "$(dirname "${BASH_SOURCE[0]}")/plymouth.sh" diff --git a/setup/modules/optional-Modules/apps/plymouth.sh b/setup/modules/optional-Modules/apps/plymouth.sh index d92af94..5f43ba1 100644 --- a/setup/modules/optional-Modules/apps/plymouth.sh +++ b/setup/modules/optional-Modules/apps/plymouth.sh @@ -1,8 +1,9 @@ #!/bin/bash # plymouth.sh — Plymouth boot splash installer # -# Installs the M-Archy Plymouth theme: skull logo centred on a dark background -# with a magenta spinning-dot animation below it. +# Installs the M-Archy Plymouth theme: the transparent skull/CRT artwork scaled +# to fill the screen over a dark background, with a magenta spinning-dot +# animation near the bottom. # # SVG NOTE: Plymouth's image loader (ply-image) is PNG-only — it links against # libpng and has no SVG or gdk-pixbuf dependency. The ply-image.h header is @@ -19,7 +20,7 @@ # Steps: # 1. Install plymouth (extra repo) # 2. Install librsvg (rsvg-convert) if logo is SVG; imagemagick for dot -# 3. Produce logo.png (300 px wide) from the resolved source +# 3. Produce logo.png (native 1920 px wide) from the resolved source # 4. Generate a 10×10 magenta dot.png for the spinner # 5. Write the m-archy theme (.plymouth descriptor + .script animation) # 6. Register with plymouth-set-default-theme @@ -32,7 +33,8 @@ source "$(dirname "${BASH_SOURCE[0]}")/../../lib/logging.sh" THEME_DIR="/usr/share/plymouth/themes/m-archy" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -DOTFILES_DIR="$(cd "$SCRIPT_DIR/../../.." && pwd)" +# apps/ → optional-Modules → modules → setup → repo root (four levels up). +DOTFILES_DIR="$(cd "$SCRIPT_DIR/../../../.." && pwd)" # Resolve logo source — env var takes priority, then bundled SVG LOGO_SRC="${PLYMOUTH_LOGO_SRC:-}" @@ -67,7 +69,7 @@ trap 'rm -f "$TMP_LOGO" "$TMP_DOT"' EXIT if [[ -z "$LOGO_SRC" ]]; then warn "No logo source found — using transparent placeholder." - convert -size 300x300 xc:transparent "$TMP_LOGO" + convert -size 1920x1080 xc:transparent "$TMP_LOGO" elif [[ "${LOGO_SRC,,}" == *.png ]]; then log "Using PNG directly: $LOGO_SRC" cp "$LOGO_SRC" "$TMP_LOGO" @@ -77,8 +79,10 @@ else log "Installing librsvg (rsvg-convert) for SVG→PNG conversion..." sudo pacman -S --noconfirm --needed librsvg fi - log "Converting $LOGO_SRC → PNG (300 px wide)..." - rsvg-convert -w 300 "$LOGO_SRC" -o "$TMP_LOGO" + # Render at native width so the full-screen splash keeps detail when the + # Plymouth script scales it to the display resolution. + log "Converting $LOGO_SRC → PNG (1920 px wide)..." + rsvg-convert -w 1920 "$LOGO_SRC" -o "$TMP_LOGO" fi # ── Generate spinner dot ────────────────────────────────────────────────────── @@ -106,7 +110,7 @@ ScriptFile=/usr/share/plymouth/themes/m-archy/m-archy.script EOF sudo tee "$THEME_DIR/m-archy.script" > /dev/null <<'EOF' -# M-Archy Plymouth splash — skull logo + magenta spinner +# M-Archy Plymouth splash — full-screen skull background + magenta spinner Window.SetBackgroundTopColor (0.10, 0.10, 0.10); Window.SetBackgroundBottomColor (0.07, 0.07, 0.07); @@ -114,19 +118,24 @@ Window.SetBackgroundBottomColor (0.07, 0.07, 0.07); screen_width = Window.GetWidth (); screen_height = Window.GetHeight (); -# Centred skull logo +# Full-screen skull background. bg-skull.svg is a 1920x1080 composition with a +# transparent field, so we scale it to fill the display and pin it at the +# origin; the transparent areas reveal the dark background gradient above. logo.image = Image ("logo.png"); -logo.sprite = Sprite (logo.image); -logo.sprite.SetX (Math.Int (screen_width / 2 - logo.image.GetWidth () / 2)); -logo.sprite.SetY (Math.Int (screen_height / 2 - logo.image.GetHeight () / 2)); +scaled = logo.image.Scale (screen_width, screen_height); +logo.sprite = Sprite (scaled); +logo.sprite.SetX (0); +logo.sprite.SetY (0); logo.sprite.SetZ (10); -# 12-dot spinner below the logo +# 12-dot spinner near the bottom of the screen. The centre is a fixed fraction +# of the screen height (not derived from the logo size) so it stays put +# regardless of the source image's dimensions. num_dots = 12; dot_r = 5; orbit = 35; cx = screen_width / 2; -cy = screen_height / 2 + logo.image.GetHeight () / 2 + 55; +cy = Math.Int (screen_height * 0.93); dot.image = Image ("dot.png"); for (i = 0; i < num_dots; i++) { diff --git a/setup/tools/generate-answerfile.sh b/setup/tools/generate-answerfile.sh index 6acdc70..264637d 100755 --- a/setup/tools/generate-answerfile.sh +++ b/setup/tools/generate-answerfile.sh @@ -239,7 +239,7 @@ if [[ "$AF_RUN_TUI" == "true" ]]; then # BEGIN GENERATED MODULES: module-checklist AF_APPS=$(dialog --backtitle "$BACKTITLE" \ --title " Applications " \ - --checklist "Optional applications — installed after base components:" 40 76 80 \ + --checklist "Optional applications — installed after base components:" 40 76 82 \ "ollama" "ollama local LLM runner and API server" off \ "llama-cpp" "llama-cpp standalone LLM inference CLI and server" off \ "open-webui" "open-webui browser UI for Ollama and LLM backends" off \ @@ -274,6 +274,8 @@ if [[ "$AF_RUN_TUI" == "true" ]]; then "wprs" "wprs Wayland proxy for remote sessions (wprs-git, AUR)" off \ "plymouth" "plymouth boot splash — bundled skull logo and spinner" on \ "plymouth-custom" "plymouth-custom boot splash with a user-supplied image" off \ + "lightdm" "lightdm LightDM GTK greeter, cyberqueer-themed (HyprLua default)" off \ + "ly" "ly ly TUI display manager, cyberqueer-themed" off \ "steam" "steam Steam gaming platform" off \ "vesktop" "vesktop Discord client with Vencord theme" off \ "spotify" "spotify Spotify launcher with Spicetify theming" off \ diff --git a/setup/tools/migrate-to-lightdm.sh b/setup/tools/migrate-to-lightdm.sh new file mode 100755 index 0000000..a0febd7 --- /dev/null +++ b/setup/tools/migrate-to-lightdm.sh @@ -0,0 +1,193 @@ +#!/bin/bash +# ============================================================================= +# migrate-to-lightdm.sh — switch an existing install to Plymouth + LightDM +# ============================================================================= +# Migrates a machine that currently boots ly / greetd / GDM / SDDM / LXDM (or any +# other display manager) to this repo's boot experience: +# +# Plymouth skull splash → LightDM + lightdm-gtk-greeter (cyberqueer theme) +# +# What it does: +# 1. Detects the currently-configured display manager(s). +# 2. Disables every known greeter EXCEPT lightdm — for the NEXT boot only. It +# does NOT stop your running session, so you stay logged in until you +# reboot yourself. +# 3. Runs the lightdm module (installs LightDM + lightdm-gtk-greeter, deploys +# the cyberqueer greeter config + skull background, enables lightdm.service). +# 4. Runs the plymouth module (skull splash, initramfs + GRUB cmdline) unless +# --no-plymouth is given. +# +# It reuses the real module scripts under optional-Modules/apps/ so there is no +# duplicated install logic — this tool only handles detection, teardown of the +# OLD display manager, and orchestration. +# +# Safe to re-run (idempotent). Reboot to complete the switch. +# +# Usage: +# migrate-to-lightdm.sh [--yes] [--no-plymouth] [--dry-run] [--help] +# -y, --yes Skip the confirmation prompt (required for non-TTY runs) +# --no-plymouth Migrate the display manager only; leave Plymouth alone +# -n, --dry-run Print what would happen; change nothing +# -h, --help Show this help and exit +# ============================================================================= + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SETUP_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" +APPS="$SETUP_DIR/modules/optional-Modules/apps" + +# Shared helpers: log / skip / warn / err, and best-effort disable_service. +source "$SETUP_DIR/modules/lib/logging.sh" + +# ── Argument parsing ────────────────────────────────────────────────────────── +ASSUME_YES=0 +DO_PLYMOUTH=1 +DRY_RUN=0 + +usage() { + cat <<'EOF' +migrate-to-lightdm.sh — switch this machine to Plymouth + LightDM (cyberqueer) + +Disables the current display manager (ly / greetd / GDM / SDDM / LXDM / …) for +the next boot, installs and themes LightDM, and sets up the Plymouth splash. Your +running session is left untouched; reboot to complete the switch. + +Usage: + migrate-to-lightdm.sh [--yes] [--no-plymouth] [--dry-run] [--help] + -y, --yes Skip the confirmation prompt (required for non-TTY runs) + --no-plymouth Migrate the display manager only; leave Plymouth alone + -n, --dry-run Print what would happen; change nothing + -h, --help Show this help and exit +EOF +} + +while [[ $# -gt 0 ]]; do + case "$1" in + -y|--yes) ASSUME_YES=1 ;; + --no-plymouth) DO_PLYMOUTH=0 ;; + -n|--dry-run) DRY_RUN=1 ;; + -h|--help) usage; exit 0 ;; + *) err "Unknown argument: $1"; echo "Try --help." >&2; exit 2 ;; + esac + shift +done + +# In dry-run, describe an action instead of doing it. In real mode, run it. +run() { + if (( DRY_RUN )); then + printf '[dry-run] would run: %s\n' "$*" + else + "$@" + fi +} + +# ── Known display managers ──────────────────────────────────────────────────── +# Every greeter/DM unit this tool knows how to turn off. lightdm is the TARGET, +# so it never appears here. ly is a template unit (ly@tty1) but some setups use +# the plain ly.service alias, so both are listed. +OTHER_DMS=( + "ly@tty1.service" "ly.service" + "greetd.service" + "gdm.service" "gdm3.service" + "sddm.service" + "lxdm.service" + "xdm.service" + "slim.service" + "lemurs.service" + "emptty.service" +) + +# ── 1. Detect what is configured now ────────────────────────────────────────── +log "Detecting the current display manager configuration..." + +# The canonical "which DM boots" pointer is the display-manager.service symlink. +# Use plain readlink to get the intended target name even if the link is broken; +# a self-referential/absent target means no real DM is configured there. +primary_dm="" +if dm_link="$(readlink /etc/systemd/system/display-manager.service 2>/dev/null)"; then + dm_link="$(basename "$dm_link")" + [[ "$dm_link" != "display-manager.service" ]] && primary_dm="$dm_link" +fi + +# Also probe every known unit directly — ly-based installs often have no +# display-manager.service symlink, they just enable ly@tty1 on tty1. +enabled_dms=() +for unit in "${OTHER_DMS[@]}"; do + state="$(systemctl is-enabled "$unit" 2>/dev/null || true)" + [[ "$state" == "enabled" || "$state" == "alias" || "$state" == "enabled-runtime" ]] \ + && enabled_dms+=("$unit") +done + +# `is-enabled` on an absent unit both prints "not-found" and exits non-zero; +# capture with `|| true` (never `|| echo`, which would concatenate two lines) +# and normalise the "not installed" cases to one label. +lightdm_state="$(systemctl is-enabled lightdm.service 2>/dev/null || true)" +[[ -z "$lightdm_state" || "$lightdm_state" == "not-found" ]] && lightdm_state="not-installed" + +echo +echo " Current display-manager.service : ${primary_dm:-}" +if (( ${#enabled_dms[@]} )); then + echo " Enabled greeter units : ${enabled_dms[*]}" +else + echo " Enabled greeter units : " +fi +echo " lightdm.service : $lightdm_state" +echo " Plymouth migration : $( ((DO_PLYMOUTH)) && echo 'yes' || echo 'skipped (--no-plymouth)')" +echo + +if (( ${#enabled_dms[@]} == 0 )) && [[ "$lightdm_state" == "enabled" ]]; then + log "LightDM already appears to be the active greeter — re-running to refresh config/theme." +fi + +# ── 2. Confirm ──────────────────────────────────────────────────────────────── +# This changes what greets you at the NEXT boot. Require an explicit yes unless +# --yes was given; on a non-interactive stdin, --yes is mandatory. +if (( ! ASSUME_YES )); then + if [[ ! -t 0 ]]; then + err "Non-interactive shell and --yes not given — refusing to change the display manager." + exit 1 + fi + read -r -p "Switch this machine to Plymouth + LightDM as described above? [y/N] " reply + case "$reply" in + y|Y|yes|YES) ;; + *) warn "Aborted — nothing changed."; exit 0 ;; + esac +fi + +# ── 3. Disable the OLD display managers (next boot only) ────────────────────── +# We intentionally do NOT `systemctl stop` the running greeter: that would kill +# your current graphical session. Disabling only removes it from the next boot; +# lightdm.service (enabled below) takes over then. +if (( ${#enabled_dms[@]} )); then + log "Disabling old display manager(s) for the next boot: ${enabled_dms[*]}" + for unit in "${enabled_dms[@]}"; do + run disable_service "$unit" + done +else + skip "No competing display managers enabled — nothing to disable." +fi + +# ── 4. Install + theme + enable LightDM (delegated to the module) ───────────── +# lightdm.sh installs LightDM + the GTK greeter, deploys the cyberqueer greeter +# config + skull background, disables greetd/ly@tty1/getty@tty1, and enables +# lightdm.service. Running it here keeps a single source of truth. +log "Setting up LightDM via the lightdm module..." +run bash "$APPS/lightdm.sh" + +# ── 5. Plymouth splash (delegated to the module) ────────────────────────────── +if (( DO_PLYMOUTH )); then + log "Setting up the Plymouth splash via the plymouth module..." + run bash "$APPS/plymouth.sh" +else + skip "Skipping Plymouth setup (--no-plymouth)." +fi + +# ── Done ────────────────────────────────────────────────────────────────────── +echo +if (( DRY_RUN )); then + log "Dry run complete — no changes were made." +else + log "Migration complete. Your current session is untouched." + log "Reboot to boot into the Plymouth splash and the LightDM cyberqueer greeter." +fi diff --git a/setup/tui-install.sh b/setup/tui-install.sh index 5c141eb..7ba9b7b 100755 --- a/setup/tui-install.sh +++ b/setup/tui-install.sh @@ -367,6 +367,8 @@ count_steps() { [[ " $a " == *" wprs "* ]] && TOTAL=$(( TOTAL + 1 )) [[ " $a " == *" plymouth "* ]] && TOTAL=$(( TOTAL + 1 )) [[ " $a " == *" plymouth-custom "* ]] && TOTAL=$(( TOTAL + 1 )) + [[ " $a " == *" lightdm "* ]] && TOTAL=$(( TOTAL + 1 )) + [[ " $a " == *" ly "* ]] && TOTAL=$(( TOTAL + 1 )) [[ " $a " == *" steam "* ]] && TOTAL=$(( TOTAL + 1 )) [[ " $a " == *" vesktop "* ]] && TOTAL=$(( TOTAL + 1 )) [[ " $a " == *" spotify "* ]] && TOTAL=$(( TOTAL + 1 )) @@ -589,6 +591,8 @@ else "wprs" "wprs Wayland proxy for remote sessions (wprs-git, AUR)" off \ "plymouth" "plymouth boot splash — bundled skull logo and spinner" on \ "plymouth-custom" "plymouth-custom boot splash with a user-supplied image" off \ + "lightdm" "lightdm LightDM GTK greeter, cyberqueer-themed (HyprLua default)" off \ + "ly" "ly ly TUI display manager, cyberqueer-themed" off \ "steam" "steam Steam gaming platform" off \ "vesktop" "vesktop Discord client with Vencord theme" off \ "spotify" "spotify Spotify launcher with Spicetify theming" off \ @@ -700,6 +704,8 @@ if ! $ANSWERFILE_MODE; then [[ " $SELECTED_APPS " == *" wprs "* ]] && SUMMARY+=" ✦ wprs\n" [[ " $SELECTED_APPS " == *" plymouth "* ]] && SUMMARY+=" ✦ plymouth\n" [[ " $SELECTED_APPS " == *" plymouth-custom "* ]] && SUMMARY+=" ✦ plymouth-custom\n" + [[ " $SELECTED_APPS " == *" lightdm "* ]] && SUMMARY+=" ✦ lightdm\n" + [[ " $SELECTED_APPS " == *" ly "* ]] && SUMMARY+=" ✦ ly\n" [[ " $SELECTED_APPS " == *" steam "* ]] && SUMMARY+=" ✦ steam\n" [[ " $SELECTED_APPS " == *" vesktop "* ]] && SUMMARY+=" ✦ vesktop\n" [[ " $SELECTED_APPS " == *" spotify "* ]] && SUMMARY+=" ✦ spotify\n" @@ -804,6 +810,20 @@ if [[ " $SELECTED_APPS " == *" plymouth-custom "* && " $SELECTED_APPS " == *" pl SELECTED_APPS="${SELECTED_APPS# }" SELECTED_APPS="${SELECTED_APPS% }" fi +if [[ " $SELECTED_APPS " == *" lightdm "* && " $SELECTED_APPS " == *" ly "* ]]; then + warn "'lightdm' and 'ly' are mutually exclusive — deselecting 'ly'" + SELECTED_APPS=" $SELECTED_APPS " + SELECTED_APPS="${SELECTED_APPS/ ly / }" + SELECTED_APPS="${SELECTED_APPS# }" + SELECTED_APPS="${SELECTED_APPS% }" +fi +if [[ " $SELECTED_APPS " == *" ly "* && " $SELECTED_APPS " == *" lightdm "* ]]; then + warn "'ly' and 'lightdm' are mutually exclusive — deselecting 'lightdm'" + SELECTED_APPS=" $SELECTED_APPS " + SELECTED_APPS="${SELECTED_APPS/ lightdm / }" + SELECTED_APPS="${SELECTED_APPS# }" + SELECTED_APPS="${SELECTED_APPS% }" +fi # END GENERATED MODULES: module-conflicts # BEGIN GENERATED MODULES: module-dispatch [[ " $SELECTED_APPS " == *" ollama "* ]] && run_module "ollama" "$APPS/ollama.sh" @@ -840,6 +860,8 @@ fi [[ " $SELECTED_APPS " == *" wprs "* ]] && run_module "wprs" "$APPS/wprs.sh" [[ " $SELECTED_APPS " == *" plymouth "* ]] && run_module "plymouth" "$APPS/plymouth.sh" [[ " $SELECTED_APPS " == *" plymouth-custom "* ]] && run_module "plymouth-custom" "$APPS/plymouth-custom.sh" +[[ " $SELECTED_APPS " == *" lightdm "* ]] && run_module "lightdm" "$APPS/lightdm.sh" +[[ " $SELECTED_APPS " == *" ly "* ]] && run_module "ly" "$APPS/ly.sh" [[ " $SELECTED_APPS " == *" steam "* ]] && run_module "steam" "$APPS/steam.sh" [[ " $SELECTED_APPS " == *" vesktop "* ]] && run_module "vesktop" "$APPS/vesktop.sh" [[ " $SELECTED_APPS " == *" spotify "* ]] && run_module "spotify" "$APPS/spotify.sh"