#!/bin/bash # ============================================================================= # hyprland.sh — Hyprland Desktop Environment installer (legacy hyprlang config) # ============================================================================= # Part of the Dotfiles setup system for Arch Linux. # # Hyprland is a dynamic tiling Wayland compositor built in C++ with a focus on # animations, eye-candy, and a powerful plugin system (hyprpm). # # This is the LEGACY variant that uses hyprlang (.conf) configuration files. # The newer hyprlua.sh uses Lua for configuration instead. Both installers # share a nearly identical package list; the key differences are: # - EWW and config source paths point to desktopenvs/hyprland/ (not hyprlua/) # - hypr-usr/ device-specific .conf files are placed at ~/.config/ root level # and sourced by hyprland.conf via 'source' directives # - hyprlua.sh additionally installs python-opencv and v4l-utils for the # webcam-based presence/idle detection daemon # # High-level install flow: # 1. System update + Flatpak # 2. pacman packages (compositor, audio, networking, tools, fonts) # 3. systemd service enablement (NetworkManager, ly display manager, udisks2) # 4. AUR packages via yay # 5. EWW status-bar (interactive form-factor selection + Rust compilation) # 6. Themes, icons, ly config, terminal symlink, SSH askpass # 7. Nordzy left-hand cursor theme # 8. Bluetooth / iwd wireless services # 9. Config file deployment from Dotfiles # 10. Wallpaper + resource files # 11. Python venv for helper scripts # 12. Udiskie tray-icon symlink fix # 13. config-updater symlinks + apply-theme.sh # # Prerequisites: internet access, yay (AUR helper), rustup, git, wget, cargo. # ============================================================================= # Exit immediately if any command fails — partial DE installs can leave the # system in a broken graphical state, so aborting early is safer. set -e # Load shared logging helpers (log, warn, err) from the setup library. source "$(dirname "${BASH_SOURCE[0]}")/../lib/logging.sh" log "Starting Hyprland installer (legacy — hyprlang config)..." # --------------------------------------------------------------------------- # 1. Update system and install Flatpak # --------------------------------------------------------------------------- # Run a full system upgrade first to avoid Arch partial-upgrade issues (on a # rolling release, installing new packages against an un-updated system can # cause library ABI mismatches). Flatpak is installed early so AUR steps that # depend on it can find it. log "Updating system and installing Flatpak..." sudo pacman -Syu --noconfirm --needed flatpak # --------------------------------------------------------------------------- # 2. Install required packages # --------------------------------------------------------------------------- log "Installing required packages..." # Packages live in an array so each can carry an inline comment. A single # backslash-continued `pacman` command cannot: bash treats the first inline # comment as the end of the command, silently dropping every later package # (which then get run as shell commands and abort under `set -e`). HYPRLAND_PACKAGES=( hyprland # the Wayland compositor / window manager hyprcursor # hardware-accelerated cursor rendering for Hyprland wl-clipboard # wl-copy / wl-paste; clipboard tools for Wayland hyprpaper # wallpaper utility with per-monitor and animation support hyprlock # GPU-accelerated screen locker (Hyprland-native) wofi # Wayland application launcher (rofi replacement) kitty # GPU-accelerated terminal (default terminal in this setup) dunst # lightweight, scriptable notification daemon nwg-dock-hyprland # dock/taskbar with Hyprland workspace awareness nwg-drawer # application drawer (grid-style launcher) nwg-menu # GTK menu used in the panel's app button nwg-look # GTK/cursor/icon theme picker for wlroots sessions # Build tools needed to compile EWW (Rust) and AUR packages (C/C++/Ruby) python cmake meson cpio pkgconf ruby-pkg-config hyprsunset # blue-light filter / night-mode daemon for Hyprland hypridle # idle daemon that triggers lock/suspend after inactivity ksshaskpass # Qt SSH passphrase dialog (registered as ssh-askpass) nm-connection-editor # GTK GUI for editing NetworkManager profiles network-manager-applet # system-tray applet showing Wi-Fi/VPN status blueman # GTK Bluetooth manager with tray icon bluez # core Linux Bluetooth protocol stack pipewire # modern audio/video routing daemon alsa-utils # ALSA CLI tools (amixer, aplay) for low-level audio firefox # web browser greetd-tuigreet # TUI login greeter (text-based, no GPU needed at DM) grim # Wayland screenshot tool (outputs to file or stdout) slurp # interactive region selector (used with grim) gst-plugin-pipewire # GStreamer plugin bridging through PipeWire imagemagick # image processing (screenshot effects, compositing) nerd-fonts # all Nerd Font patched families (icon glyphs in bar) otf-font-awesome # Font Awesome icon glyphs for EWW/dunst # Compatibility layers: let ALSA, JACK, and PulseAudio apps route through # PipeWire without requiring code changes in those apps pipewire-alsa pipewire-jack pipewire-pulse qt5-wayland # Qt5 platform plugin for native Wayland rendering qt6-wayland # Qt6 platform plugin for native Wayland rendering swww # smooth animated wallpaper daemon ttf-jetbrains-mono # monospace font for terminals and the EWW bar wireplumber # PipeWire session/policy manager qt6ct # Qt6 colour/style configurator (run as user) xdg-desktop-portal-hyprland # Hyprland XDG portal (screen share, file pick) xdg-utils # xdg-open / MIME handling helpers xorg-server # X server for XWayland (legacy X11 apps) xorg-xinit # startx / xinitrc support for XWayland papirus-icon-theme # icon theme used system-wide and by udiskie cool-retro-term # retro CRT-style terminal emulator qalculate-gtk # powerful GTK calculator with unit conversion iwd # Intel Wireless Daemon (lightweight Wi-Fi back-end) dbus # D-Bus inter-process communication daemon thunar # lightweight GTK file manager (XFCE project) tumbler # thumbnail service for Thunar thunar-archive-plugin # right-click archive (zip/tar) integration thunar-shares-plugin # Samba share management from Thunar thunar-volman # automatic volume/device mounting in Thunar hyprpicker # colour picker outputting hex/rgb/hsl under Hyprland pcmanfm-qt # Qt file manager kept as fallback udisks2 # D-Bus service for querying and managing storage devices ly # minimal TUI display manager (replaces getty on tty1) kew # terminal music player hyprpolkitagent # Hyprland-native Polkit authentication agent pavucontrol # PulseAudio/PipeWire volume control GUI playerctl # MPRIS media player controller (play/pause CLI) wf-recorder # screen recorder for wlroots compositors sound-theme-freedesktop # standard freedesktop sound event library ) sudo pacman -Syu --noconfirm --needed -- "${HYPRLAND_PACKAGES[@]}" # --------------------------------------------------------------------------- # 3. Enable essential services # --------------------------------------------------------------------------- log "Enabling essential services..." # NetworkManager must be active on boot for network connectivity. enable_service NetworkManager.service # getty@tty1 is the default text-mode login prompt; we replace it with ly. # '|| true' prevents abort if the unit is already disabled or doesn't exist. sudo systemctl disable getty@tty1.service || true # ly is the TUI display manager that runs on tty1 and launches Hyprland after # the user logs in. enable_service ly@tty1.service # udisks2 provides the D-Bus API for block devices; required by udiskie for # automatic USB/external drive mounting. enable_service udisks2.service # --------------------------------------------------------------------------- # 4. Install AUR packages # --------------------------------------------------------------------------- log "Installing AUR packages..." # Activate the stable Rust toolchain so AUR packages that compile Rust code # (and EWW compiled below) use a known-good toolchain version. rustup default stable # yay flags: # --answerdiff None — skip PKGBUILD diff display (non-interactive) # --answerclean All — always clean build dirs between builds # --noconfirm — no confirmation prompts # # Packages: # hyprland-workspaces — EWW workspace widget reading Hyprland IPC socket # vicinae-bin — pre-built vicinae (vim-like keybind layer for scripts) # bluetuith — TUI Bluetooth manager (used in the menus) # wvkbd — on-screen virtual keyboard for Wayland (touch) # iwmenu — wofi-based Wi-Fi network picker using iwd # pinta — simple image editor # walker-bin — fast app launcher / runner (pre-built binary) # ulauncher — extensible app launcher with plugin ecosystem # bzmenu — quick Bluetooth device connect menu for the bar # udiskie — automounter with tray icon (built on udisks2) # wofi-calc — inline calculator pop-up inside wofi # bri — brightness control CLI helper for bar widgets # chamel — theme-switching helper (applies colour palettes) yay -Syu --answerdiff None --answerclean All --noconfirm \ hyprland-workspaces vicinae-bin bluetuith wvkbd iwmenu pinta \ walker-bin ulauncher bzmenu udiskie \ wofi-calc bri chamel # --------------------------------------------------------------------------- # 5. EWW bar selection and compilation # --------------------------------------------------------------------------- # EWW (Elkowar's Wacky Widgets) is a Rust widget framework that powers the # custom status bar. Three layouts exist for different hardware form factors: # eww/ — Notebook layout (includes battery widget) # eww-nobattery/ — Desktop PC layout (no battery bar) # eww-touch/ — Tablet layout (larger touch targets) log "Setting up EWW bar..." # Wipe any previous EWW config to avoid stale widget definitions conflicting # with the freshly copied one. rm -rf ~/.config/eww # Prompt for form factor with a single keypress (no Enter needed). read -n1 -p "Install eww bar for PC, Notebook or Tablet [P/N/T]: " doit echo # Print newline so subsequent output starts on a fresh line case $doit in # Notebook: copy the battery-aware layout n|N) cp -rf ~/Dotfiles/desktopenvs/hyprland/eww/ ~/.config/ ;; # Desktop PC: copy the no-battery layout p|P) cp -rf ~/Dotfiles/desktopenvs/hyprland/eww-nobattery/ ~/.config/eww ;; # Tablet: copy touch-optimised layout t|T) cp -rf ~/Dotfiles/desktopenvs/hyprland/eww-touch/ ~/.config/eww ;; # Unknown key: warn and skip; the user must copy manually later *) warn "No valid choice — skipping EWW copy. Run manually later." ;; esac log "Compiling EWW..." # EWW is not in the official repos so we compile from source. # ~/install-tmp is a staging area for source trees fetched during installation. mkdir -p ~/install-tmp cd ~/install-tmp git clone https://github.com/elkowar/eww cd eww # --release → optimised binary (significantly faster than debug) # --no-default-features → disable the X11 backend entirely # --features=wayland → enable only the Wayland backend cargo build --release --no-default-features --features=wayland chmod +x target/release/eww # Install system-wide so any autostart entry or script can call 'eww' directly. sudo cp target/release/eww /usr/bin/ cd ~ # Return home so subsequent relative-path steps work correctly # --------------------------------------------------------------------------- # 6. Theme and icon setup # --------------------------------------------------------------------------- log "Installing themes and icons..." # Install the cyberqueer GTK theme system-wide so GTK2/3/4 apps pick it up. sudo cp -r ~/Dotfiles/gtk-themes/cyberqueer /usr/share/themes # Install the matching btop colour theme for the terminal system monitor. sudo cp ~/Dotfiles/desktopenvs/hyprland/btop/themes/cyberqueer.theme /usr/share/btop/themes # Deploy the ly display-manager config (login screen appearance, session list). sudo cp -f ~/Dotfiles/etc-ly-config.ini /etc/ly/config.ini # Register kitty as the system-default terminal for xdg-terminal-exec so # file managers and scripts that call "Open Terminal Here" launch kitty. sudo ln -sf /usr/bin/kitty /usr/bin/xdg-terminal-exec # Register ksshaskpass as the SSH passphrase helper. # When SSH needs a passphrase in a non-terminal context (e.g. git push from a # script), it invokes /usr/lib/ssh/ssh-askpass; this link provides a GUI dialog. sudo ln -sf /usr/bin/ksshaskpass /usr/lib/ssh/ssh-askpass # --------------------------------------------------------------------------- # 7. Cursor setup # --------------------------------------------------------------------------- # Nordzy-cursors-lefthand is a Nord-palette left-handed cursor theme. # Downloaded from GitHub Releases rather than the AUR because the AUR build # may lag behind the upstream release schedule. log "Installing cursor theme..." mkdir -p ~/.icons wget -O ~/install-tmp/Nordzy-cursors-lefthand.tar.gz \ https://github.com/guillaumeboehm/Nordzy-cursors/releases/download/v2.3.0/Nordzy-cursors-lefthand.tar.gz # Extract directly into ~/.icons/ so the theme is immediately discoverable by # Hyprland (via hyprcursor) and by GTK applications. tar -zxf ~/install-tmp/Nordzy-cursors-lefthand.tar.gz -C ~/.icons/ # --------------------------------------------------------------------------- # 8. Enable Bluetooth and wireless services # --------------------------------------------------------------------------- log "Enabling Bluetooth and wireless services..." # bluez: core Bluetooth protocol stack (powers and manages adapters on boot) enable_service bluez # bluetooth.service: high-level service handling pairing and profiles enable_service bluetooth.service # iwd: modern Wi-Fi daemon from Intel; used by iwmenu for the bar Wi-Fi picker enable_service iwd.service # --------------------------------------------------------------------------- # 9. Hyprland plugins (must be run from inside a live Hyprland session) # --------------------------------------------------------------------------- # hyprpm links against the exact compositor binary, so it cannot run from the # installer. Execute these commands manually after first login: # hyprpm update # hyprpm add https://github.com/hyprwm/hyprland-plugins # --------------------------------------------------------------------------- # 10. Copy configs # --------------------------------------------------------------------------- log "Copying configs..." # Each entry in CONFIGS maps to a sub-directory (or file) inside # desktopenvs/hyprland/ that is deployed verbatim to ~/.config/. # Old copies are wiped first to prevent stale files from prior installs # interfering with the fresh deployment. CONFIGS=(kitty mimeapps.list vicinae walker ulauncher hypr xfce4 wofi dunst alacritty nwg-dock-hyprland nwg-drawer nwg-panel scripts btop gtk-3.0) for cfg in "${CONFIGS[@]}"; do rm -rf ~/.config/"$cfg" cp -r ~/Dotfiles/desktopenvs/hyprland/"$cfg" ~/.config/ done # hypr-usr/ holds device-specific overrides (monitor layout, keybinds, envvars). # In the legacy hyprlang setup these are .conf files at the ~/.config/ root # level; hyprland.conf sources them with 'source = ~/.config/monitors.conf' etc. cp ~/Dotfiles/desktopenvs/hyprland/hypr-usr/* ~/.config/ # colors.conf defines the shared colour palette used by EWW, dunst, and scripts. cp ~/Dotfiles/colors.conf ~/.config/colors.conf # --------------------------------------------------------------------------- # 11. Wallpaper and resources # --------------------------------------------------------------------------- log "Copying wallpaper and resources..." mkdir -p ~/Pictures # Firefox logo SVG used as the dock/launcher shortcut icon. cp ~/Dotfiles/resources/fflogo.svg ~/Pictures/fflogo.svg # Download the personalised wallpaper from the owner's Nextcloud instance. # ?v=15 is a cache-buster version parameter on the Nextcloud theming API. wget "https://cloud.abdelbaki.eu/apps/theming/image/background?v=15" -O ~/Pictures/background.jpg # --------------------------------------------------------------------------- # 12. Python venv for scripts # --------------------------------------------------------------------------- # Many EWW and Hyprland helper scripts are written in Python and need these # third-party libraries. An isolated venv avoids polluting the system Python # and prevents conflicts with pacman-managed Python packages. log "Setting up Python venv for scripts..." python -m venv ~/.config/python-script ~/.config/python-script/bin/pip install \ speedtest-cli `# Internet speed test widget for the EWW bar` \ requests `# HTTP client used by various widgets and scripts` \ pint `# Unit conversion library for the calculator script` \ simpleeval `# Safe maths expression evaluator (wofi-calc backend)` \ parsedatetime `# Natural-language date/time parser for timer scripts` # --------------------------------------------------------------------------- # 13. Udiskie icon fix # --------------------------------------------------------------------------- # udiskie uses freedesktop icon names (udiskie-checkbox-checked, etc.) that # most icon themes do not ship. We symlink them from Papirus-Dark's existing # checkbox icons as a close visual match. Placing symlinks in the hicolor # theme ensures every GTK app can find them as hicolor is the last-resort # fallback in the icon theme lookup chain. log "Applying Udiskie icon fix..." PAPIRUS_DIR="/usr/share/icons/Papirus-Dark/status" HICOLOR_DIR="/usr/share/icons/hicolor/scalable/status" if [ -d "$PAPIRUS_DIR" ]; then sudo ln -sf "$PAPIRUS_DIR/checkbox-checked.svg" "$HICOLOR_DIR/udiskie-checkbox-checked.svg" sudo ln -sf "$PAPIRUS_DIR/checkbox-unchecked.svg" "$HICOLOR_DIR/udiskie-checkbox-unchecked.svg" # Rebuild the icon cache so GTK discovers the new symlinked entries without # requiring a full logout/login. sudo gtk-update-icon-cache -f -t /usr/share/icons/hicolor else warn "Papirus-Dark not found — skipping udiskie icon fix." fi # --------------------------------------------------------------------------- # 14. Enable udiskie # --------------------------------------------------------------------------- # udiskie is the auto-mounter / tray-icon daemon that surfaces mounted volumes. # Enable the systemd user unit and start it immediately so this session already # benefits from auto-mounting without requiring a reboot. log "Enabling udiskie service..." enable_service udiskie.service start_service udiskie.service # --------------------------------------------------------------------------- # 15. Install config updater and theme script # --------------------------------------------------------------------------- # config-updater is a lightweight mechanism that re-syncs selected config files # from the Dotfiles repo without running the full installer again. # updater.conf lists which files to keep in sync; update-configs.sh performs # the actual copy operation. # # Symlinks (ln -sf) are used so that 'git pull' in ~/Dotfiles immediately takes # effect the next time update-configs.sh is run. log "Installing config updater and theme script..." mkdir -p ~/.config/config-updater ln -sf ~/Dotfiles/desktopenvs/hyprland/config-updater/updater.conf ~/.config/config-updater/updater.conf ln -sf ~/Dotfiles/desktopenvs/hyprland/config-updater/update-configs.sh ~/update-configs.sh # apply-theme.sh applies the cyberqueer colour palette across all running apps # (sets GTK/Qt themes, reloads dunst config, refreshes EWW colour variables). # Copied (not symlinked) to ~ so it works even if ~/Dotfiles is unmounted. cp ~/Dotfiles/apply-theme.sh ~/apply-theme.sh chmod +x ~/apply-theme.sh # --------------------------------------------------------------------------- # 16. WallRizz (run manually after login — requires a running desktop session) # --------------------------------------------------------------------------- # WallRizz generates a colour scheme from the active wallpaper and applies it # to EWW, dunst, and terminals. It requires a live Wayland session and cannot # be safely run from this installer script. # Uncomment and run manually after your first login: # curl -sL "$(curl -s https://api.github.com/repos/5hubham5ingh/WallRizz/releases/latest \ # | grep -Po '"browser_download_url": "\K[^"]+' | grep WallRizz)" | tar -xz \ # && sudo mv WallRizz /usr/bin/ log "Hyprland installation complete. Reboot to start."