diff --git a/docs/md/installation.md b/docs/md/installation.md index 8eafd2b..ca7d752 100644 --- a/docs/md/installation.md +++ b/docs/md/installation.md @@ -35,7 +35,7 @@ The TUI walks you through: - `core` — 100+ base system packages - `svc` — core services (NetworkManager, cronie, fail2ban, greetd) - `shell` — zsh, Neovim, Yazi, Micro, Starship - - `plymouth` — boot splash screen (skull logo + magenta spinner, **on by default**) + - `plymouth` — boot splash screen (skull logo + boot-log tail, **on by default**) 3. **Desktop Environment** — HyprLua, Niri, Hyprland, Sway, KDE Plasma, GNOME, COSMIC, XFCE, LXQt, or none 4. **Applications** — checklist of ~50 optional apps (see [Modules](modules.md)) 5. **Colorway** — optional; enter hex values to customise the CyberQueer palette diff --git a/docs/md/modules.md b/docs/md/modules.md index 3b834bc..7edd214 100644 --- a/docs/md/modules.md +++ b/docs/md/modules.md @@ -133,7 +133,7 @@ bash ~/Dotfiles/setup/install-modules.sh | `timeshift` | system snapshot and backup with autosnap | | `zfs` | zfs-dkms kernel module | | `wprs` | Wayland proxy for remote sessions (wprs-git, AUR) | -| `plymouth` | boot splash — bundled skull logo and spinner | +| `plymouth` | boot splash — bundled skull logo + boot-log tail | | `plymouth-custom` | boot splash with a user-supplied image | | `lightdm` | LightDM GTK greeter, cyberqueer-themed (HyprLua default) | | `ly` | ly TUI display manager, cyberqueer-themed | diff --git a/resources/bg-skull.svg b/resources/bg-skull.svg index 230d044..128441e 100644 --- a/resources/bg-skull.svg +++ b/resources/bg-skull.svg @@ -1,63 +1,2 @@ - - - - + + diff --git a/setup/install-modules.sh b/setup/install-modules.sh index 1eae7c1..ddc6340 100755 --- a/setup/install-modules.sh +++ b/setup/install-modules.sh @@ -212,7 +212,7 @@ SELECTED=$(dialog --backtitle "$BACKTITLE" \ "ffmpeg" "FFmpeg extras thumbnailer · GStreamer codecs" off \ "localtunnel" "LocalTunnel expose localhost via tunnel" off \ "butter" "butter btrfs snapshot backup (AUR)" off \ - "plymouth" "Plymouth boot splash — skull logo + spinner" off \ + "plymouth" "Plymouth boot splash — skull logo + boot-log tail" 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 \ diff --git a/setup/modules.conf b/setup/modules.conf index e07da11..17233b8 100644 --- a/setup/modules.conf +++ b/setup/modules.conf @@ -49,7 +49,7 @@ localtunnel|system|expose localhost over a public URL|off| timeshift|system|system snapshot and backup with autosnap|on| 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|system|boot splash — bundled skull logo + boot-log tail|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 diff --git a/setup/modules/optional-Modules/apps/plymouth.sh b/setup/modules/optional-Modules/apps/plymouth.sh index 5f43ba1..66cdfe7 100644 --- a/setup/modules/optional-Modules/apps/plymouth.sh +++ b/setup/modules/optional-Modules/apps/plymouth.sh @@ -1,9 +1,9 @@ #!/bin/bash # plymouth.sh — Plymouth boot splash installer # -# 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. +# Installs the M-Archy Plymouth theme: the magenta skull-monitor logo centred +# on a dark background, with the latest 3 boot-log lines polled underneath it +# as plain text (no spinner). # # 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,14 +19,13 @@ # # Steps: # 1. Install plymouth (extra repo) -# 2. Install librsvg (rsvg-convert) if logo is SVG; imagemagick for dot -# 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 -# 7. Inject plymouth / sd-plymouth hook into /etc/mkinitcpio.conf -# 8. Add 'quiet splash' to GRUB_CMDLINE_LINUX_DEFAULT -# 9. Regenerate GRUB config and initramfs +# 2. Install librsvg (rsvg-convert) if logo is SVG +# 3. Produce logo.png (600 px wide) from the resolved source +# 4. Write the m-archy theme (.plymouth descriptor + .script animation) +# 5. Register with plymouth-set-default-theme +# 6. Inject plymouth / sd-plymouth hook into /etc/mkinitcpio.conf +# 7. Add 'quiet splash' to GRUB_CMDLINE_LINUX_DEFAULT +# 8. Regenerate GRUB config and initramfs set -euo pipefail source "$(dirname "${BASH_SOURCE[0]}")/../../lib/logging.sh" @@ -54,22 +53,17 @@ fi log "Installing Plymouth..." sudo pacman -S --noconfirm --needed plymouth -# ── Ensure conversion tools ─────────────────────────────────────────────────── -# imagemagick is always needed for the spinner dot. -# librsvg (rsvg-convert) is only needed when the logo source is an SVG. -if ! command -v convert &>/dev/null; then - log "Installing imagemagick (dot generation)..." - sudo pacman -S --noconfirm --needed imagemagick -fi - # ── Produce logo.png ────────────────────────────────────────────────────────── TMP_LOGO="$(mktemp /tmp/plymouth-logo.XXXXXX.png)" -TMP_DOT="/tmp/plymouth-dot.png" -trap 'rm -f "$TMP_LOGO" "$TMP_DOT"' EXIT +trap 'rm -f "$TMP_LOGO"' EXIT if [[ -z "$LOGO_SRC" ]]; then warn "No logo source found — using transparent placeholder." - convert -size 1920x1080 xc:transparent "$TMP_LOGO" + if ! command -v convert &>/dev/null; then + log "Installing imagemagick (placeholder generation)..." + sudo pacman -S --noconfirm --needed imagemagick + fi + convert -size 600x600 xc:transparent "$TMP_LOGO" elif [[ "${LOGO_SRC,,}" == *.png ]]; then log "Using PNG directly: $LOGO_SRC" cp "$LOGO_SRC" "$TMP_LOGO" @@ -79,29 +73,22 @@ else log "Installing librsvg (rsvg-convert) for SVG→PNG conversion..." sudo pacman -S --noconfirm --needed librsvg fi - # 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" + # Render at 600 px wide — the skull is centred (not full-screen), and the + # Plymouth script scales it down to a fraction of the display height, so we + # only need enough resolution to stay crisp on high-DPI panels. + log "Converting $LOGO_SRC → PNG (600 px wide)..." + rsvg-convert -w 600 "$LOGO_SRC" -o "$TMP_LOGO" fi -# ── Generate spinner dot ────────────────────────────────────────────────────── -# 10×10 magenta circle — centred at (5,5), radius 4 px -convert -size 10x10 xc:transparent \ - -fill '#E40046' \ - -draw 'circle 5,5 5,1' \ - "$TMP_DOT" - # ── Install theme files ─────────────────────────────────────────────────────── log "Installing M-Archy Plymouth theme..." sudo mkdir -p "$THEME_DIR" sudo cp "$TMP_LOGO" "$THEME_DIR/logo.png" -sudo cp "$TMP_DOT" "$THEME_DIR/dot.png" sudo tee "$THEME_DIR/m-archy.plymouth" > /dev/null <<'EOF' [Plymouth Theme] Name=M-Archy -Description=M-Archy boot splash — skull logo with spinning dots +Description=M-Archy boot splash — centred skull logo with a boot-log tail ModuleName=script [script] @@ -110,7 +97,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 — full-screen skull background + magenta spinner +# M-Archy Plymouth splash — centred skull logo + latest 3 boot-log lines. Window.SetBackgroundTopColor (0.10, 0.10, 0.10); Window.SetBackgroundBottomColor (0.07, 0.07, 0.07); @@ -118,47 +105,65 @@ Window.SetBackgroundBottomColor (0.07, 0.07, 0.07); screen_width = Window.GetWidth (); screen_height = Window.GetHeight (); -# 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"); -scaled = logo.image.Scale (screen_width, screen_height); +# ── Skull logo, centred ─────────────────────────────────────────────────────── +# logo.png is the tight skull-monitor artwork (roughly square). Scale it to a +# fraction of the screen height, preserving aspect ratio, then centre it and +# nudge it up a little so the log lines below have room to breathe. +logo.image = Image ("logo.png"); +target_h = screen_height * 0.42; +scale = target_h / logo.image.GetHeight (); +scaled = logo.image.Scale (logo.image.GetWidth () * scale, target_h); + logo.sprite = Sprite (scaled); -logo.sprite.SetX (0); -logo.sprite.SetY (0); +logo.sprite.SetX ((screen_width - scaled.GetWidth ()) / 2); +logo.sprite.SetY ((screen_height - scaled.GetHeight ()) / 2 - screen_height * 0.08); logo.sprite.SetZ (10); -# 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 = Math.Int (screen_height * 0.93); -dot.image = Image ("dot.png"); +# ── Boot-log tail — latest 3 lines ──────────────────────────────────────────── +# A rolling buffer of the three most recent status/message strings Plymouth +# hands us, drawn as centred text beneath the logo. The newest line is the +# brightest; older lines fade back. +num_lines = 3; +line_gap = 26; # px between successive baselines +text_top = Math.Int (screen_height * 0.72); # y of the oldest (top) line -for (i = 0; i < num_dots; i++) { - dot[i].sprite = Sprite (dot.image); - dot[i].sprite.SetZ (20); +for (i = 0; i < num_lines; i++) { + log_line[i] = ""; + log_sprite[i] = Sprite (); + log_sprite[i].SetZ (20); } -frame = 0; - -fun refresh_callback () { - frame++; - step = 2 * Math.Pi / num_dots; - for (i = 0; i < num_dots; i++) { - angle = step * i + frame * 0.15; - dot[i].sprite.SetX (Math.Int (cx + Math.Cos (angle) * orbit - dot_r)); - dot[i].sprite.SetY (Math.Int (cy + Math.Sin (angle) * orbit - dot_r)); - t = (i + Math.Int (frame / 4) % num_dots) % num_dots; - f = t / num_dots; - dot[i].sprite.SetOpacity (0.15 + 0.85 * f * f); +fun draw_lines () { + for (i = 0; i < num_lines; i++) { + # Empty slots (before the buffer fills) stay hidden — Image.Text ("") + # is unreliable across Plymouth versions, so never render it. + if (log_line[i] == "") { + log_sprite[i].SetOpacity (0); + } else { + shade = 0.40 + 0.25 * i; # 0.40, 0.65, 0.90 top→bottom + image = Image.Text (log_line[i], shade, shade, shade); + log_sprite[i].SetImage (image); + log_sprite[i].SetX ((screen_width - image.GetWidth ()) / 2); + log_sprite[i].SetY (text_top + i * line_gap); + log_sprite[i].SetOpacity (1); + } } } -Plymouth.SetRefreshFunction (refresh_callback); +fun push_line (text) { + # Scroll the buffer up by one line and append the newcomer at the bottom. + for (i = 0; i < num_lines - 1; i++) { + log_line[i] = log_line[i + 1]; + } + log_line[num_lines - 1] = text; + draw_lines (); +} + +# Both callbacks feed the same tail: systemd unit progress arrives via the +# status function, explicit `plymouth display-message` strings via the message +# function. +Plymouth.SetUpdateStatusFunction (fun (status) { push_line (status); }); +Plymouth.SetDisplayMessageFunction (fun (text) { push_line (text); }); EOF # ── Register theme ──────────────────────────────────────────────────────────── diff --git a/setup/tools/generate-answerfile.sh b/setup/tools/generate-answerfile.sh index 264637d..e806cff 100755 --- a/setup/tools/generate-answerfile.sh +++ b/setup/tools/generate-answerfile.sh @@ -272,7 +272,7 @@ if [[ "$AF_RUN_TUI" == "true" ]]; then "timeshift" "timeshift system snapshot and backup with autosnap" on \ "zfs" "zfs zfs-dkms kernel module" off \ "wprs" "wprs Wayland proxy for remote sessions (wprs-git, AUR)" off \ - "plymouth" "plymouth boot splash — bundled skull logo and spinner" on \ + "plymouth" "plymouth boot splash — bundled skull logo + boot-log tail" 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 \ diff --git a/setup/tools/migrate-to-lightdm.sh b/setup/tools/migrate-to-lightdm.sh index a0febd7..ccdd046 100755 --- a/setup/tools/migrate-to-lightdm.sh +++ b/setup/tools/migrate-to-lightdm.sh @@ -14,13 +14,21 @@ # 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 +# 4. Purges obsolete Plymouth artifacts left by earlier versions of this repo +# (e.g. the spinner's dot.png) so an upgraded install ends up byte-clean. +# 5. 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. # +# Double duty: on a machine that is ALREADY on Plymouth + LightDM (an install +# migrated by an earlier version of this repo) re-running simply refreshes the +# greeter config and re-installs the current Plymouth theme — the clean upgrade +# path from the old full-screen-skull + spinner splash to the centred-skull + +# boot-log-tail one. +# # Safe to re-run (idempotent). Reboot to complete the switch. # # Usage: @@ -177,6 +185,19 @@ run bash "$APPS/lightdm.sh" # ── 5. Plymouth splash (delegated to the module) ────────────────────────────── if (( DO_PLYMOUTH )); then + # Upgrade cleanup: the current theme is a centred skull + boot-log tail. The + # previous version scaled the skull full-screen and drew a spinning-dot + # throbber from dot.png. That file is now dead weight — strip it (and any + # other stale theme assets) BEFORE re-running the module, so it is neither + # rendered nor baked into the initramfs that plymouth.sh rebuilds. + THEME_DIR="/usr/share/plymouth/themes/m-archy" + for stale in "$THEME_DIR/dot.png"; do + if [[ -e "$stale" ]]; then + log "Removing obsolete Plymouth asset: $stale" + run sudo rm -f "$stale" + fi + done + log "Setting up the Plymouth splash via the plymouth module..." run bash "$APPS/plymouth.sh" else diff --git a/setup/tui-install.sh b/setup/tui-install.sh index 7ba9b7b..9220a73 100755 --- a/setup/tui-install.sh +++ b/setup/tui-install.sh @@ -589,7 +589,7 @@ else "timeshift" "timeshift system snapshot and backup with autosnap" on \ "zfs" "zfs zfs-dkms kernel module" off \ "wprs" "wprs Wayland proxy for remote sessions (wprs-git, AUR)" off \ - "plymouth" "plymouth boot splash — bundled skull logo and spinner" on \ + "plymouth" "plymouth boot splash — bundled skull logo + boot-log tail" 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 \