diff --git a/sysupdate.sh b/sysupdate.sh index 1db80b2..e1e73e9 100755 --- a/sysupdate.sh +++ b/sysupdate.sh @@ -597,6 +597,75 @@ _fix_hypr_usr() { fi } +# Offer to redeploy hypr/usr/ (device-specific lua) from the dotfiles template, +# file by file. hypr/usr/ is excluded from the normal config-updater sync to +# preserve per-device customisation (monitors.lua, wallpaper.conf), but feature/ +# bind updates in autostart.lua, binds.lua, windowrules.lua etc. still land in +# the dotfiles template and need an explicit, reviewable opt-in to reach a +# machine that already has its own hypr/usr/. Skipped entirely on first-time +# setup — _migrate_hypr_usr already seeds usr/ from the template in that case. +_redeploy_usr_configs() { + local de_dir; de_dir=$(_de_source_dir) + local src_usr="${de_dir:+$de_dir/hypr/usr}" + local usr_dir="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/usr" + + [[ -n "${src_usr:-}" && -d "$src_usr" ]] || return 0 + [[ -d "$usr_dir" ]] || return 0 + + ask "Redeploy user-local configs (hypr/usr/)?" || { log "Skipped user-local config redeploy"; return 0; } + + local -a files=() + while IFS= read -r -d '' item; do + files+=("$(basename "$item")") + done < <(find "$src_usr" -maxdepth 1 -mindepth 1 -type f ! -name '*.old' -print0 | sort -z) + + if [[ ${#files[@]} -eq 0 ]]; then + warn "No template files found in $src_usr" + return 0 + fi + + local -a selected=() + if command -v dialog &>/dev/null; then + local items=() + for f in "${files[@]}"; do + local tag="on" + [[ "$f" == "monitors.lua" || "$f" == "wallpaper.conf" ]] && tag="off" + local status="new" + [[ -f "$usr_dir/$f" ]] && { diff -q "$usr_dir/$f" "$src_usr/$f" &>/dev/null && status="unchanged" || status="differs"; } + items+=("$f" "($status)" "$tag") + done + local chosen + chosen=$(dialog --stdout --separate-output \ + --title " Redeploy hypr/usr/ " \ + --checklist " SPACE = toggle | ENTER = confirm | ESC = cancel (monitors.lua / wallpaper.conf default OFF — device-specific) " \ + 0 70 0 "${items[@]}") || { warn "Cancelled — no user-local configs redeployed."; return 0; } + while IFS= read -r line; do + [[ -n "$line" ]] && selected+=("$line") + done <<< "$chosen" + else + warn "'dialog' not installed — redeploying all except monitors.lua/wallpaper.conf" + for f in "${files[@]}"; do + [[ "$f" == "monitors.lua" || "$f" == "wallpaper.conf" ]] && continue + selected+=("$f") + done + fi + + if [[ ${#selected[@]} -eq 0 ]]; then + warn "Nothing selected — no user-local configs redeployed." + return 0 + fi + + for f in "${selected[@]}"; do + if cp -p "$src_usr/$f" "$usr_dir/$f"; then + ok "redeployed hypr/usr/$f" + else + err "failed hypr/usr/$f" + fi + done + + _fix_hypr_usr +} + # Deploy root-owned greeter config (/etc/greetd) that config-updater can't reach. # Only when greetd is the active greeter on this machine. Uses the sudo credential # primed once at startup, so it doesn't re-prompt. PAM is intentionally left to the @@ -613,13 +682,95 @@ _deploy_greetd() { ok "greetd config deployed" || warn "greetd config deploy had errors" } +# Ensure this machine has finished the Plymouth + greetd/ReGreet boot/login +# migration. Delegates entirely to setup/tools/migrate-to-greetd.sh (idempotent, +# already handles old-DM detection/teardown, PAM/FIDO, wallpaper sync, initramfs +# + GRUB) rather than duplicating that logic here. Skips silently once the +# machine is already on the target stack. +_ensure_plymouth_regreet() { + local migrate_tool="$DOTFILES/setup/tools/migrate-to-greetd.sh" + [[ -x "$migrate_tool" ]] || return 0 + + local greetd_state; greetd_state=$(systemctl is-enabled greetd.service 2>/dev/null || true) + local using_regreet=false + grep -q 'regreet' /etc/greetd/config.toml 2>/dev/null && using_regreet=true + local plymouth_ok=false + pacman -Qq plymouth &>/dev/null && [[ -d /usr/share/plymouth/themes/m-archy ]] && plymouth_ok=true + + if [[ "$greetd_state" == "enabled" && "$using_regreet" == true && "$plymouth_ok" == true ]]; then + ok "Plymouth + greetd/ReGreet already active" + return 0 + fi + + warn "Not yet on Plymouth + greetd/ReGreet (currently: greetd=${greetd_state}, regreet=${using_regreet}, plymouth=${plymouth_ok})" + if ask "Migrate now? (installs plymouth+regreet+cage, rebuilds initramfs; reboot needed after)"; then + "$migrate_tool" --yes + fi +} + +# Ensure the Astal GObject typelibs astal-menu's main.py imports at startup are +# installed. config-updater only copies the astal-menu/ config directory — it +# never installs packages — so a machine that's never run the AUR install is +# missing these even after a full config sync. +_ensure_astal_menu_deps() { + local de_dir; de_dir=$(_de_source_dir) + [[ "${de_dir:-}" == */hyprlua ]] || return 0 + [[ -d "$de_dir/astal-menu" ]] || return 0 + + local -a needed=(libastal-network-git libastal-bluetooth-git libastal-apps-git) + local -a missing=() + for pkg in "${needed[@]}"; do + pacman -Qq "$pkg" &>/dev/null || missing+=("$pkg") + done + + if [[ ${#missing[@]} -eq 0 ]]; then + ok "astal-menu AUR deps already installed" + return 0 + fi + + warn "astal-menu is missing AUR deps: ${missing[*]}" + if ask "Install them now?"; then + if yay -S --noconfirm --needed "${missing[@]}"; then + ok "astal-menu deps installed" + else + warn "Failed to install some astal-menu deps" + fi + fi +} + +# Ensure hyprshutdown is installed. hypr/usr/binds.lua's power binds +# (Super+Shift/Ctrl/Ctrl+Shift+O) call it directly; without it those binds +# silently no-op. It's in the official extra repo, not AUR. +_ensure_hyprshutdown() { + local de_dir; de_dir=$(_de_source_dir) + [[ "${de_dir:-}" == */hyprlua ]] || return 0 + + if pacman -Qq hyprshutdown &>/dev/null; then + ok "hyprshutdown already installed" + return 0 + fi + + warn "hyprshutdown is missing — the power binds in hypr/usr/binds.lua will no-op without it" + if ask "Install it now?"; then + if sudo pacman -S --noconfirm --needed hyprshutdown; then + ok "hyprshutdown installed" + else + warn "Failed to install hyprshutdown" + fi + fi +} + sync_configs() { section "Config Sync" # ── Migration: old flat layout → hypr/usr/ ─────────────────────────────── _migrate_hypr_usr _fix_hypr_usr + _redeploy_usr_configs _deploy_greetd + _ensure_plymouth_regreet + _ensure_astal_menu_deps + _ensure_hyprshutdown # ── Preferred: use the installed update-configs.sh ─────────────────────── local cfg_script