Open the update terminal in Ghostty, offering to install it via pkexec when missing and falling back to foot if declined. Add the system-update-terminal window rule the script already referred to, so the window floats centred at 1000x650 instead of tiling. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
106 lines
4.9 KiB
Bash
Executable File
106 lines
4.9 KiB
Bash
Executable File
#!/bin/bash
|
|
# Launched by SystemUpdate.qml (top bar, next to the clock) — opens a
|
|
# terminal running whatever update command fits this distro, then notifies
|
|
# once it's done. Ported from the old waybar custom/updater module
|
|
# (.config/waybar/scripts/update-distro.sh); kept multi-distro even though
|
|
# this machine is Arch, since these dotfiles aren't.
|
|
#
|
|
# The window it opens is floated + centered by a matching Hyprland rule
|
|
# (system-update-terminal, in .config/hypr/layout/windowrules.lua),
|
|
# same treatment as Bitwarden's window, rather than tiling into whatever
|
|
# workspace you happened to be on.
|
|
|
|
iDIR="$HOME/.config/swaync/images"
|
|
|
|
# Printed inside the terminal before the actual update command runs, so it
|
|
# reads as "updating" from the first frame rather than looking like an
|
|
# empty/stuck window while pacman/apt/etc. take a moment to start printing.
|
|
#
|
|
# The terminal runs this in a fresh `bash -c`, which doesn't inherit shell
|
|
# functions from this script's own environment (export -f only reaches bash
|
|
# processes forked from *this* one, not whatever the terminal execs) — so
|
|
# instead, the already-colored text is built once here with real escape
|
|
# bytes ($'...'), then %q-quoted into a self-contained `echo '...'` that
|
|
# reproduces those same bytes verbatim when the child bash parses it.
|
|
msg=" Updating System — please wait "
|
|
line=$(printf '=%.0s' $(seq 1 ${#msg}))
|
|
banner_text=$'\033[1;36m'"$line"$'\033[0m\n\033[1;36m'"$msg"$'\033[0m\n\033[1;36m'"$line"$'\033[0m\n\n'
|
|
BANNER="echo $(printf '%q' "$banner_text")"
|
|
|
|
# GHOSTTY_INSTALL is how to install the terminal on this distro, if it's
|
|
# packaged there at all — only Arch ships it in the official repos.
|
|
if command -v paru &> /dev/null; then
|
|
CMD="paru -Syu"
|
|
LABEL="Arch-based system"
|
|
GHOSTTY_INSTALL="pacman -S --needed --noconfirm ghostty"
|
|
elif command -v yay &> /dev/null; then
|
|
CMD="yay -Syu"
|
|
LABEL="Arch-based system"
|
|
GHOSTTY_INSTALL="pacman -S --needed --noconfirm ghostty"
|
|
elif command -v dnf &> /dev/null; then
|
|
CMD="sudo dnf update --refresh -y"
|
|
LABEL="Fedora system"
|
|
elif command -v apt &> /dev/null; then
|
|
CMD="sudo apt update && sudo apt upgrade -y"
|
|
LABEL="Debian/Ubuntu system"
|
|
elif command -v zypper &> /dev/null; then
|
|
CMD="sudo zypper dup -y"
|
|
LABEL="openSUSE system"
|
|
else
|
|
notify-send -i "$iDIR/error.png" -u critical "Unsupported system" "This script does not support your distribution."
|
|
exit 1
|
|
fi
|
|
|
|
# --- Terminal: Ghostty, offering to install it if missing ---
|
|
# This runs from the bar with no terminal of its own, so there's nowhere to
|
|
# type a sudo password — the install goes through pkexec instead, which
|
|
# pops up the polkit agent's graphical password prompt. Declining (or a
|
|
# failed install) falls back to foot for this run, so updating never gets
|
|
# blocked on the terminal choice.
|
|
if ! command -v ghostty &> /dev/null; then
|
|
if [ -n "$GHOSTTY_INSTALL" ]; then
|
|
# -A waits for a click and prints the chosen action's name (nothing if
|
|
# the notification is dismissed instead).
|
|
choice=$(notify-send -i "$iDIR/error.png" -u critical \
|
|
-A install="Install Ghostty" -A foot="Use foot this time" \
|
|
"Ghostty not installed" "The system updater runs in Ghostty. Install it now?")
|
|
if [ "$choice" = "install" ]; then
|
|
if pkexec $GHOSTTY_INSTALL; then
|
|
notify-send -i "$iDIR/profile-pic.jpg" -u low "Ghostty installed" "Starting the update..."
|
|
else
|
|
notify-send -i "$iDIR/error.png" "Ghostty install failed" "Using foot for this update."
|
|
fi
|
|
fi
|
|
else
|
|
notify-send -i "$iDIR/error.png" "Ghostty not installed" \
|
|
"Install Ghostty for the system updater — using foot for now."
|
|
fi
|
|
fi
|
|
|
|
if command -v ghostty &> /dev/null; then
|
|
# --gtk-single-instance=false: otherwise, with a Ghostty window already
|
|
# open, this would just hand the window off to that running instance and
|
|
# return immediately — SystemUpdates.qml relies on this script blocking
|
|
# until the update window is closed (that's when it re-checks the count),
|
|
# and the "has been updated" notification below would fire up front.
|
|
TERMINAL=(ghostty --gtk-single-instance=false --title=update -e)
|
|
elif command -v foot &> /dev/null; then
|
|
TERMINAL=(foot -T update)
|
|
else
|
|
notify-send -i "$iDIR/error.png" "Need a terminal:" "Neither Ghostty nor foot is installed."
|
|
exit 1
|
|
fi
|
|
|
|
# Keeps the terminal open (whether the update succeeded or failed — read
|
|
# always runs regardless, since it's ; not &&) until you press Enter,
|
|
# instead of the terminal closing the instant the update command exits and
|
|
# taking any output/errors with it.
|
|
WAIT_PROMPT="echo; read -p 'Update finished — press Enter to close...'"
|
|
|
|
# Pull + re-stow the dotfiles first, so config changes from the other machine
|
|
# land alongside the package update.
|
|
SYNC="$(printf '%q' "$(dirname "$0")/sync-dotfiles.sh")"
|
|
|
|
"${TERMINAL[@]}" bash -c "$BANNER; $SYNC; $CMD; $WAIT_PROMPT"
|
|
notify-send -i "$iDIR/profile-pic.jpg" -u low "$LABEL" 'has been updated.'
|