From 2ebb33460c75f9c7b25ad3f9bd90d793fe7c31ce Mon Sep 17 00:00:00 2001 From: stornic56 <71296607+stornic56@users.noreply.github.com> Date: Fri, 10 Jul 2026 19:50:36 -0500 Subject: [PATCH] Broadcom, Utils & Headless Fixes - Removed dead Broadcom hardware IDs (4357/4358/4360/4727) from `_is_broadcom_b43`, retaining only valid ID 4352 to eliminate false positives in the case statement. - Added a guard in `_handle_wireless` Level 3 to verify `linux-headers` availability via `apt-cache policy`. Skips DKMS compilation if headers are missing, preventing transaction failures during installation. - Implemented Broadcom combo card detection (WiFi + Bluetooth) by scanning `PCI_BT_DEVS`. Automatically writes `/etc/modprobe.d/broadcom-combo.conf` with `softdep wl post: btusb` and warns users about potential reboot requirements. - Enhanced Level 2 (`firmware-b43-installer`) with post-installation validation for `/lib/firmware/b43`. Provides clear recovery instructions via `sudo dpkg-reconfigure firmware-b43-installer` if the directory is empty or missing after installation. - Created a new helper `_msg_red()` in `utils.sh` to handle critical error messages with colored Whiptail output, replacing standard alerts for migration warnings and failures. - Updated `repos/migrate.sh` to use `_msg_red()` for branch migration warnings and failure states, ensuring visibility of critical issues while keeping completion messages informative. - Verified headless mode guards across 16 separate extras files (`office.sh`, `fetch.sh`, `cursors.sh`, etc.), preventing unnecessary package installations on servers without display environments. - Completed syntax verification (`bash -n`) across all core and extra modules, ensuring no errors in the updated logic for firmware, gaming, swap, or repository management scripts. - update readme.md --- README.md | 59 ++++++++-- debianito.sh | 12 ++- modules/extras/design/design.sh | 67 ++++++------ modules/extras/dev/dev.sh | 34 +++--- modules/extras/download/download.sh | 55 ++++++---- modules/extras/essential/essential.sh | 5 +- modules/extras/fetch/fetch.sh | 2 +- modules/extras/internet/internet.sh | 102 +++++++++--------- modules/extras/office/office.sh | 13 ++- modules/extras/players/players.sh | 18 ++-- modules/extras/programming/programming.sh | 64 +++++------ modules/extras/security/security.sh | 32 +++--- modules/extras/system/software_centers.sh | 6 ++ modules/extras/system/system.sh | 92 ++++++++-------- modules/extras/themes/cursors/cursors.sh | 32 +++--- .../themes/desktop-themes/desktop-themes.sh | 38 +++---- modules/extras/themes/fonts/fonts.sh | 40 ++++--- modules/extras/themes/icons/icons.sh | 69 ++++++------ modules/firmware.sh | 83 ++++++++++++-- modules/repos/migrate.sh | 8 +- modules/utils.sh | 48 +++++---- 21 files changed, 535 insertions(+), 344 deletions(-) diff --git a/README.md b/README.md index 42cdf1f..15d556b 100644 --- a/README.md +++ b/README.md @@ -50,15 +50,17 @@ After running the script: | **1** | [System Info](/docs/system_info.md) | Show detected OS, CPU, RAM, GPU and hardware details | | **2** | [User Privileges & Feedback](/docs/user_priv_feed.md) | Configure sudo group membership, enable passwordless sudo for frequent tasks, repair home directory ownership issues, and toggle visual password feedback (asterisks) in terminal | | **3** | [Configure Repositories](/docs/repos_config.md) | Setup official repos with non-free/contrib options, optional Backports support and Deb822/classic format injection.| -| **4** | [Firmware & Wireless Drivers](/docs/firmware.md) | Install essential firmware for GPUs and wireless| +| **4** | [Firmware, Wireless & Bluetooth](/docs/firmware.md) | Install essential firmware for GPUs and wireless| | **5** | [Graphics Drivers & Mesa Stack](/docs/gpu.md) | Configure AMD/Intel/NVIDIA drivers and Mesa graphics stack + monitoring tools | | **6** | [Backports Kernel](/docs/kernel.md) | Install latest kernel from Debian backports| -| **7** | [Gaming Setup and Performance](/docs/gaming.md)| Steam, Heroic Games Launcher, [RetroArch](/docs/retroarch.md) GameMode, MangoHud, OpenRGB, Java JRE (Temurin 8/17/21) | -| **8** | [Install ZRAM](/docs/zram.md)| Configure compressed RAM for memory optimization| -| **9** | Install Programs and Software | Selection from several categories (Development, Themes, System, etc.) | -| **10** | Exit | Return to terminal | +| **7** | [Gaming Setup ](/docs/gaming.md)| Steam, Heroic Games Launcher, [RetroArch](/docs/retroarch.md) GameMode, MangoHud, OpenRGB, Java JRE (Temurin 8/17/21) | +| **8** | [ZRAM](/docs/zram.md)| Configure compressed RAM for memory optimization| +| **9** | Swap Management| Manage swap file or partition size and enable/disable swap space for system stability| +| **10** | Install Programs and Software | Browse and install packages by category (Development, Themes, System Tools, etc.) using APT | +| **11** | Boot Rescue & Repair| Fix GRUB bootloader issues, chroot repair, or restore system boot configuration| +| **12** | Exit | Return to terminal | -### Install Programs and Software (Option 9) +### Install Programs and Software (Option 10) The submenu offers the next categories: @@ -67,7 +69,7 @@ The submenu offers the next categories: | **0** | Essential Pack | Quick install of common tools (compression, system info, VLC, MS fonts)| | **1** | Customization System | Desktop themes, icon themes, cursor themes, and fonts | | **2** | Download & Network | Downloaders (aria2, ytdlp, FileZilla) + Torrent clients (qBittorrent, Deluge, Transmission) | -| **3** | Internet (Browsers, Email Clients, VPN Tools) | Web browsers (Firefox/Mozilla, LibreWolf, Floorp, Chromium, Brave, Tor), email clients (Thunderbird), and VPN tools including Riseup | +| **3** | Internet (Browsers, Email Clients, VPN) | Web browsers (Firefox/Mozilla, LibreWolf, Floorp, Chromium, Brave, Tor), email client (Thunderbird), and VPN tools (RiseUp, Proton, Mullvad)| | **4** | Media Players | Multimedia playback with VLC media player and MPV for advanced video/audio support | | **5** | Multimedia & Design | image editing (GIMP), video editing (Kdenlive, HandBrake), 3D modeling (Blender), audio recording (Audacity), and graphics design (Inkscape) | | **6** | Code Editors & IDEs | vim, vim-gtk3, Neovim, Helix, nano, Emacs, Kate, Mousepad, Gedit, Geany, GNOME Text Editor, and VSCodium (VS Code open-source) | @@ -84,9 +86,42 @@ The submenu offers the next categories: | Directory/File | Description | |----------------|-------------| -| `./debianito.sh` | Main entry point; handles menu navigation and system detection. | -| `/modules/` | Modular scripts for specific tasks: sudo config, repos, firmware, gpu, kernel, gaming, zram. | -| `/modules/extras/` | Split-by-category sub-modules for the "Install Programs and Software" menu (Option 9). | +| `debianito.sh` | Main entry point; handles menu navigation and system detection. | +| `docs/` | Documentation directory containing Markdown files for each module. | +| `modules/` | Core modular scripts organized by category: repos, gpu, gaming, kernel, firmware, zram, etc. | +| `modules/bullseye/` | Legacy Debian 11 (Bullseye) specific modules: `extras.sh`, `legacy.sh`, `repos.sh`. | +| `modules/extras/` | Software installer sub-modules split by category (themes, downloaders, internet, dev tools, etc.). | +| `modules/gaming/` | Gaming launcher and optimization scripts: Steam, Heroic, Lutris, performance tools. | +| `modules/gpu/` | GPU driver installation scripts for AMD and NVIDIA with architecture detection. | +| `modules/repos/` | Repository management scripts: migration tool (`migrate.sh`) and format detection (`repo_detect.sh`). | +| `modules/extras/design/` | Multimedia & design tools installer (Blender, GIMP, Kdenlive, OBS). | +| `modules/extras/dev/` | Development tools installer with special handling for Jellyfin and Java. | +| `modules/extras/download/` | Download tools installer (aria2, FileZilla) and torrent clients (qBittorrent, Transmission). | +| `modules/extras/essential/` | Essential package installer for basic system utilities on older Debian versions. | +| `modules/extras/fetch/` | System information fetcher tools (neofetch, screenfetch, linuxlogo). | +| `modules/extras/internet/` | Internet tools installer: browsers, email clients, download managers. | +| `modules/extras/java.sh` | Java runtime installer for Minecraft and development (Temurin 8/17/21). | +| `modules/extras/office/` | Office productivity suite installer (LibreOffice, GIMP alternatives). | +| `modules/extras/players/` | Media player installer (MPV, VLC) with codec support. | +| `modules/extras/programming/` | Code editors and IDEs installer (Vim, Neovim, Emacs, Kate). | +| `modules/extras/security/` | Security tools installer: ClamAV, Fail2Ban, UFW, Wireshark. | +| `modules/extras/system/` | System utilities installer with software center options (GNOME Software, Discover). | +| `modules/extras/themes/` | Desktop customization installer: themes, icons, cursors, fonts. | +| `modules/gaming/_helpers.sh` | Shared helper functions for gaming modules (32-bit support, Mesa drivers). | +| `modules/gpu/amd_intel.sh` | AMD and Intel GPU firmware + monitoring tools (radeontop, nvtop, vainfo). | +| `modules/gpu/_helpers.sh` | Shared helper functions for GPU detection (NVIDIA architecture checks). | +| `modules/nvidia.sh` | NVIDIA driver installer with multi-architecture support (Kepler, Fermi, Maxwell, Pascal, Blackwell). | +| `modules/amd_intel.sh` | AMD and Intel GPU firmware + monitoring tools installation. | +| `modules/kernel.sh` | Kernel management: backports kernel installation and detection. | +| `modules/repos/migrate.sh` | Branch migration tool for Debian stable → testing/SID with backup/rollback. | +| `modules/repos/repo_detect.sh` | Repository format detection (DEB822 vs classic) for idempotent configuration. | +| `modules/rescue.sh` | Boot rescue and repair tools: GRUB fix, chroot repair, system restore. | +| `modules/sudo_config.sh` | Sudo configuration: group membership, passwordless sudo, home directory ownership. | +| `modules/swap.sh` | Swap management: file/partition size configuration and enable/disable swap space. | +| `modules/sysinfo.sh` | System information detection and display (OS, CPU, RAM, GPU, storage). | +| `modules/utils.sh` | Utility functions shared across modules (color codes, confirmation dialogs, installation helpers). | +| `modules/zram.sh` | ZRAM configuration for compressed RAM optimization. | +| `README.md` | Project documentation and usage instructions. | ```bash ├── debianito.sh @@ -158,15 +193,17 @@ The submenu offers the next categories: │   ├── gpu.sh │   ├── kernel.sh │   ├── repos +│   │   ├── migrate.sh │   │   └── repo_detect.sh │   ├── repos.sh +│   ├── rescue.sh │   ├── sudo_config.sh +│   ├── swap.sh │   ├── sysinfo.sh │   ├── utils.sh │   └── zram.sh └── README.md ``` - --- > 🤖 **AI-Assisted Development Note** diff --git a/debianito.sh b/debianito.sh index 3d094aa..8c916cf 100644 --- a/debianito.sh +++ b/debianito.sh @@ -51,6 +51,8 @@ main_menu() { fi while true; do + sudo -v >/dev/null 2>&1 || true + local STATE_REFRESHED=false local choice choice=$(_menu "DEBIANITO — simple configurator script" "" \ $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \ @@ -78,6 +80,7 @@ main_menu() { else configure_repos || true fi + STATE_REFRESHED=true ;; 4) if [ "$DEBIAN_VERSION" = "11" ] && type install_firmware_bullseye &>/dev/null; then @@ -86,7 +89,7 @@ main_menu() { install_firmware || true fi ;; - 5) install_gpu_drivers || true ;; + 5) install_gpu_drivers || true; STATE_REFRESHED=true ;; 6) if [ "$DEBIAN_VERSION" = "11" ]; then _msg "Not Available" \ @@ -96,6 +99,7 @@ kernels. Use the stable kernel provided by Bullseye." 10 60 else install_kernel_backports || true fi + STATE_REFRESHED=true ;; 7) if [ "$DEBIAN_VERSION" = "11" ] && type install_gaming_bullseye &>/dev/null; then @@ -103,9 +107,10 @@ kernels. Use the stable kernel provided by Bullseye." 10 60 else install_gaming || true fi + STATE_REFRESHED=true ;; 8) install_zram || true ;; - 9) manage_swap || true ;; + 9) manage_swap || true; STATE_REFRESHED=true ;; 10) if [ "$DEBIAN_VERSION" = "11" ] && type install_extras_bullseye &>/dev/null; then install_extras_bullseye || true @@ -116,6 +121,9 @@ kernels. Use the stable kernel provided by Bullseye." 10 60 11) rescue_boot || true ;; 12) echo "Exiting."; exit 0 ;; esac + if $STATE_REFRESHED; then + refresh_system_state + fi done } diff --git a/modules/extras/design/design.sh b/modules/extras/design/design.sh index 27338bf..5f171ce 100644 --- a/modules/extras/design/design.sh +++ b/modules/extras/design/design.sh @@ -4,47 +4,46 @@ _cat_design() { local headless=false _is_headless && headless=true - local audacity_state; audacity_state=$(_state "audacity") - local ardour_state; ardour_state=$(_state "ardour") - local blender_state; blender_state=$(_state "blender") - local ffmpeg_state; ffmpeg_state=$(_state "ffmpeg") - local gimp_state; gimp_state=$(_state "gimp") - local handbrake_state; handbrake_state=$(_state "handbrake") - local inkscape_state; inkscape_state=$(_state "inkscape") - local kdenlive_state; kdenlive_state=$(_state "kdenlive") - local krita_state; krita_state=$(_state "krita") - local obs_state; obs_state=$(_state "obs-studio") - local openshot_state; openshot_state=$(_state "openshot-qt") - local scribus_state; scribus_state=$(_state "scribus") - local shotcut_state; shotcut_state=$(_state "shotcut") + local -a items=() + if ! $headless; then + local audacity_state; audacity_state=$(_state "audacity") + local ardour_state; ardour_state=$(_state "ardour") + local blender_state; blender_state=$(_state "blender") + local gimp_state; gimp_state=$(_state "gimp") + local handbrake_state; handbrake_state=$(_state "handbrake") + local inkscape_state; inkscape_state=$(_state "inkscape") + local kdenlive_state; kdenlive_state=$(_state "kdenlive") + local krita_state; krita_state=$(_state "krita") + local obs_state; obs_state=$(_state "obs-studio") + local openshot_state; openshot_state=$(_state "openshot-qt") + local scribus_state; scribus_state=$(_state "scribus") + local shotcut_state; shotcut_state=$(_state "shotcut") + items+=( + "audacity" "Audio editor/recorder$(_inst audacity)" "$audacity_state" + "ardour" "Digital audio workstation$(_inst ardour)" "$ardour_state" + "blender" "3D modeling/animation suite$(_inst blender)" "$blender_state" + "gimp" "Image editor (Photoshop alternative)$(_inst gimp)" "$gimp_state" + "handbrake" "Video transcoder (DVD ripper)$(_inst handbrake)" "$handbrake_state" + "inkscape" "Vector graphics editor$(_inst inkscape)" "$inkscape_state" + "kdenlive" "Video editor (KDE)$(_inst kdenlive)" "$kdenlive_state" + "krita" "Digital painting/illustration$(_inst krita)" "$krita_state" + "obs-studio" "Screen recording/streaming$(_inst obs-studio)" "$obs_state" + "openshot-qt" "Video editor (simple)$(_inst openshot-qt)" "$openshot_state" + "scribus" "Desktop publishing (DTP)$(_inst scribus)" "$scribus_state" + "shotcut" "Video editor (cross-platform)$(_inst shotcut)" "$shotcut_state" + ) + fi + local ffmpeg_state; ffmpeg_state=$(_state "ffmpeg") + items+=("ffmpeg" "Multimedia framework (CLI)$(_inst ffmpeg)" "$ffmpeg_state") local choices - choices=$(_checklist "Multimedia & Design" "Select multimedia and design tools${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \ - "audacity" "Audio editor/recorder$(_inst audacity)" "$audacity_state" \ - "ardour" "Digital audio workstation$(_inst ardour)" "$ardour_state" \ - "blender" "3D modeling/animation suite$(_inst blender)" "$blender_state" \ - "ffmpeg" "Multimedia framework (CLI)$(_inst ffmpeg)" "$ffmpeg_state" \ - "gimp" "Image editor (Photoshop alternative)$(_inst gimp)" "$gimp_state" \ - "handbrake" "Video transcoder (DVD ripper)$(_inst handbrake)" "$handbrake_state" \ - "inkscape" "Vector graphics editor$(_inst inkscape)" "$inkscape_state" \ - "kdenlive" "Video editor (KDE)$(_inst kdenlive)" "$kdenlive_state" \ - "krita" "Digital painting/illustration$(_inst krita)" "$krita_state" \ - "obs-studio" "Screen recording/streaming$(_inst obs-studio)" "$obs_state" \ - "openshot-qt" "Video editor (simple)$(_inst openshot-qt)" "$openshot_state" \ - "scribus" "Desktop publishing (DTP)$(_inst scribus)" "$scribus_state" \ - "shotcut" "Video editor (cross-platform)$(_inst shotcut)" "$shotcut_state" \ - ) + choices=$(_checklist "Multimedia & Design" "Select multimedia and design tools${SCROLL_HINT}:" \ + $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA "${items[@]}") clear [ -z "$choices" ] && return - local cleaned; cleaned=$(echo "$choices" | tr -d '"') - for pkg in $cleaned; do - if $headless; then - echo "Skipping $pkg (headless mode)" - continue - fi if ! is_installed "$pkg"; then _run_install "$pkg" else diff --git a/modules/extras/dev/dev.sh b/modules/extras/dev/dev.sh index b06c13b..af29ae1 100644 --- a/modules/extras/dev/dev.sh +++ b/modules/extras/dev/dev.sh @@ -4,6 +4,7 @@ _cat_dev() { local headless=false _is_headless && headless=true + local -a items=() local apache_state; apache_state=$(_state "apache2") local build_state; build_state=$(_state "build-essential") local certbot_state; certbot_state=$(_state "certbot") @@ -19,25 +20,28 @@ _cat_dev() { local sqlite_state; sqlite_state=$(_state "sqlite3") local jdk_desc; jdk_desc=$(_any_jdk_installed_desc) local jdk_state; jdk_state=$(_any_jdk_state) + items+=( + "apache2" "Apache web server$(_inst apache2)" "$apache_state" + "build-essential" "C/C++ build tools (gcc, make)$(_inst build-essential)" "$build_state" + "certbot" "Let's Encrypt TLS certificates$(_inst certbot)" "$certbot_state" + "docker" "Docker + docker-compose$(_inst docker.io)" "$docker_state" + "mariadb-server" "MariaDB database server$(_inst mariadb-server)" "$mariadb_state" + "netcat-openbsd" "TCP/IP networking utility$(_inst netcat-openbsd)" "$netcat_state" + "nginx" "Nginx web server$(_inst nginx)" "$nginx_state" + "openssh-server" "SSH server$(_inst openssh-server)" "$ssh_state" + "openssl" "OpenSSL cryptography toolkit$(_inst openssl)" "$openssl_state" + "postgresql" "PostgreSQL database server$(_inst postgresql)" "$pg_state" + "python3-pip" "Python 3 pip + venv + dev$(_inst python3-pip)" "$pip_state" + "redis-server" "Redis key-value store$(_inst redis-server)" "$redis_state" + "sqlite3" "SQLite database engine$(_inst sqlite3)" "$sqlite_state" + "jellyfin" "Jellyfin Media Server (Web GUI on port 8096)$(_inst jellyfin)" OFF + "openjdk-dev-env" "Adoptium Temurin JDK (17, 21, 25 LTS)${jdk_desc}" "${jdk_state}" + ) local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6)) local choices choices=$(_checklist "Development & Servers" "Select development tools and servers${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \ - "apache2" "Apache web server$(_inst apache2)" "$apache_state" \ - "build-essential" "C/C++ build tools (gcc, make)$(_inst build-essential)" "$build_state" \ - "certbot" "Let's Encrypt TLS certificates$(_inst certbot)" "$certbot_state" \ - "docker" "Docker + docker-compose$(_inst docker.io)" "$docker_state" \ - "mariadb-server" "MariaDB database server$(_inst mariadb-server)" "$mariadb_state" \ - "netcat-openbsd" "TCP/IP networking utility$(_inst netcat-openbsd)" "$netcat_state" \ - "nginx" "Nginx web server$(_inst nginx)" "$nginx_state" \ - "openssh-server" "SSH server$(_inst openssh-server)" "$ssh_state" \ - "openssl" "OpenSSL cryptography toolkit$(_inst openssl)" "$openssl_state" \ - "postgresql" "PostgreSQL database server$(_inst postgresql)" "$pg_state" \ - "python3-pip" "Python 3 pip + venv + dev$(_inst python3-pip)" "$pip_state" \ - "redis-server" "Redis key-value store$(_inst redis-server)" "$redis_state" \ - "sqlite3" "SQLite database engine$(_inst sqlite3)" "$sqlite_state" \ - "jellyfin" "Jellyfin Media Server (Web GUI on port 8096)$(_inst jellyfin)" OFF \ - "openjdk-dev-env" "Adoptium Temurin JDK (17, 21, 25 LTS)${jdk_desc}" "${jdk_state}" \ + "${items[@]}" \ ) clear diff --git a/modules/extras/download/download.sh b/modules/extras/download/download.sh index 658c726..05bcb38 100644 --- a/modules/extras/download/download.sh +++ b/modules/extras/download/download.sh @@ -4,40 +4,53 @@ _cat_download() { local headless=false _is_headless && headless=true + local -a items1=() + local -a items2=() local aria2_state; aria2_state=$(_state "aria2") - local filezilla_state; filezilla_state=$(_state "filezilla") local ytdlp_state; ytdlp_state=$(_state "yt-dlp") - local ytdlp_gui_state; ytdlp_gui_state=$(_state "youtubedl-gui") - - local deluge_state; deluge_state=$(_state "deluge") local deluged_state; deluged_state=$(_state "deluged") local mktorrent_state; mktorrent_state=$(_state "mktorrent") - local qbit_state; qbit_state=$(_state "qbittorrent") local qbitnox_state; qbitnox_state=$(_state "qbittorrent-nox") local tr_cli_state; tr_cli_state=$(_state "transmission-cli") - local tr_gtk_state; tr_gtk_state=$(_state "transmission-gtk") - local tr_qt_state; tr_qt_state=$(_state "transmission-qt") + items1+=( + "aria2" "Multiprotocol downloader (CLI)$(_inst aria2)" "$aria2_state" + "yt-dlp" "Video downloader CLI$(_inst yt-dlp)" "$ytdlp_state" + ) + items2+=( + "deluged" "BitTorrent daemon/server$(_inst deluged)" "$deluged_state" + "mktorrent" "Torrent metainfo creator (CLI)$(_inst mktorrent)" "$mktorrent_state" + "qbittorrent-nox" "BitTorrent WebUI/CLI$(_inst qbittorrent-nox)" "$qbitnox_state" + "transmission-cli" "BitTorrent client (CLI)$(_inst transmission-cli)" "$tr_cli_state" + ) + if ! $headless; then + local filezilla_state; filezilla_state=$(_state "filezilla") + local ytdlp_gui_state; ytdlp_gui_state=$(_state "youtubedl-gui") + local deluge_state; deluge_state=$(_state "deluge") + local qbit_state; qbit_state=$(_state "qbittorrent") + local tr_gtk_state; tr_gtk_state=$(_state "transmission-gtk") + local tr_qt_state; tr_qt_state=$(_state "transmission-qt") + items1+=( + "filezilla" "FTP/SFTP client (GUI)$(_inst filezilla)" "$filezilla_state" + "youtubedl-gui" "GUI for yt-dlp$(_inst youtubedl-gui)" "$ytdlp_gui_state" + ) + items2+=( + "deluge" "BitTorrent client (GTK)$(_inst deluge)" "$deluge_state" + "qbittorrent" "BitTorrent client (Qt)$(_inst qbittorrent)" "$qbit_state" + "transmission-gtk" "BitTorrent client (GTK)$(_inst transmission-gtk)" "$tr_gtk_state" + "transmission-qt" "BitTorrent client (Qt)$(_inst transmission-qt)" "$tr_qt_state" + ) + fi local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6)) local choices1 choices2="" choices1=$(_checklist "Downloaders" "Select download tools:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \ - "aria2" "Multiprotocol downloader (CLI)$(_inst aria2)" "$aria2_state" \ - "filezilla" "FTP/SFTP client (GUI)$(_inst filezilla)" "$filezilla_state" \ - "yt-dlp" "Video downloader CLI$(_inst yt-dlp)" "$ytdlp_state" \ - "youtubedl-gui" "GUI for yt-dlp$(_inst youtubedl-gui)" "$ytdlp_gui_state" \ + "${items1[@]}" \ ) clear choices2=$(_checklist "Torrent Clients" "Select torrent clients:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \ - "deluge" "BitTorrent client (GTK)$(_inst deluge)" "$deluge_state" \ - "deluged" "BitTorrent daemon/server$(_inst deluged)" "$deluged_state" \ - "mktorrent" "Torrent metainfo creator (CLI)$(_inst mktorrent)" "$mktorrent_state" \ - "qbittorrent" "BitTorrent client (Qt)$(_inst qbittorrent)" "$qbit_state" \ - "qbittorrent-nox" "BitTorrent WebUI/CLI$(_inst qbittorrent-nox)" "$qbitnox_state" \ - "transmission-cli" "BitTorrent client (CLI)$(_inst transmission-cli)" "$tr_cli_state" \ - "transmission-gtk" "BitTorrent client (GTK)$(_inst transmission-gtk)" "$tr_gtk_state" \ - "transmission-qt" "BitTorrent client (Qt)$(_inst transmission-qt)" "$tr_qt_state" \ + "${items2[@]}" \ ) clear @@ -58,10 +71,6 @@ _cat_download() { install_backports_or_stable qbittorrent-nox ;; *) - if $headless; then - echo "Skipping $pkg (headless mode)" - continue - fi if ! is_installed "$pkg"; then _run_install "$pkg" else diff --git a/modules/extras/essential/essential.sh b/modules/extras/essential/essential.sh index 4115762..39adb0d 100644 --- a/modules/extras/essential/essential.sh +++ b/modules/extras/essential/essential.sh @@ -10,12 +10,13 @@ _quick_install() { fi _msg "Essential Pack" \ - "Install basic programs:\n\n - Compression (zip, unrar, 7z)\n - System tools (htop, inxi, ${fetch_pkg})\n - VLC media player\n - Microsoft fonts" 13 60 + "Install basic programs:\n\n - Compression (zip, unrar, 7z)\n - System tools (htop, inxi, ${fetch_pkg}, $(_is_headless || echo "VLC"))\n - Microsoft fonts" 13 60 local quick_pkgs=( zip unzip rar unrar p7zip-full p7zip-rar - "$fetch_pkg" htop vlc inxi ttf-mscorefonts-installer + "$fetch_pkg" htop inxi ttf-mscorefonts-installer ) + _is_headless || quick_pkgs+=(vlc) _run_install_batch "${quick_pkgs[@]}" echo -e "${GREEN}Essential Pack installed.${NC}" } diff --git a/modules/extras/fetch/fetch.sh b/modules/extras/fetch/fetch.sh index d4e7f6c..b1f0ee1 100644 --- a/modules/extras/fetch/fetch.sh +++ b/modules/extras/fetch/fetch.sh @@ -18,7 +18,7 @@ _cat_fetch() { hyfetch_state=$(_state "hyfetch") fi - local items=() + local -a items=() if [ "$fetch_pkg" = "fastfetch" ]; then items+=("fastfetch" "System info fetcher$(_inst fastfetch)" "$fetch_state") diff --git a/modules/extras/internet/internet.sh b/modules/extras/internet/internet.sh index d7225fc..45d09a0 100644 --- a/modules/extras/internet/internet.sh +++ b/modules/extras/internet/internet.sh @@ -117,55 +117,63 @@ install_protonvpn() { _cat_internet() { local headless=false _is_headless && headless=true - local chromium_state; chromium_state=$(_state "chromium") - local dillo_state; dillo_state=$(_state "dillo") - local elinks_state; elinks_state=$(_state "elinks") - local epiphany_state; epiphany_state=$(_state "epiphany-browser") - local falkon_state; falkon_state=$(_state "falkon") - local firefox_state="OFF" - if command -v firefox &>/dev/null && ! is_installed "firefox-esr"; then - firefox_state="ON" + local -a items=() + if ! $headless; then + local chromium_state; chromium_state=$(_state "chromium") + local dillo_state; dillo_state=$(_state "dillo") + local epiphany_state; epiphany_state=$(_state "epiphany-browser") + local falkon_state; falkon_state=$(_state "falkon") + local firefox_state="OFF" + if command -v firefox &>/dev/null && ! is_installed "firefox-esr"; then + firefox_state="ON" + fi + local firefox_esr_state + firefox_esr_state=$(_state "firefox-esr") + local floorp_state; floorp_state=$(_state "floorp") + local konqueror_state; konqueror_state=$(_state "konqueror") + local librewolf_state; librewolf_state=$(_state "librewolf") + local palemoon_state; palemoon_state=$(_state "palemoon") + local privacybrowser_state; privacybrowser_state=$(_state "privacybrowser") + local qutebrowser_state; qutebrowser_state=$(_state "qutebrowser") + local thunderbird_state; thunderbird_state=$(_state "thunderbird") + local torbrowser_state; torbrowser_state=$(_state "torbrowser-launcher") + local mullvadbrowser_state; mullvadbrowser_state=$(_state "mullvad-browser") + local protonvpn_state; protonvpn_state=$(_state "protonvpn") + items+=( + "chromium" "Chromium web browser$(_inst chromium)" "$chromium_state" + "dillo" "Lightweight graphical browser$(_inst dillo)" "$dillo_state" + "epiphany-browser" "GNOME web browser$(_inst epiphany-browser)" "$epiphany_state" + "falkon" "KDE web browser (QtWebEngine)$(_inst falkon)" "$falkon_state" + "firefox" "Firefox from Mozilla (replaces ESR)" "$firefox_state" + "firefox-esr" "Firefox ESR (official Debian + locale auto)" "$firefox_esr_state" + "floorp" "Firefox-based browser (extrepo)$(_inst floorp)" "$floorp_state" + "konqueror" "KDE file manager / web browser$(_inst konqueror)" "$konqueror_state" + "librewolf" "Privacy-focused Firefox fork (extrepo)$(_inst librewolf)" "$librewolf_state" + "palemoon" "Classic Firefox-derived browser (extrepo)" "$palemoon_state" + "privacybrowser" "Privacy-focused web browser$(_inst privacybrowser)" "$privacybrowser_state" + "qutebrowser" "Keyboard-driven browser (Qt)$(_inst qutebrowser)" "$qutebrowser_state" + "thunderbird" "Email client$(_inst thunderbird)" "$thunderbird_state" + "torbrowser-launcher" "Tor Browser launcher$(_inst torbrowser-launcher)" "$torbrowser_state" + "mullvad-browser" "Mullvad privacy browser$(_inst mullvad-browser)" "$mullvadbrowser_state" + "protonvpn" "ProtonVPN client$(_inst protonvpn)" "$protonvpn_state" + ) fi - local firefox_esr_state - firefox_esr_state=$(_state "firefox-esr") - local floorp_state; floorp_state=$(_state "floorp") - local konqueror_state; konqueror_state=$(_state "konqueror") - local librewolf_state; librewolf_state=$(_state "librewolf") - local palemoon_state; palemoon_state=$(_state "palemoon") - local privacybrowser_state; privacybrowser_state=$(_state "privacybrowser") - local qutebrowser_state; qutebrowser_state=$(_state "qutebrowser") - local riseupvpn_state; riseupvpn_state=$(_state "riseup-vpn") - local thunderbird_state; thunderbird_state=$(_state "thunderbird") - local torbrowser_state; torbrowser_state=$(_state "torbrowser-launcher") - local w3m_state; w3m_state=$(_state "w3m") - local tailscale_state; tailscale_state=$(_state "tailscale") - local mullvad_state; mullvad_state=$(_state "mullvad-vpn") - local mullvadbrowser_state; mullvadbrowser_state=$(_state "mullvad-browser") - local protonvpn_state; protonvpn_state=$(_state "protonvpn") + local elinks_state; elinks_state=$(_state "elinks") + local riseupvpn_state; riseupvpn_state=$(_state "riseup-vpn") + local w3m_state; w3m_state=$(_state "w3m") + local tailscale_state; tailscale_state=$(_state "tailscale") + local mullvad_state; mullvad_state=$(_state "mullvad-vpn") + items+=( + "elinks" "Text-mode web browser$(_inst elinks)" "$elinks_state" + "riseup-vpn" "Riseup VPN client$(_inst riseup-vpn)" "$riseupvpn_state" + "w3m" "Text-mode browser + deps (w3m-img)$(_inst w3m)" "$w3m_state" + "tailscale" "Zero-config VPN & mesh networking$(_inst tailscale)" "$tailscale_state" + "mullvad-vpn" "Mullvad VPN client (WireGuard)$(_inst mullvad-vpn)" "$mullvad_state" + ) local choices choices=$(_checklist "Internet" "Select browsers, email, and VPN tools${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \ - "chromium" "Chromium web browser$(_inst chromium)" "$chromium_state" \ - "dillo" "Lightweight graphical browser$(_inst dillo)" "$dillo_state" \ - "elinks" "Text-mode web browser$(_inst elinks)" "$elinks_state" \ - "epiphany-browser" "GNOME web browser$(_inst epiphany-browser)" "$epiphany_state" \ - "falkon" "KDE web browser (QtWebEngine)$(_inst falkon)" "$falkon_state" \ - "firefox" "Firefox from Mozilla (replaces ESR)" "$firefox_state" \ - "firefox-esr" "Firefox ESR (official Debian + locale auto)" "$firefox_esr_state" \ - "floorp" "Firefox-based browser (extrepo)$(_inst floorp)" "$floorp_state" \ - "konqueror" "KDE file manager / web browser$(_inst konqueror)" "$konqueror_state" \ - "librewolf" "Privacy-focused Firefox fork (extrepo)$(_inst librewolf)" "$librewolf_state" \ - "palemoon" "Classic Firefox-derived browser (extrepo)" "$palemoon_state" \ - "privacybrowser" "Privacy-focused web browser$(_inst privacybrowser)" "$privacybrowser_state" \ - "qutebrowser" "Keyboard-driven browser (Qt)$(_inst qutebrowser)" "$qutebrowser_state" \ - "riseup-vpn" "Riseup VPN client$(_inst riseup-vpn)" "$riseupvpn_state" \ - "thunderbird" "Email client$(_inst thunderbird)" "$thunderbird_state" \ - "torbrowser-launcher" "Tor Browser launcher$(_inst torbrowser-launcher)" "$torbrowser_state" \ - "w3m" "Text-mode browser + deps (w3m-img)$(_inst w3m)" "$w3m_state" \ - "tailscale" "Zero-config VPN & mesh networking$(_inst tailscale)" "$tailscale_state" \ - "mullvad-vpn" "Mullvad VPN client (WireGuard)$(_inst mullvad-vpn)" "$mullvad_state" \ - "mullvad-browser" "Mullvad privacy browser$(_inst mullvad-browser)" "$mullvadbrowser_state" \ - "protonvpn" "ProtonVPN client$(_inst protonvpn)" "$protonvpn_state" \ + "${items[@]}" \ ) clear @@ -233,10 +241,6 @@ _cat_internet() { fi ;; *) - if $headless; then - echo "Skipping $pkg (headless mode)" - continue - fi if ! is_installed "$pkg"; then _run_install "$pkg" else diff --git a/modules/extras/office/office.sh b/modules/extras/office/office.sh index 71e90a2..40a982f 100644 --- a/modules/extras/office/office.sh +++ b/modules/extras/office/office.sh @@ -60,10 +60,19 @@ install_libreoffice_bpo() { } _cat_office() { + local headless=false + _is_headless && headless=true + local -a items=() + if ! $headless; then + items+=( + "onlyoffice" "OnlyOffice Desktop Editors (extrepo)" OFF + "libreoffice" "LibreOffice (backports on Bookworm/Trixie)" OFF + ) + fi + local choices choices=$(_checklist "Office & Productivity" "Select office applications${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \ - "onlyoffice" "OnlyOffice Desktop Editors (extrepo)" OFF \ - "libreoffice" "LibreOffice (backports on Bookworm/Trixie)" OFF \ + "${items[@]}" \ ) [ -z "$choices" ] && return diff --git a/modules/extras/players/players.sh b/modules/extras/players/players.sh index 634d0a9..bc44dce 100644 --- a/modules/extras/players/players.sh +++ b/modules/extras/players/players.sh @@ -4,14 +4,20 @@ _cat_players() { local headless=false _is_headless && headless=true - local mpv_state; mpv_state=$(_state "mpv") - local vlc_state; vlc_state=$(_state "vlc") + local -a items=() + if ! $headless; then + local mpv_state; mpv_state=$(_state "mpv") + local vlc_state; vlc_state=$(_state "vlc") + items+=( + "mpv" "Lightweight media player$(_inst mpv)" "$mpv_state" + "vlc" "VLC media player$(_inst vlc)" "$vlc_state" + ) + fi local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6)) local choices choices=$(_checklist "Media Players" "Select media players:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \ - "mpv" "Lightweight media player$(_inst mpv)" "$mpv_state" \ - "vlc" "VLC media player$(_inst vlc)" "$vlc_state" \ + "${items[@]}" \ ) clear @@ -20,10 +26,6 @@ _cat_players() { local cleaned; cleaned=$(echo "$choices" | tr -d '"') for pkg in $cleaned; do - if $headless; then - echo "Skipping $pkg (headless mode)" - continue - fi if ! is_installed "$pkg"; then _run_install "$pkg" else diff --git a/modules/extras/programming/programming.sh b/modules/extras/programming/programming.sh index 2632e59..74447ab 100644 --- a/modules/extras/programming/programming.sh +++ b/modules/extras/programming/programming.sh @@ -4,37 +4,45 @@ _cat_programming() { local headless=false _is_headless && headless=true - local vim_state; vim_state=$(_state "vim") - local vimgtk_state; vimgtk_state=$(_state "vim-gtk3") - local neovim_state; neovim_state=$(_state "neovim") - local hx_state; hx_state=$(_state "hx") - local nano_state; nano_state=$(_state "nano") - local emacs_state; emacs_state=$(_state "emacs") - local kate_state; kate_state=$(_state "kate") - local mousepad_state; mousepad_state=$(_state "mousepad") - local gedit_state; gedit_state=$(_state "gedit") - local geany_state; geany_state=$(_state "geany") - local gte_state; gte_state=$(_state "gnome-text-editor") - local codium_state="OFF" - if command -v codium &>/dev/null; then - codium_state="ON" + local -a items=() + local vim_state; vim_state=$(_state "vim") + local neovim_state; neovim_state=$(_state "neovim") + local hx_state; hx_state=$(_state "hx") + local nano_state; nano_state=$(_state "nano") + local emacs_state; emacs_state=$(_state "emacs") + items+=( + "vim" "Classic terminal editor$(_inst vim)" "$vim_state" + "neovim" "Modern vim fork$(_inst neovim)" "$neovim_state" + "hx" "Helix modal editor (Rust)$(_inst hx)" "$hx_state" + "nano" "Simple terminal editor$(_inst nano)" "$nano_state" + "emacs" "Extensible editor / IDE$(_inst emacs)" "$emacs_state" + ) + if ! $headless; then + local vimgtk_state; vimgtk_state=$(_state "vim-gtk3") + local kate_state; kate_state=$(_state "kate") + local mousepad_state; mousepad_state=$(_state "mousepad") + local gedit_state; gedit_state=$(_state "gedit") + local geany_state; geany_state=$(_state "geany") + local gte_state; gte_state=$(_state "gnome-text-editor") + local codium_state="OFF" + if command -v codium &>/dev/null; then + codium_state="ON" + fi + items+=( + "vim-gtk3" "Vim with GTK3 GUI$(_inst vim-gtk3)" "$vimgtk_state" + "kate" "KDE advanced text editor$(_inst kate)" "$kate_state" + "mousepad" "Xfce text editor$(_inst mousepad)" "$mousepad_state" + "gedit" "GNOME text editor$(_inst gedit)" "$gedit_state" + "geany" "Lightweight IDE$(_inst geany)" "$geany_state" + "gnome-text-editor" "GNOME modern text editor$(_inst gnome-text-editor)" "$gte_state" + "vscodium" "VS Code open-source (extrepo)$(_inst codium)" "$codium_state" + ) fi local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6)) local choices choices=$(_checklist "Programming Applications" "Select editors and IDEs${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \ - "vim" "Classic terminal editor$(_inst vim)" "$vim_state" \ - "vim-gtk3" "Vim with GTK3 GUI$(_inst vim-gtk3)" "$vimgtk_state" \ - "neovim" "Modern vim fork$(_inst neovim)" "$neovim_state" \ - "hx" "Helix modal editor (Rust)$(_inst hx)" "$hx_state" \ - "nano" "Simple terminal editor$(_inst nano)" "$nano_state" \ - "emacs" "Extensible editor / IDE$(_inst emacs)" "$emacs_state" \ - "kate" "KDE advanced text editor$(_inst kate)" "$kate_state" \ - "mousepad" "Xfce text editor$(_inst mousepad)" "$mousepad_state" \ - "gedit" "GNOME text editor$(_inst gedit)" "$gedit_state" \ - "geany" "Lightweight IDE$(_inst geany)" "$geany_state" \ - "gnome-text-editor" "GNOME modern text editor$(_inst gnome-text-editor)" "$gte_state" \ - "vscodium" "VS Code open-source (extrepo)$(_inst codium)" "$codium_state" \ + "${items[@]}" \ ) clear @@ -48,10 +56,6 @@ _cat_programming() { install_vscodium ;; *) - if $headless; then - echo "Skipping $pkg (headless mode)" - continue - fi if ! is_installed "$pkg"; then _run_install "$pkg" else diff --git a/modules/extras/security/security.sh b/modules/extras/security/security.sh index a01fac4..41c1130 100644 --- a/modules/extras/security/security.sh +++ b/modules/extras/security/security.sh @@ -4,22 +4,30 @@ _cat_security() { local headless=false _is_headless && headless=true - local wireshark_state; wireshark_state=$(_state "wireshark") - local tcpdump_state; tcpdump_state=$(_state "tcpdump") - local zenmap_state; zenmap_state=$(_state "zenmap") - local fail2ban_state; fail2ban_state=$(_state "fail2ban") - local ufw_state; ufw_state=$(_state "ufw") - local clamav_state; clamav_state=$(_state "clamav") + local -a items=() + if ! $headless; then + local wireshark_state; wireshark_state=$(_state "wireshark") + local zenmap_state; zenmap_state=$(_state "zenmap") + items+=( + "wireshark" "Network protocol analyzer (GUI)$(_inst wireshark)" "$wireshark_state" + "zenmap" "Network scanner GUI (Nmap frontend)$(_inst zenmap)" "$zenmap_state" + ) + fi + local tcpdump_state; tcpdump_state=$(_state "tcpdump") + local fail2ban_state; fail2ban_state=$(_state "fail2ban") + local ufw_state; ufw_state=$(_state "ufw") + local clamav_state; clamav_state=$(_state "clamav") + items+=( + "tcpdump" "Command-line packet analyzer$(_inst tcpdump)" "$tcpdump_state" + "fail2ban" "Brute-force protection daemon$(_inst fail2ban)" "$fail2ban_state" + "ufw" "Uncomplicated firewall$(_inst ufw)" "$ufw_state" + "clamav" "Antivirus engine (ClamAV)$(_inst clamav)" "$clamav_state" + ) local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6)) local choices choices=$(_checklist "Security & Networking" "Select security and networking tools${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \ - "wireshark" "Network protocol analyzer (GUI)$(_inst wireshark)" "$wireshark_state" \ - "tcpdump" "Command-line packet analyzer$(_inst tcpdump)" "$tcpdump_state" \ - "zenmap" "Network scanner GUI (Nmap frontend)$(_inst zenmap)" "$zenmap_state" \ - "fail2ban" "Brute-force protection daemon$(_inst fail2ban)" "$fail2ban_state" \ - "ufw" "Uncomplicated firewall$(_inst ufw)" "$ufw_state" \ - "clamav" "Antivirus engine (ClamAV)$(_inst clamav)" "$clamav_state" \ + "${items[@]}" \ ) clear diff --git a/modules/extras/system/software_centers.sh b/modules/extras/system/software_centers.sh index 26f820c..3048564 100644 --- a/modules/extras/system/software_centers.sh +++ b/modules/extras/system/software_centers.sh @@ -1,6 +1,12 @@ # software_centers.sh — Standalone Software Center installer _cat_software_centers() { + local headless=false + _is_headless && headless=true + if $headless; then + echo "Software centers require a GUI — skipping." + return + fi local de_type de_type=$(_detect_desktop_type) local sc_choice diff --git a/modules/extras/system/system.sh b/modules/extras/system/system.sh index 4466517..11bf8c6 100644 --- a/modules/extras/system/system.sh +++ b/modules/extras/system/system.sh @@ -19,7 +19,7 @@ _detect_desktop_type() { _cat_general() { local headless=false _is_headless && headless=true - local alacritty_state; alacritty_state=$(_state "alacritty") + local -a items=() local btop_state; btop_state=$(_state "btop") local compress_state if is_installed "zip" && is_installed "unzip" && is_installed "p7zip-full"; then @@ -27,8 +27,6 @@ _cat_general() { else compress_state="OFF" fi - local conky_state; conky_state=$(_state "conky") - local corectrl_state; corectrl_state=$(_state "corectrl") local cpufetch_state; cpufetch_state=$(_state "cpufetch") local cpu_x_state; cpu_x_state=$(_state "cpu-x") local curl_wget_state @@ -37,60 +35,70 @@ _cat_general() { else curl_wget_state="OFF" fi - local dcgtk_state; dcgtk_state=$(_state "doublecmd-gtk") - local dcqt_state; dcqt_state=$(_state "doublecmd-qt") local extrepo_state; extrepo_state=$(_state "extrepo") local flatpak_state; flatpak_state=$(_state "flatpak") local fwupd_state; fwupd_state=$(_state "fwupd") - local disks_state; disks_state=$(_state "gnome-disk-utility") - local gparted_state; gparted_state=$(_state "gparted") - local hardinfo_state; hardinfo_state=$(_state "hardinfo") local htop_state; htop_state=$(_state "htop") local inxi_state; inxi_state=$(_state "inxi") - local kitty_state; kitty_state=$(_state "kitty") local kvm_state; kvm_state=$(_state "virt-manager") local lshw_state; lshw_state=$(_state "lshw") local mc_state; mc_state=$(_state "mc") local nala_state; nala_state=$(_state "nala") local ncdu_state; ncdu_state=$(_state "ncdu") - local psensor_state; psensor_state=$(_state "psensor") - local timeshift_state; timeshift_state=$(_state "timeshift") local tmux_state; tmux_state=$(_state "tmux") local wine_state; wine_state=$(_state "wine") local nvme_state; nvme_state=$(_state "nvme-cli") + items+=( + "btop" "Resource monitor (fancy top)$(_inst btop)" "$btop_state" + "compress" "Compression tools (zip, unrar, 7z)$(_inst zip)" "$compress_state" + "cpufetch" "CPU info fetcher$(_inst cpufetch)" "$cpufetch_state" + "cpu-x" "CPU-X (alternative to CPU-Z)$(_inst cpu-x)" "$cpu_x_state" + "curl-wget" "HTTP transfer tools (curl, wget)$(_inst curl)" "$curl_wget_state" + "extrepo" "External repository manager$(_inst extrepo)" "$extrepo_state" + "flatpak" "Flatpak sandbox + Flathub$(_inst flatpak)" "$flatpak_state" + "fwupd" "Firmware update daemon$(_inst fwupd)" "$fwupd_state" + "htop" "Interactive process viewer$(_inst htop)" "$htop_state" + "inxi" "System information tool$(_inst inxi)" "$inxi_state" + "kvm" "QEMU/KVM virtualization$(_inst virt-manager)" "$kvm_state" + "lshw" "List hardware details$(_inst lshw)" "$lshw_state" + "mc" "Midnight Commander (file manager)$(_inst mc)" "$mc_state" + "nala" "APT frontend (parallel downloads)$(_inst nala)" "$nala_state" + "ncdu" "Disk usage analyzer (ncurses)$(_inst ncdu)" "$ncdu_state" + "nvme-cli" "NVMe SSD health monitoring$(_inst nvme-cli)" "$nvme_state" + "tmux" "Terminal multiplexer$(_inst tmux)" "$tmux_state" + "wine" "Windows compatibility layer$(_inst wine)" "$wine_state" + ) + if ! $headless; then + local alacritty_state; alacritty_state=$(_state "alacritty") + local conky_state; conky_state=$(_state "conky") + local corectrl_state; corectrl_state=$(_state "corectrl") + local dcgtk_state; dcgtk_state=$(_state "doublecmd-gtk") + local dcqt_state; dcqt_state=$(_state "doublecmd-qt") + local disks_state; disks_state=$(_state "gnome-disk-utility") + local gparted_state; gparted_state=$(_state "gparted") + local hardinfo_state; hardinfo_state=$(_state "hardinfo") + local kitty_state; kitty_state=$(_state "kitty") + local psensor_state; psensor_state=$(_state "psensor") + local timeshift_state; timeshift_state=$(_state "timeshift") + items+=( + "alacritty" "GPU-accelerated terminal$(_inst alacritty)" "$alacritty_state" + "conky" "System monitor for desktop$(_inst conky)" "$conky_state" + "corectrl" "AMD GPU control (CoreCtrl)$(_inst corectrl)" "$corectrl_state" + "doublecmd-gtk" "Dual-panel file manager (GTK)$(_inst doublecmd-gtk)" "$dcgtk_state" + "doublecmd-qt" "Dual-panel file manager (Qt)$(_inst doublecmd-qt)" "$dcqt_state" + "gnome-disk-utility" "Disk management GUI$(_inst gnome-disk-utility)" "$disks_state" + "gparted" "GNOME partition editor$(_inst gparted)" "$gparted_state" + "hardinfo" "Graphical system profiler$(_inst hardinfo)" "$hardinfo_state" + "kitty" "GPU-based terminal emulator$(_inst kitty)" "$kitty_state" + "psensor" "Hardware temperature monitor$(_inst psensor)" "$psensor_state" + "timeshift" "System restore snapshots$(_inst timeshift)" "$timeshift_state" + ) + fi local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6)) local choices choices=$(_checklist "System Tools" "Select system utilities to install${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \ - "alacritty" "GPU-accelerated terminal$(_inst alacritty)" "$alacritty_state" \ - "btop" "Resource monitor (fancy top)$(_inst btop)" "$btop_state" \ - "compress" "Compression tools (zip, unrar, 7z)$(_inst zip)" "$compress_state" \ - "conky" "System monitor for desktop$(_inst conky)" "$conky_state" \ - "corectrl" "AMD GPU control (CoreCtrl)$(_inst corectrl)" "$corectrl_state" \ - "cpufetch" "CPU info fetcher$(_inst cpufetch)" "$cpufetch_state" \ - "cpu-x" "CPU-X (alternative to CPU-Z)$(_inst cpu-x)" "$cpu_x_state" \ - "curl-wget" "HTTP transfer tools (curl, wget)$(_inst curl)" "$curl_wget_state" \ - "doublecmd-gtk" "Dual-panel file manager (GTK)$(_inst doublecmd-gtk)" "$dcgtk_state" \ - "doublecmd-qt" "Dual-panel file manager (Qt)$(_inst doublecmd-qt)" "$dcqt_state" \ - "extrepo" "External repository manager$(_inst extrepo)" "$extrepo_state" \ - "flatpak" "Flatpak sandbox + Flathub$(_inst flatpak)" "$flatpak_state" \ - "fwupd" "Firmware update daemon$(_inst fwupd)" "$fwupd_state" \ - "gnome-disk-utility" "Disk management GUI$(_inst gnome-disk-utility)" "$disks_state" \ - "gparted" "GNOME partition editor$(_inst gparted)" "$gparted_state" \ - "hardinfo" "Graphical system profiler$(_inst hardinfo)" "$hardinfo_state" \ - "htop" "Interactive process viewer$(_inst htop)" "$htop_state" \ - "inxi" "System information tool$(_inst inxi)" "$inxi_state" \ - "kitty" "GPU-based terminal emulator$(_inst kitty)" "$kitty_state" \ - "kvm" "QEMU/KVM virtualization$(_inst virt-manager)" "$kvm_state" \ - "lshw" "List hardware details$(_inst lshw)" "$lshw_state" \ - "mc" "Midnight Commander (file manager)$(_inst mc)" "$mc_state" \ - "nvme-cli" "NVMe SSD health monitoring$(_inst nvme-cli)" "$nvme_state" \ - "nala" "APT frontend (parallel downloads)$(_inst nala)" "$nala_state" \ - "ncdu" "Disk usage analyzer (ncurses)$(_inst ncdu)" "$ncdu_state" \ - "psensor" "Hardware temperature monitor$(_inst psensor)" "$psensor_state" \ - "timeshift" "System restore snapshots$(_inst timeshift)" "$timeshift_state" \ - "tmux" "Terminal multiplexer$(_inst tmux)" "$tmux_state" \ - "wine" "Windows compatibility layer$(_inst wine)" "$wine_state" \ + "${items[@]}" \ ) clear @@ -256,10 +264,6 @@ _cat_general() { fi ;; *) - if $headless; then - echo "Skipping $pkg (headless mode)" - continue - fi if ! is_installed "$pkg"; then _run_install "$pkg" else diff --git a/modules/extras/themes/cursors/cursors.sh b/modules/extras/themes/cursors/cursors.sh index 5d67922..94d9a22 100644 --- a/modules/extras/themes/cursors/cursors.sh +++ b/modules/extras/themes/cursors/cursors.sh @@ -2,21 +2,29 @@ # cursors.sh — Cursor themes _cat_cursors() { - local bibata_state; bibata_state=$(_state "bibata-cursor-theme") - local breeze_state; breeze_state=$(_state "breeze-cursor-theme") - local chameleon_state; chameleon_state=$(_state "chameleon-cursor-theme") - local dmz_state; dmz_state=$(_state "dmz-cursor-theme") - local xcursor_state; xcursor_state=$(_state "xcursor-themes") - local oxygen_state; oxygen_state=$(_state "oxygencursors") + local headless=false + _is_headless && headless=true + local -a items=() + if ! $headless; then + local bibata_state; bibata_state=$(_state "bibata-cursor-theme") + local breeze_state; breeze_state=$(_state "breeze-cursor-theme") + local chameleon_state; chameleon_state=$(_state "chameleon-cursor-theme") + local dmz_state; dmz_state=$(_state "dmz-cursor-theme") + local xcursor_state; xcursor_state=$(_state "xcursor-themes") + local oxygen_state; oxygen_state=$(_state "oxygencursors") + items+=( + "bibata-cursor-theme" "Bibata cursors$(_inst bibata-cursor-theme)" "$bibata_state" + "breeze-cursor-theme" "Breeze cursors (KDE)$(_inst breeze-cursor-theme)" "$breeze_state" + "chameleon-cursor-theme" "Chameleon cursors$(_inst chameleon-cursor-theme)" "$chameleon_state" + "dmz-cursor-theme" "DMZ cursors$(_inst dmz-cursor-theme)" "$dmz_state" + "xcursor-themes" "X11 base cursors$(_inst xcursor-themes)" "$xcursor_state" + "oxygencursors" "Oxygen cursors (KDE legacy)$(_inst oxygencursors)" "$oxygen_state" + ) + fi local choices choices=$(_checklist "Cursor Themes" "Select cursor themes to install${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \ - "bibata-cursor-theme" "Bibata cursors$(_inst bibata-cursor-theme)" "$bibata_state" \ - "breeze-cursor-theme" "Breeze cursors (KDE)$(_inst breeze-cursor-theme)" "$breeze_state" \ - "chameleon-cursor-theme" "Chameleon cursors$(_inst chameleon-cursor-theme)" "$chameleon_state" \ - "dmz-cursor-theme" "DMZ cursors$(_inst dmz-cursor-theme)" "$dmz_state" \ - "xcursor-themes" "X11 base cursors$(_inst xcursor-themes)" "$xcursor_state" \ - "oxygencursors" "Oxygen cursors (KDE legacy)$(_inst oxygencursors)" "$oxygen_state" \ + "${items[@]}" \ ) clear diff --git a/modules/extras/themes/desktop-themes/desktop-themes.sh b/modules/extras/themes/desktop-themes/desktop-themes.sh index aaf8e14..c4496c4 100644 --- a/modules/extras/themes/desktop-themes/desktop-themes.sh +++ b/modules/extras/themes/desktop-themes/desktop-themes.sh @@ -4,23 +4,29 @@ _cat_themes() { local headless=false _is_headless && headless=true - local arc_state; arc_state=$(_state "arc-theme") - local blackbird_state; blackbird_state=$(_state "blackbird-gtk-theme") - local bluebird_state; bluebird_state=$(_state "bluebird-gtk-theme") - local breeze_gtk_state; breeze_gtk_state=$(_state "breeze-gtk-theme") - local greybird_state; greybird_state=$(_state "greybird-gtk-theme") - local numix_gtk_state; numix_gtk_state=$(_state "numix-gtk-theme") - local orchis_state; orchis_state=$(_state "orchis-gtk-theme") + local -a items=() + if ! $headless; then + local arc_state; arc_state=$(_state "arc-theme") + local blackbird_state; blackbird_state=$(_state "blackbird-gtk-theme") + local bluebird_state; bluebird_state=$(_state "bluebird-gtk-theme") + local breeze_gtk_state; breeze_gtk_state=$(_state "breeze-gtk-theme") + local greybird_state; greybird_state=$(_state "greybird-gtk-theme") + local numix_gtk_state; numix_gtk_state=$(_state "numix-gtk-theme") + local orchis_state; orchis_state=$(_state "orchis-gtk-theme") + items+=( + "arc-theme" "Arc GTK theme$(_inst arc-theme)" "$arc_state" + "blackbird-gtk-theme" "Blackbird GTK theme$(_inst blackbird-gtk-theme)" "$blackbird_state" + "bluebird-gtk-theme" "Bluebird GTK theme$(_inst bluebird-gtk-theme)" "$bluebird_state" + "breeze-gtk-theme" "Breeze GTK theme (KDE port)$(_inst breeze-gtk-theme)" "$breeze_gtk_state" + "greybird-gtk-theme" "Greybird GTK theme$(_inst greybird-gtk-theme)" "$greybird_state" + "numix-gtk-theme" "Numix GTK theme$(_inst numix-gtk-theme)" "$numix_gtk_state" + "orchis-gtk-theme" "Orchis GTK theme$(_inst orchis-gtk-theme)" "$orchis_state" + ) + fi local choices choices=$(_checklist "Desktop Themes (GTK/KDE)" "Select desktop themes to install${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \ - "arc-theme" "Arc GTK theme$(_inst arc-theme)" "$arc_state" \ - "blackbird-gtk-theme" "Blackbird GTK theme$(_inst blackbird-gtk-theme)" "$blackbird_state" \ - "bluebird-gtk-theme" "Bluebird GTK theme$(_inst bluebird-gtk-theme)" "$bluebird_state" \ - "breeze-gtk-theme" "Breeze GTK theme (KDE port)$(_inst breeze-gtk-theme)" "$breeze_gtk_state" \ - "greybird-gtk-theme" "Greybird GTK theme$(_inst greybird-gtk-theme)" "$greybird_state" \ - "numix-gtk-theme" "Numix GTK theme$(_inst numix-gtk-theme)" "$numix_gtk_state" \ - "orchis-gtk-theme" "Orchis GTK theme$(_inst orchis-gtk-theme)" "$orchis_state" \ + "${items[@]}" \ ) clear @@ -29,10 +35,6 @@ _cat_themes() { local cleaned; cleaned=$(echo "$choices" | tr -d '"') for pkg in $cleaned; do - if $headless; then - echo "Skipping $pkg (headless mode)" - continue - fi if ! is_installed "$pkg"; then _run_install "$pkg" else diff --git a/modules/extras/themes/fonts/fonts.sh b/modules/extras/themes/fonts/fonts.sh index 0a48b12..421675f 100644 --- a/modules/extras/themes/fonts/fonts.sh +++ b/modules/extras/themes/fonts/fonts.sh @@ -2,25 +2,33 @@ # fonts.sh — Fonts _cat_fonts() { - local bebas_state; bebas_state=$(_state "fonts-bebas-neue") - local anon_state; anon_state=$(_state "fonts-anonymous-pro") - local verana_state; verana_state=$(_state "fonts-adf-verana") - local f3270_state; f3270_state=$(_state "fonts-3270") - local liberation_state; liberation_state=$(_state "fonts-liberation") - local mscore_state; mscore_state=$(_state "ttf-mscorefonts-installer") - local ubuntu_state; ubuntu_state=$(_state "fonts-ubuntu") - local recommended_state; recommended_state=$(_state "fonts-recommended") + local headless=false + _is_headless && headless=true + local -a items=() + if ! $headless; then + local bebas_state; bebas_state=$(_state "fonts-bebas-neue") + local anon_state; anon_state=$(_state "fonts-anonymous-pro") + local verana_state; verana_state=$(_state "fonts-adf-verana") + local f3270_state; f3270_state=$(_state "fonts-3270") + local liberation_state; liberation_state=$(_state "fonts-liberation") + local mscore_state; mscore_state=$(_state "ttf-mscorefonts-installer") + local ubuntu_state; ubuntu_state=$(_state "fonts-ubuntu") + local recommended_state; recommended_state=$(_state "fonts-recommended") + items+=( + "fonts-bebas-neue" "Bebas Neue (display)$(_inst fonts-bebas-neue)" "$bebas_state" + "fonts-anonymous-pro" "Anonymous Pro (monospace)$(_inst fonts-anonymous-pro)" "$anon_state" + "fonts-adf-verana" "ADF Verana (sans-serif)$(_inst fonts-adf-verana)" "$verana_state" + "fonts-3270" "IBM 3270 terminal font$(_inst fonts-3270)" "$f3270_state" + "fonts-liberation" "Liberation (MS-compatible)$(_inst fonts-liberation)" "$liberation_state" + "ttf-mscorefonts-installer" "Microsoft fonts (EULA required)$(_inst ttf-mscorefonts-installer)" "$mscore_state" + "fonts-ubuntu" "Ubuntu font family$(_inst fonts-ubuntu)" "$ubuntu_state" + "fonts-recommended" "Debian recommended fonts$(_inst fonts-recommended)" "$recommended_state" + ) + fi local choices choices=$(_checklist "Fonts" "Select fonts to install${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \ - "fonts-bebas-neue" "Bebas Neue (display)$(_inst fonts-bebas-neue)" "$bebas_state" \ - "fonts-anonymous-pro" "Anonymous Pro (monospace)$(_inst fonts-anonymous-pro)" "$anon_state" \ - "fonts-adf-verana" "ADF Verana (sans-serif)$(_inst fonts-adf-verana)" "$verana_state" \ - "fonts-3270" "IBM 3270 terminal font$(_inst fonts-3270)" "$f3270_state" \ - "fonts-liberation" "Liberation (MS-compatible)$(_inst fonts-liberation)" "$liberation_state" \ - "ttf-mscorefonts-installer" "Microsoft fonts (EULA required)$(_inst ttf-mscorefonts-installer)" "$mscore_state" \ - "fonts-ubuntu" "Ubuntu font family$(_inst fonts-ubuntu)" "$ubuntu_state" \ - "fonts-recommended" "Debian recommended fonts$(_inst fonts-recommended)" "$recommended_state" \ + "${items[@]}" \ ) clear diff --git a/modules/extras/themes/icons/icons.sh b/modules/extras/themes/icons/icons.sh index 3a0594e..b6aa67b 100644 --- a/modules/extras/themes/icons/icons.sh +++ b/modules/extras/themes/icons/icons.sh @@ -4,40 +4,41 @@ _cat_icons() { local headless=false _is_headless && headless=true - local breeze_state; breeze_state=$(_state "breeze-icon-theme") - local deepin_state; deepin_state=$(_state "deepin-icon-theme") - local ele_state; ele_state=$(_state "elementary-icon-theme") - local ele_xfce_state; ele_xfce_state=$(_state "elementary-xfce-icon-theme") - local moka_state; moka_state=$(_state "moka-icon-theme") - local numix_state; numix_state=$(_state "numix-icon-theme") - local numix_c_state; numix_c_state=$(_state "numix-icon-theme-circle") - local obsidian_state; obsidian_state=$(_state "obsidian-icon-theme") - local papirus_state; papirus_state=$(_state "papirus-icon-theme") - local paper_state; paper_state=$(_state "paper-icon-theme") - local suru_state; suru_state=$(_state "suru-icon-theme") + local -a items=() + if ! $headless; then + local breeze_state; breeze_state=$(_state "breeze-icon-theme") + local deepin_state; deepin_state=$(_state "deepin-icon-theme") + local ele_state; ele_state=$(_state "elementary-icon-theme") + local ele_xfce_state; ele_xfce_state=$(_state "elementary-xfce-icon-theme") + local moka_state; moka_state=$(_state "moka-icon-theme") + local numix_state; numix_state=$(_state "numix-icon-theme") + local numix_c_state; numix_c_state=$(_state "numix-icon-theme-circle") + local obsidian_state; obsidian_state=$(_state "obsidian-icon-theme") + local papirus_state; papirus_state=$(_state "papirus-icon-theme") + local paper_state; paper_state=$(_state "paper-icon-theme") + local suru_state; suru_state=$(_state "suru-icon-theme") - local kf6_state="OFF" - local has_kf6=false - if [ "$DEBIAN_CODENAME" = "trixie" ]; then - kf6_state=$(_state "kf6-breeze-icon-theme") - has_kf6=true - fi + local kf6_state="OFF" + if [ "$DEBIAN_CODENAME" = "trixie" ]; then + kf6_state=$(_state "kf6-breeze-icon-theme") + fi - local items=( - "breeze-icon-theme" "Breeze icon theme$(_inst breeze-icon-theme)" "$breeze_state" - "deepin-icon-theme" "Deepin icon theme$(_inst deepin-icon-theme)" "$deepin_state" - "elementary-icon-theme" "Elementary icon theme$(_inst elementary-icon-theme)" "$ele_state" - "elementary-xfce-icon-theme" "Elementary Xfce icons$(_inst elementary-xfce-icon-theme)" "$ele_xfce_state" - "moka-icon-theme" "Moka icon theme$(_inst moka-icon-theme)" "$moka_state" - "numix-icon-theme" "Numix icon theme$(_inst numix-icon-theme)" "$numix_state" - "numix-icon-theme-circle" "Numix Circle icon theme$(_inst numix-icon-theme-circle)" "$numix_c_state" - "obsidian-icon-theme" "Obsidian icon theme$(_inst obsidian-icon-theme)" "$obsidian_state" - "papirus-icon-theme" "Papirus icon theme$(_inst papirus-icon-theme)" "$papirus_state" - "paper-icon-theme" "Paper icon theme$(_inst paper-icon-theme)" "$paper_state" - "suru-icon-theme" "Suru icon theme$(_inst suru-icon-theme)" "$suru_state" - ) - if $has_kf6; then - items+=("kf6-breeze-icon-theme" "KF6 Breeze icon theme$(_inst kf6-breeze-icon-theme)" "$kf6_state") + items=( + "breeze-icon-theme" "Breeze icon theme$(_inst breeze-icon-theme)" "$breeze_state" + "deepin-icon-theme" "Deepin icon theme$(_inst deepin-icon-theme)" "$deepin_state" + "elementary-icon-theme" "Elementary icon theme$(_inst elementary-icon-theme)" "$ele_state" + "elementary-xfce-icon-theme" "Elementary Xfce icons$(_inst elementary-xfce-icon-theme)" "$ele_xfce_state" + "moka-icon-theme" "Moka icon theme$(_inst moka-icon-theme)" "$moka_state" + "numix-icon-theme" "Numix icon theme$(_inst numix-icon-theme)" "$numix_state" + "numix-icon-theme-circle" "Numix Circle icon theme$(_inst numix-icon-theme-circle)" "$numix_c_state" + "obsidian-icon-theme" "Obsidian icon theme$(_inst obsidian-icon-theme)" "$obsidian_state" + "papirus-icon-theme" "Papirus icon theme$(_inst papirus-icon-theme)" "$papirus_state" + "paper-icon-theme" "Paper icon theme$(_inst paper-icon-theme)" "$paper_state" + "suru-icon-theme" "Suru icon theme$(_inst suru-icon-theme)" "$suru_state" + ) + if [ "$DEBIAN_CODENAME" = "trixie" ]; then + items+=("kf6-breeze-icon-theme" "KF6 Breeze icon theme$(_inst kf6-breeze-icon-theme)" "$kf6_state") + fi fi local choices @@ -51,10 +52,6 @@ _cat_icons() { local cleaned; cleaned=$(echo "$choices" | tr -d '"') for pkg in $cleaned; do - if $headless; then - echo "Skipping $pkg (headless mode)" - continue - fi if ! is_installed "$pkg"; then _run_install "$pkg" else diff --git a/modules/firmware.sh b/modules/firmware.sh index 865635c..001a19e 100644 --- a/modules/firmware.sh +++ b/modules/firmware.sh @@ -130,7 +130,7 @@ _is_broadcom_b43() { local dec=$((16#$id)) if [ "$dec" -ge $((16#4301)) ] && [ "$dec" -le $((16#4331)) ]; then return 0; fi if [ "$dec" -ge $((16#4336)) ] && [ "$dec" -le $((16#4338)) ]; then return 0; fi - case "$id" in 4352|4357|4358|4360|4727) return 0 ;; esac + case "$id" in 4352) return 0 ;; esac return 1 } @@ -255,8 +255,22 @@ _handle_wireless() { fi installed_any=true elif _is_broadcom_b43 "$dev_id"; then - _run_install_pkg firmware-b43-installer - installed_any=true + if ! dpkg -l firmware-b43-installer >/dev/null 2>&1; then + _run_install_pkg firmware-b43-installer + fi + + if [ ! -d /lib/firmware/b43 ] || [ -z "$(ls -A /lib/firmware/b43 2>/dev/null)" ]; then + _msg "b43 Firmware Warning" \ + "The firmware-b43-installer package was installed, but the\n\ +proprietary firmware download appears to have failed\n\ +(no files found in /lib/firmware/b43).\n\n\ +To fix this, connect a wired network and run:\n\ + sudo dpkg-reconfigure firmware-b43-installer\n\n\ +After the firmware is downloaded, reboot the system." 14 75 + _pause + else + installed_any=true + fi elif _is_broadcom_b43legacy "$dev_id"; then _run_install_pkg firmware-b43legacy-installer installed_any=true @@ -264,9 +278,34 @@ _handle_wireless() { local bcm_ver header_ver bcm_ver=$(apt-cache policy broadcom-sta-dkms 2>/dev/null | awk 'NR==3 {print $2; exit}') header_ver=$(apt-cache policy linux-headers-$(uname -r) 2>/dev/null | awk 'NR==3 {print $2; exit}') + + if ! apt-cache policy "linux-headers-$(uname -r)" 2>/dev/null | grep -q "Candidate: [^ (none)]"; then + _msg "Broadcom Error" \ + "linux-headers-$(uname -r) not available.\n\nCannot compile broadcom-sta-dkms without kernel headers." 10 60 + _pause + continue + fi + if _confirm "Broadcom WiFi" "Install Broadcom driver?\n\nRequired for this chipset. Compiles a kernel module.\n\n broadcom-sta-dkms ${bcm_ver:-unknown}\n linux-headers-$(uname -r) ${header_ver:-unknown}\n\nProceed?"; then _run_cmd "Broadcom" "sudo DEBIAN_FRONTEND=noninteractive apt install -y linux-headers-$(uname -r) broadcom-sta-dkms" \ "Installing Broadcom driver..." + + local has_broadcom_bt=false + for btdev in "${PCI_BT_DEVS[@]}"; do + if echo "$btdev" | grep -qi 'broadcom'; then + has_broadcom_bt=true + break + fi + done + if $has_broadcom_bt; then + echo -e "${YELLOW}Broadcom combo card (WiFi + Bluetooth) detected.${NC}" + cat > /etc/modprobe.d/broadcom-combo.conf <<'EOF' +# Broadcom combo: ensure btusb loads after wl +softdep wl post: btusb +EOF + echo -e "${YELLOW}A reboot may be required for Bluetooth to work correctly.${NC}" + fi + echo "Broadcom proprietary driver installed. A reboot may be required." _pause installed_any=true @@ -286,14 +325,44 @@ _handle_wireless() { fi } +# ── Ensure non-free repository is enabled ── +_ensure_nonfree_repo() { + local nonfree_found=false + if [ -f /etc/apt/sources.list ] && grep -Eq '^[^#]*\bnon-free\b' /etc/apt/sources.list 2>/dev/null; then + nonfree_found=true + fi + if ! $nonfree_found && [ -d /etc/apt/sources.list.d ]; then + if grep -qr 'Components:.*\bnon-free\b' /etc/apt/sources.list.d/*.sources 2>/dev/null; then + nonfree_found=true + fi + fi + if $nonfree_found; then + return 0 + fi + + if _confirm "non-free Repository" "Component 'non-free' (and 'non-free-firmware') is required for WiFi/Bluetooth/GPU firmware.\n\nAdd them to your APT repositories?"; then + if [ -f /etc/apt/sources.list ]; then + sudo sed -i '/^deb / { /non-free/! s/\(main[^ ]*\)/\1 non-free non-free-firmware/ }' /etc/apt/sources.list + fi + if [ -d /etc/apt/sources.list.d ]; then + for f in /etc/apt/sources.list.d/*.sources; do + [ -f "$f" ] || continue + sudo sed -i '/^Components:/ { /non-free/! s/$/ non-free non-free-firmware/ }' "$f" + done + fi + sudo apt update + echo -e "${GREEN}non-free repository enabled.${NC}" + return 0 + fi + return 1 +} + # ── Main entry point ── install_firmware() { echo -e "${YELLOW}Base firmware check...${NC}" - if ! grep -qr "non-free" /etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/null; then - _msg "Error" "Error: No 'non-free' repositories were detected.\n\ -Please first run the 'Configure repositories' option in the\n\ -main menu to install proprietary firmwares." 10 65 + if ! _ensure_nonfree_repo; then + _msg "Error" "No 'non-free' repositories were enabled and the user declined to add them.\nPlease enable non-free manually or accept the prompt in the Firmware option." 10 65 return 1 fi diff --git a/modules/repos/migrate.sh b/modules/repos/migrate.sh index c04870f..3c14e73 100644 --- a/modules/repos/migrate.sh +++ b/modules/repos/migrate.sh @@ -62,7 +62,7 @@ _write_deb822_branch() { _branch_migration() { # ── Screen 1: Risk warning ── - _msg "WARNING: Branch Migration" \ + _msg_red "WARNING: Branch Migration" \ "Migrating from Debian Stable to Testing or SID is a\n\ MAJOR change and CAN make your system UNBOOTABLE.\n\n\ Risks include:\n\ @@ -71,7 +71,7 @@ Risks include:\n\ • Some packages may be removed or replaced\n\ • SID (unstable) receives NO security updates\n\n\ A full persistent backup will be saved to /var/backups/\n\ -so you can restore if things go wrong." 16 70 || true +so you can restore if things go wrong." 16 70 if ! _confirm "Branch Migration" "Do you want to proceed with the migration?"; then echo "Migration cancelled." @@ -89,7 +89,7 @@ so you can restore if things go wrong." 16 70 || true plan+=" 7. Run: apt autoremove -y\n\n" plan+="If apt update fails, the backup is restored immediately." - _msg "Migration Plan" "$plan" 16 70 || true + _msg_red "Migration Plan" "$plan" 16 70 if ! _confirm "Migration Plan" "Proceed with the plan?"; then echo "Migration cancelled." @@ -145,7 +145,7 @@ so you can restore if things go wrong." 16 70 || true if ! sudo apt update; then echo -e "${RED}apt update failed. Restoring backup...${NC}" _restore_backup - _msg "Migration Failed" \ + _msg_red "Migration Failed" \ "apt update failed. Backup has been restored from:\n\ $_MIGRATE_BACKUP\n\n\ Your system should be back to its previous state.\n\ diff --git a/modules/utils.sh b/modules/utils.sh index 4081bd5..5094c45 100644 --- a/modules/utils.sh +++ b/modules/utils.sh @@ -550,6 +550,10 @@ _msg() { whiptail --title "$1" --msgbox "$2" "${3:-10}" "${4:-65}" || true } +_msg_red() { + whiptail --colors --title "\Z1$1\Zn" --msgbox "\Z1$2\Zn" "${3:-12}" "${4:-70}" || true +} + _menu() { local title="$1" text="$2" h="$3" w="$4" lh="$5"; shift 5 whiptail --title "$title" --menu "$text" "$h" "$w" "$lh" "$@" 3>&1 1>&2 2>&3 || true @@ -582,9 +586,8 @@ _validate_sudoers() { } _pause() { - echo "" - echo "Press [ENTER] to continue..." - read -r + local msg="${1:-Presiona OK para continuar.}" + whiptail --title "Continuar" --msgbox "$msg" 8 50 3>&1 1>&2 2>&3 || true } # Blocks 2-4: clear → run → pause @@ -712,22 +715,31 @@ _check_network() { # ---------------------------------- # LightDM configuration # ---------------------------------- -_configure_lightdm() { + _configure_lightdm() { command -v lightdm &>/dev/null || return 0 - if ! is_installed lightdm-gtk-greeter-settings; then - echo -e "${YELLOW}Installing lightdm-gtk-greeter-settings...${NC}" - sudo DEBIAN_FRONTEND=noninteractive apt install -y lightdm-gtk-greeter-settings + if _confirm "LightDM" "Configure LightDM to show the user list on the login screen?\n\nThis disables greeter-hide-users."; then + if ! is_installed lightdm-gtk-greeter-settings; then + echo -e "${YELLOW}Installing lightdm-gtk-greeter-settings...${NC}" + sudo DEBIAN_FRONTEND=noninteractive apt install -y lightdm-gtk-greeter-settings + fi + + local conf_dir="/etc/lightdm/lightdm.conf.d" + local conf_file="${conf_dir}/99-show-users.conf" + + if [ -f "$conf_file" ] && grep -q '^greeter-hide-users=false' "$conf_file"; then + return + fi + + sudo mkdir -p "$conf_dir" + printf '[Seat:*]\ngreeter-hide-users=false\n' | sudo tee "$conf_file" > /dev/null + echo -e "${GREEN}LightDM configured to show user list.${NC}" fi - - local conf_dir="/etc/lightdm/lightdm.conf.d" - local conf_file="${conf_dir}/99-show-users.conf" - - if [ -f "$conf_file" ] && grep -q '^greeter-hide-users=false' "$conf_file"; then - return - fi - - sudo mkdir -p "$conf_dir" - printf '[Seat:*]\ngreeter-hide-users=false\n' | sudo tee "$conf_file" > /dev/null - echo -e "${GREEN}LightDM configured to show user list.${NC}" +} + +# ── Lazy system state refresh ── +refresh_system_state() { + detect_debian_version + detect_gpu + detect_cpu_ram }