Name: sl-toolbox Version: 1.2.2 Release: 100.1.1%{?dist} Summary: Sl's centralized toolbox interface for Fedora License: Apache-2.0 URL: https://slsrepo.com BuildArch: noarch Requires: bash Requires: dnf Requires: curl Requires: sudo Requires: gum Requires: ncurses %description Sl's centralized Fedora package toolbox for installing and managing Slash packages from the COPR repository. %prep # Nothing to prepare. %build cat > sl-toolbox <<'EOF' #!/usr/bin/env bash set -u # Initialize the alternate screen and catch force-quits. tput smcup 2>/dev/null || true clear trap 'tput rmcup 2>/dev/null || true; exit 0' SIGINT SIGTERM EXIT pause_for_logs() { echo "" read -r -p "➜ Press Enter to return to menu..." echo "" } print_banner() { clear echo -e "\e[38;5;25m" cat << "BANNER" _____ _ _ _____ _ _ / ___|| ( )___ |_ _|__ ___ | | |__ _____ __ \___ \| |// __| | |/ _ \ / _ \| | '_ \ / _ \ \/ / ___) | | \__ \ | | (_) | (_) | | |_) | (_) > < |____/|_| |___/ |_|\___/ \___/|_|_.__/ \___/_/\_\ BANNER echo -e "\e[0m" echo "" } sl_menu() { gum choose \ --cursor="➜ " \ --cursor.foreground="#42a5f5" \ --selected.foreground="#42a5f5" \ --header.foreground="#1b7ece" \ --selected.bold \ "$@" } need_sudo() { if [ "$EUID" -eq 0 ]; then return 0 fi sudo -v } install_pkg() { local pkg="$1" print_banner echo "Installing $pkg..." echo "" need_sudo || { echo "Could not get sudo privileges." pause_for_logs return } sudo dnf install -y "$pkg" pause_for_logs } enable_slash_copr() { print_banner echo "Enabling SLASH COPR repository..." echo "" need_sudo || { echo "Could not get sudo privileges." pause_for_logs return } sudo dnf install -y dnf-plugins-core sudo dnf copr enable -y slsrepo/slash pause_for_logs } enable_kernel_sl_copr() { print_banner echo "Enabling kernel-sl COPR repository..." echo "" need_sudo || { echo "Could not get sudo privileges." pause_for_logs return } sudo dnf install -y dnf-plugins-core sudo dnf copr enable -y slsrepo/kernel-sl pause_for_logs } list_available_kernel_versions() { # Do not use repoquery --queryformat here. DNF 5 can print unsupported # query tags literally, which is how we ended up showing %{nevra} before. dnf list --showduplicates --available kernel 2>/dev/null || \ dnf list --showduplicates kernel 2>/dev/null || true } find_latest_kernel_sl_evr() { local variant="$1" local arch arch="$(uname -m)" list_available_kernel_versions | awk -v variant="$variant" -v arch="$arch" ' $1 == "kernel." arch { evr = $2 if (variant == "v3") { if (evr ~ /\.sl\.v3\./) print evr } else { if (evr ~ /\.sl\./ && evr !~ /\.sl\.v3\./) print evr } } ' | sort -V | tail -n 1 } show_available_sl_kernels() { local arch arch="$(uname -m)" list_available_kernel_versions | awk -v arch="$arch" ' $1 == "kernel." arch && $2 ~ /\.sl(\.v3)?\./ { print " " $1 " " $2 } ' | sort -V || true } install_kernel_sl_package() { local variant="$1" local label="$2" local arch evr pkg print_banner echo "Installing $label..." echo "" arch="$(uname -m)" if [ "$arch" != "x86_64" ]; then echo "kernel-sl COPR builds are x86_64-only." pause_for_logs return fi need_sudo || { echo "Could not get sudo privileges." pause_for_logs return } sudo dnf install -y dnf-plugins-core sudo dnf copr enable -y slsrepo/kernel-sl evr="$(find_latest_kernel_sl_evr "$variant")" if [ -z "$evr" ]; then echo "No matching $label package was found in the enabled repositories." echo "" echo "Available SL kernel packages:" show_available_sl_kernels pause_for_logs return fi pkg="kernel-${evr}.${arch}" echo "Installing $pkg" echo "" if ! sudo dnf install -y "$pkg"; then echo "" echo "DNF did not accept $pkg. Trying without the arch suffix..." sudo dnf install -y "kernel-${evr}" fi echo "" echo "$label installed. Reboot to use the new kernel." pause_for_logs } kernel_menu() { while true; do print_banner choice=$(sl_menu --header="--- Sl's Fedora Kernel ---" \ "Enable kernel-sl COPR Repository" \ "Install kernel-sl" \ "Install kernel-sl-v3" \ "Back") case "$choice" in "Enable kernel-sl COPR Repository") enable_kernel_sl_copr ;; "Install kernel-sl") install_kernel_sl_package "generic" "kernel-sl" ;; "Install kernel-sl-v3") install_kernel_sl_package "v3" "kernel-sl-v3" ;; "Back"|"") return ;; esac done } optimize_dnf() { print_banner echo "Optimizing DNF..." echo "" need_sudo || { echo "Could not get sudo privileges." pause_for_logs return } sudo mkdir -p /etc/dnf sudo touch /etc/dnf/dnf.conf sudo grep -q '^fastestmirror=' /etc/dnf/dnf.conf \ && sudo sed -i 's/^fastestmirror=.*/fastestmirror=True/' /etc/dnf/dnf.conf \ || echo 'fastestmirror=True' | sudo tee -a /etc/dnf/dnf.conf >/dev/null sudo grep -q '^max_parallel_downloads=' /etc/dnf/dnf.conf \ && sudo sed -i 's/^max_parallel_downloads=.*/max_parallel_downloads=10/' /etc/dnf/dnf.conf \ || echo 'max_parallel_downloads=10' | sudo tee -a /etc/dnf/dnf.conf >/dev/null sudo grep -q '^defaultyes=' /etc/dnf/dnf.conf \ && sudo sed -i 's/^defaultyes=.*/defaultyes=True/' /etc/dnf/dnf.conf \ || echo 'defaultyes=True' | sudo tee -a /etc/dnf/dnf.conf >/dev/null sudo grep -q '^keepcache=' /etc/dnf/dnf.conf \ && sudo sed -i 's/^keepcache=.*/keepcache=True/' /etc/dnf/dnf.conf \ || echo 'keepcache=True' | sudo tee -a /etc/dnf/dnf.conf >/dev/null echo "" echo "DNF config updated:" grep -E '^(fastestmirror|max_parallel_downloads|defaultyes|keepcache)=' /etc/dnf/dnf.conf || true pause_for_logs } clean_dnf_cache() { print_banner echo "Cleaning DNF cache..." echo "" need_sudo || { echo "Could not get sudo privileges." pause_for_logs return } sudo dnf clean all pause_for_logs } install_dnf_automatic() { print_banner echo "Installing and enabling automatic DNF updates..." echo "" need_sudo || { echo "Could not get sudo privileges." pause_for_logs return } if sudo dnf install -y dnf5-plugin-automatic; then if systemctl list-unit-files dnf5-automatic.timer >/dev/null 2>&1; then sudo systemctl enable --now dnf5-automatic.timer systemctl status dnf5-automatic.timer --no-pager || true else echo "dnf5-plugin-automatic installed, but dnf5-automatic.timer was not found." echo "Trying classic dnf-automatic instead..." sudo dnf install -y dnf-automatic sudo systemctl enable --now dnf-automatic.timer systemctl status dnf-automatic.timer --no-pager || true fi else sudo dnf install -y dnf-automatic sudo systemctl enable --now dnf-automatic.timer systemctl status dnf-automatic.timer --no-pager || true fi pause_for_logs } show_enabled_repos() { print_banner echo "Enabled DNF repositories:" echo "" dnf repolist --enabled || true pause_for_logs } set_graphical_session_default() { print_banner echo "Setting the graphical session as the default boot target..." echo "" need_sudo || { echo "Could not get sudo privileges." pause_for_logs return } echo "Current default target:" systemctl get-default echo "" echo "Installing the Wayland shell session integration package..." sudo dnf install wayland-shell-session-dvt echo "" echo "Setting graphical.target as the default boot target..." sudo systemctl set-default graphical.target echo "" echo "New default target:" systemctl get-default echo "" echo "The graphical session is now configured as the default boot target." echo "Please reboot the system for the change to take effect." pause_for_logs } configure_system_locale() { print_banner echo "Add and set a system locale" echo "" echo "Current locale configuration:" localectl status 2>/dev/null || true echo "" local selected_locale local lang_code selected_locale="$(gum input --header="Enter a locale to add and use" --placeholder="For example: en_US.UTF-8 or he_IL.UTF-8")" if [ -z "$selected_locale" ]; then return fi need_sudo || { echo "Could not get sudo privileges." pause_for_logs return } if [[ "$selected_locale" =~ ^([A-Za-z]{2,3})_ ]]; then lang_code="${BASH_REMATCH[1],,}" echo "" echo "Installing Fedora language pack: glibc-langpack-$lang_code" sudo dnf install -y "glibc-langpack-$lang_code" fi echo "" echo "Setting LANG=$selected_locale..." if ! sudo localectl set-locale "LANG=$selected_locale"; then echo "" echo "Could not set $selected_locale." echo "Check available locales with: localectl list-locales" pause_for_logs return fi echo "" echo "Updated locale configuration:" localectl status echo "" echo "The locale is configured for new sessions." echo "Log out and back in, or reboot, to apply it everywhere." pause_for_logs } setup_slash_desktop() { print_banner echo "Setting up SLASH on this Fedora system..." echo "" echo "This installs Sl's desktop packages with Niri/greetd integration for sl-greeter." echo "" need_sudo || { echo "Could not get sudo privileges." pause_for_logs return } echo "Enabling the SLASH COPR repository..." sudo dnf install -y dnf-plugins-core sudo dnf copr enable -y slsrepo/slash echo "" echo "Installing the SLASH desktop..." sudo dnf install -y sl-desktop-full sl-taskbar sl-menubar sl-dock sl-duobar wayland-shell-session-dvt echo "" echo "Configuring sl-greeter and graphical boot..." sudo systemctl daemon-reload sudo systemctl disable gdm.service >/dev/null 2>&1 || true sudo systemctl enable greetd.service sudo ln -sfn /usr/lib/systemd/system/greetd.service /etc/systemd/system/display-manager.service sudo systemctl set-default graphical.target echo "" echo "SLASH setup is complete." echo "Please reboot the system to start the graphical session." pause_for_logs } upgrade_system() { print_banner echo "Upgrading Fedora packages..." echo "" need_sudo || { echo "Could not get sudo privileges." pause_for_logs return } sudo dnf upgrade -y pause_for_logs } enable_rpmfusion() { print_banner echo "Enabling RPM Fusion free and nonfree repositories..." echo "" need_sudo || { echo "Could not get sudo privileges." pause_for_logs return } sudo dnf install -y \ "https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %%fedora).noarch.rpm" \ "https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %%fedora).noarch.rpm" pause_for_logs } enable_flathub() { print_banner echo "Enabling Flathub system-wide..." echo "" need_sudo || { echo "Could not get sudo privileges." pause_for_logs return } sudo dnf install -y flatpak sudo flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo pause_for_logs } add_terra_repository() { print_banner echo "Adding Terra repository..." echo "" need_sudo || { echo "Could not get sudo privileges." pause_for_logs return } sudo dnf install -y --nogpgcheck --repofrompath 'terra,https://repos.fyralabs.com/terra$releasever' terra-release pause_for_logs } install_appimage_support() { print_banner echo "Installing AppImage support and Gear Lever..." echo "" need_sudo || { echo "Could not get sudo privileges." pause_for_logs return } sudo dnf install -y fuse-libs flatpak sudo flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo flatpak install -y flathub it.mijorus.gearlever pause_for_logs } install_gnome_tools() { print_banner echo "Installing GNOME Tweaks and Extension Manager..." echo "" need_sudo || { echo "Could not get sudo privileges." pause_for_logs return } sudo dnf install -y gnome-tweaks flatpak sudo flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo flatpak install -y flathub com.mattjakeman.ExtensionManager pause_for_logs } install_multimedia_codecs() { print_banner echo "Installing multimedia codecs from RPM Fusion..." echo "" echo "This may swap ffmpeg-free for full ffmpeg and upgrade multimedia groups." echo "" need_sudo || { echo "Could not get sudo privileges." pause_for_logs return } sudo dnf swap -y ffmpeg-free ffmpeg --allowerasing || true sudo dnf group upgrade -y multimedia --allowerasing || true sudo dnf group upgrade -y core || true pause_for_logs } install_pipewire_zeroconf() { print_banner echo "Installing PipeWire Zeroconf / AirPlay RAOP discovery support..." echo "" need_sudo || { echo "Could not get sudo privileges." pause_for_logs return } sudo dnf install -y \ pipewire-pulseaudio \ pipewire-config-raop \ avahi \ avahi-tools sudo systemctl enable --now avahi-daemon.service systemctl --user daemon-reload 2>/dev/null || true systemctl --user restart pipewire pipewire-pulse wireplumber 2>/dev/null || true echo "" echo "PipeWire RAOP / AirPlay discovery support installed." echo "AirPlay devices should appear as audio outputs when they are visible on the local network." echo "" pause_for_logs } install_tailscale() { print_banner echo "Installing Tailscale..." echo "" need_sudo || { echo "Could not get sudo privileges." pause_for_logs return } sudo dnf install -y dnf-plugins-core if sudo dnf config-manager addrepo --help >/dev/null 2>&1; then sudo dnf config-manager addrepo --from-repofile=https://pkgs.tailscale.com/stable/fedora/tailscale.repo else sudo dnf config-manager --add-repo https://pkgs.tailscale.com/stable/fedora/tailscale.repo fi sudo dnf install -y tailscale sudo systemctl enable --now tailscaled echo "" echo "Starting Tailscale login..." sudo tailscale up pause_for_logs } install_ghostty() { print_banner echo "Installing Ghostty from the scottames/ghostty COPR..." echo "" need_sudo || { echo "Could not get sudo privileges." pause_for_logs return } sudo dnf install -y dnf-plugins-core sudo dnf copr enable -y scottames/ghostty sudo dnf install -y ghostty pause_for_logs } install_fedora_server_environment() { print_banner echo "Installing Fedora Server Packages..." echo "" echo "This installs the Fedora Server package environment on top of the current system." echo "It does not change the existing disk layout, filesystem choices, or desktop environment." echo "" need_sudo || { echo "Could not get sudo privileges." pause_for_logs return } sudo dnf install -y dnf-plugins-core if sudo dnf environment install -y server-product-environment; then true elif sudo dnf group install -y "Fedora Server Edition"; then true else sudo dnf install -y @^server-product-environment fi sudo systemctl enable --now cockpit.socket || true if systemctl is-active --quiet firewalld; then sudo firewall-cmd --add-service=cockpit --permanent || true sudo firewall-cmd --reload || true fi echo "" echo "Fedora Server Packages installed successfully :)" echo "Cockpit socket enabled successfully :)" echo "" pause_for_logs } install_docker() { print_banner echo "Installing Docker Engine from the official Docker repository..." echo "" need_sudo || { echo "Could not get sudo privileges." pause_for_logs return } sudo dnf install -y dnf-plugins-core if sudo dnf config-manager addrepo --help >/dev/null 2>&1; then sudo dnf config-manager addrepo --from-repofile=https://download.docker.com/linux/fedora/docker-ce.repo else sudo dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo fi sudo dnf install -y \ docker-ce \ docker-ce-cli \ containerd.io \ docker-buildx-plugin \ docker-compose-plugin sudo systemctl enable --now docker.service if getent group docker >/dev/null 2>&1; then sudo usermod -aG docker "$USER" || true echo "" echo "Added $USER to the docker group." echo "Log out and back in before running docker without sudo." fi pause_for_logs } install_virtualization() { print_banner echo "Installing KVM/QEMU/libvirt virtualization tools..." echo "" need_sudo || { echo "Could not get sudo privileges." pause_for_logs return } sudo dnf group install -y --with-optional virtualization || \ sudo dnf install -y \ qemu-kvm \ libvirt \ virt-install \ virt-manager \ virt-viewer \ libguestfs-tools \ edk2-ovmf \ bridge-utils sudo systemctl enable --now libvirtd.service if getent group libvirt >/dev/null 2>&1; then sudo usermod -aG libvirt "$USER" || true echo "" echo "Added $USER to the libvirt group." echo "Log out and back in before managing VMs without extra auth." fi pause_for_logs } create_ssh_key() { print_banner echo "Creating an SSH key if one does not already exist..." echo "" mkdir -p "$HOME/.ssh" chmod 700 "$HOME/.ssh" if [ -f "$HOME/.ssh/id_ed25519" ]; then echo "SSH key already exists:" echo " $HOME/.ssh/id_ed25519" echo "" echo "Public key:" cat "$HOME/.ssh/id_ed25519.pub" 2>/dev/null || true pause_for_logs return fi read -r -p "Email/comment for SSH key: " ssh_comment if [ -z "$ssh_comment" ]; then ssh_comment="$USER@$(hostname)" fi ssh-keygen -t ed25519 -C "$ssh_comment" -f "$HOME/.ssh/id_ed25519" echo "" echo "Public key:" cat "$HOME/.ssh/id_ed25519.pub" pause_for_logs } run_firmware_updates() { print_banner echo "Checking for firmware updates..." echo "" need_sudo || { echo "Could not get sudo privileges." pause_for_logs return } sudo dnf install -y fwupd sudo fwupdmgr refresh --force || true sudo fwupdmgr get-devices || true sudo fwupdmgr get-updates || true sudo fwupdmgr update || true pause_for_logs } install_zen_flatpak() { print_banner echo "Installing Zen Browser from Flathub..." echo "" echo "This is the easiest Zen install path, but KeePassXC browser integration can be problematic with Flatpak browsers." echo "" need_sudo || { echo "Could not get sudo privileges." pause_for_logs return } sudo dnf install -y flatpak sudo flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo flatpak install -y flathub app.zen_browser.zen pause_for_logs } install_zen_stable_tarball() { print_banner echo "Installing Zen Browser stable tarball using the official install script..." echo "" curl -fsSL https://github.com/zen-browser/updates-server/raw/refs/heads/main/install.sh | bash pause_for_logs } install_zen_twilight_tarball() { print_banner echo "Installing Zen Browser Twilight tarball using the official install script..." echo "" curl -fsSL https://github.com/zen-browser/updates-server/raw/refs/heads/main/install-twilight.sh | bash pause_for_logs } github_latest_asset() { local pattern="$1" curl -fsSL https://api.github.com/repos/zen-browser/desktop/releases/latest \ | grep -oE '"browser_download_url": "[^"]+"' \ | cut -d '"' -f 4 \ | grep -Ei "$pattern" \ | head -n 1 } install_zen_stable_appimage() { print_banner echo "Installing Zen Browser stable AppImage..." echo "" local arch local arch_pattern local url local appdir local appimage arch="$(uname -m)" case "$arch" in x86_64) arch_pattern='(x86_64|amd64)' ;; aarch64) arch_pattern='(aarch64|arm64)' ;; *) echo "Unsupported architecture for Zen AppImage auto-download: $arch" pause_for_logs return ;; esac url="$(github_latest_asset 'AppImage$' | grep -Ei "$arch_pattern" | head -n 1 || true)" if [ -z "$url" ]; then url="$(github_latest_asset 'AppImage$' | head -n 1 || true)" fi if [ -z "$url" ]; then echo "Could not find a Zen AppImage asset in the latest GitHub release." echo "Use the tarball script option instead." pause_for_logs return fi appdir="$HOME/Applications" appimage="$appdir/Zen-Browser.AppImage" mkdir -p "$appdir" curl -fL "$url" -o "$appimage" chmod +x "$appimage" mkdir -p "$HOME/.local/share/applications" cat > "$HOME/.local/share/applications/zen-browser-appimage.desktop" </dev/null 2>&1 || true echo "" echo "Zen AppImage installed at:" echo " $appimage" pause_for_logs } install_keepassxc() { print_banner echo "Installing KeePassXC..." echo "" need_sudo || { echo "Could not get sudo privileges." pause_for_logs return } sudo dnf install -y keepassxc pause_for_logs } configure_keepassxc_browser_helper() { print_banner echo "Configuring KeePassXC browser native messaging helper..." echo "" echo "This is mainly useful for non-Flatpak Zen installs." echo "For Flatpak Zen, this is best-effort only because Flatpak browser native messaging is limited." echo "" need_sudo || { echo "Could not get sudo privileges." pause_for_logs return } sudo dnf install -y keepassxc local proxy local manifest_name local manifest_json proxy="$(command -v keepassxc-proxy || true)" manifest_name="org.keepassxc.keepassxc_browser.json" if [ -z "$proxy" ]; then echo "Could not find keepassxc-proxy." echo "Make sure the Fedora keepassxc package installed it." pause_for_logs return fi manifest_json="$(mktemp)" cat > "$manifest_json" < "$flatpak_helper" < "$flatpak_manifest" </dev/null 2>&1 || true rm -f "$flatpak_manifest" fi rm -f "$manifest_json" echo "" echo "KeePassXC native messaging manifests were created." echo "" echo "Next steps:" echo " 1. Open KeePassXC." echo " 2. Enable Browser Integration in KeePassXC settings." echo " 3. Install the KeePassXC-Browser extension in Zen." echo " 4. Restart Zen." echo "" pause_for_logs } zen_browser_menu() { while true; do print_banner choice=$(sl_menu --header="--- Zen Browser ---" \ "Install Zen from Flathub" \ "Install Zen Stable Tarball" \ "Install Zen Twilight Tarball" \ "Install Zen Stable AppImage" \ "Install KeePassXC" \ "Configure KeePassXC Browser Helper" \ "Back") case "$choice" in "Install Zen from Flathub") install_zen_flatpak ;; "Install Zen Stable Tarball") install_zen_stable_tarball ;; "Install Zen Twilight Tarball") install_zen_twilight_tarball ;; "Install Zen Stable AppImage") install_zen_stable_appimage ;; "Install KeePassXC") install_keepassxc ;; "Configure KeePassXC Browser Helper") configure_keepassxc_browser_helper ;; "Back"|"") return ;; esac done } desktop_pkgs_menu() { while true; do print_banner choice=$(sl_menu --header="--- Sl's Desktop ---" \ "Set up SLASH on this system" \ "Full Desktop (sl-desktop-full)" \ "sl-greeter & sl-lock (sl-desktop-utils)" \ "Desktop Assets (sl-desktop-assets)" \ "Blue DMS Theme (sl-blue-dms-theme)" \ "Menubar (sl-menubar)" \ "Dock (sl-dock)" \ "Duobar (sl-duobar)" \ "Taskbar (sl-taskbar)" \ "Icons on the Desktop (sl-desktop-surface)" \ "Shake to find the Cursor (sl-cursor-shake)" \ "Back") case "$choice" in "Set up Slash on this system") setup_slash_desktop ;; "Full Desktop (sl-desktop-full)") install_pkg "sl-desktop-full" ;; "sl-greeter & sl-lock (sl-desktop-utils)") install_pkg "sl-desktop-utils" ;; "Desktop Assets (sl-desktop-assets)") install_pkg "sl-desktop-assets" ;; "Blue DMS Theme (sl-blue-dms-theme)") install_pkg "sl-blue-dms-theme" ;; "Menubar (sl-menubar)") install_pkg "sl-menubar" ;; "Dock (sl-dock)") install_pkg "sl-dock" ;; "Duobar (sl-duobar)") install_pkg "sl-duobar" ;; "Taskbar (sl-taskbar)") install_pkg "sl-taskbar" ;; "Icons on the Desktop (sl-desktop-surface)") install_pkg "sl-desktop-surface" ;; "Shake to find the Cursor (sl-cursor-shake)") install_pkg "sl-cursor-shake" ;; "Back"|"") return ;; esac done } bg_pkgs_menu() { while true; do print_banner choice=$(sl_menu --header="--- Sl's Daily Background ---" \ "From Bing (sl-daily-background-bing)" \ "From NASA (sl-daily-background-nasa)" \ "From Unsplash (sl-daily-background-unsplash)" \ "Back") case "$choice" in "From Bing (sl-daily-background-bing)") install_pkg "sl-daily-background-bing" ;; "From NASA (sl-daily-background-nasa)") install_pkg "sl-daily-background-nasa" ;; "From Unsplash (sl-daily-background-unsplash)") install_pkg "sl-daily-background-unsplash" ;; "Back"|"") return ;; esac done } packages_menu() { while true; do print_banner choice=$(sl_menu --header="--- Install Sl’s Packages ---" \ "Sl’s Desktop" \ "Sl’s Daily Background" \ "Sl’s Display Mirror" \ "Sl’s Disklabel Utils" \ "Sl’s XKB Mac Layouts" \ "Sl's Sync Utility" \ "Meerkrite TUI Editor" \ "Meerkrite GTK GUI Editor" \ "Back") case "$choice" in "Sl’s Desktop") desktop_pkgs_menu ;; "Sl’s Daily Background") bg_pkgs_menu ;; "Sl’s Display Mirror") install_pkg "sl-display-mirror" ;; "Sl’s Disklabel Utils") install_pkg "sl-disklabel-utils" ;; "Sl’s XKB Mac Layouts") install_pkg "sl-xkb-mac-layouts" ;; "Sl's Sync Utility") install_pkg "sl-sync" ;; "Meerkrite TUI Editor") install_pkg "meerkrite-tui" ;; "Meerkrite GTK GUI Editor") install_pkg "meerkrite" ;; "Back"|"") return ;; esac done } useful_fedora_commands_menu() { while true; do print_banner choice=$(sl_menu --header="--- Useful Fedora Commands ---" \ "Check for Firmware Updates" \ "Optimize DNF" \ "Clean DNF Cache" \ "Enable DNF Automatic Updates" \ "Show Enabled Repositories" \ "Set Graphical Session as Default" \ "Add/Set System Locale" \ "Enable RPM Fusion" \ "Enable Flathub" \ "Add Terra Repository" \ "Install AppImage Support & Gear Lever" \ "Install GNOME Tweaks & Extension Manager" \ "Install Multimedia Codecs" \ "Install PipeWire Zeroconf Support" \ "Install Tailscale" \ "Install Zen Browser" \ "Install Ghostty (from COPR)" \ "Install Fedora Server Packages" \ "Install Docker Engine" \ "Install Virtualization Tools" \ "Create SSH Key" \ "Back") case "$choice" in "Check for Firmware Updates") run_firmware_updates ;; "Optimize DNF") optimize_dnf ;; "Clean DNF Cache") clean_dnf_cache ;; "Enable DNF Automatic Updates") install_dnf_automatic ;; "Show Enabled Repositories") show_enabled_repos ;; "Set Graphical Session as Default") set_graphical_session_default ;; "Add/Set System Locale") configure_system_locale ;; "Enable RPM Fusion") enable_rpmfusion ;; "Enable Flathub") enable_flathub ;; "Add Terra Repository") add_terra_repository ;; "Install AppImage Support & Gear Lever") install_appimage_support ;; "Install GNOME Tweaks & Extension Manager") install_gnome_tools ;; "Install Multimedia Codecs") install_multimedia_codecs ;; "Install PipeWire Zeroconf Support") install_pipewire_zeroconf ;; "Install Tailscale") install_tailscale ;; "Install Zen Browser") zen_browser_menu ;; "Install Ghostty (from COPR)") install_ghostty ;; "Install Fedora Server Packages") install_fedora_server_environment ;; "Install Docker Engine") install_docker ;; "Install Virtualization Tools") install_virtualization ;; "Create SSH Key") create_ssh_key ;; "Back"|"") return ;; esac done } ARCH=$(uname -m) while true; do print_banner choice=$(sl_menu --header="--- Welcome to Sl's Fedora Toolbox ($ARCH) ---" \ "Enable the SLASH COPR Repository" \ "Install Sl’s Kernel" \ "Install Sl’s Packages" \ "Upgrade Fedora Packages" \ "Useful Fedora Commands" \ "Quit") case "$choice" in "Enable the SLASH COPR Repository") enable_slash_copr ;; "Install Sl’s Kernel") kernel_menu ;; "Install Sl’s Packages") packages_menu ;; "Upgrade Fedora Packages") upgrade_system ;; "Useful Fedora Commands") useful_fedora_commands_menu ;; "Quit"|"") tput rmcup 2>/dev/null || true exit 0 ;; esac done EOF %install install -Dm755 sl-toolbox %{buildroot}%{_bindir}/sl-toolbox %files %{_bindir}/sl-toolbox %changelog * Tue Sep 29 2026 Sl (Shahaf Levi) - 1.2.1-2 - Add sl-desktop-surface and sl-cursor-shake to Sl's Desktop package menu. * Tue Aug 04 2026 Sl (Shahaf Levi) - 1.2.0-1 - Add sl-sync and meerkrite to package menus - Bump version to 1.2.0-1 * Sun Jun 28 2026 Sl (Shahaf Levi) - 1.1.2 - Add kernel-sl COPR enable/install actions - Add kernel-sl and kernel-sl-v3 installer menu * Sat Jun 20 2026 Sl (Shahaf Levi) - 1.1.1 - Reorder Useful Fedora Commands menu - Add DNF automatic updates action - Add PipeWire Zeroconf support action - Add Zen Browser submenu with Flathub, tarball, AppImage, and KeePassXC helper options - Add Gear Lever to AppImage support action - Keep Fedora build filtered to Fedora-safe package management actions only