#!/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..." sudo pacman -Syu --noconfirm --needed \ hyprland hyprcursor wl-clipboard hyprpaper hyprlock wofi kitty dunst \ # 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 nwg-drawer nwg-menu nwg-look \ # 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 python cmake meson cpio pkgconf ruby-pkg-config \ # Build tools needed to compile EWW (Rust) and AUR packages (C/C++/Ruby) hyprsunset hypridle ksshaskpass \ # 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 network-manager-applet blueman bluez \ # 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 alsa-utils firefox greetd-tuigreet \ # 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 slurp gst-plugin-pipewire imagemagick \ # 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 otf-font-awesome \ # nerd-fonts — all Nerd Font patched families (icon glyphs in bar) # otf-font-awesome — Font Awesome icon glyphs for EWW/dunst pipewire-alsa pipewire-jack pipewire-pulse \ # Compatibility layers: let ALSA, JACK, and PulseAudio apps route through # PipeWire without requiring code changes in those apps qt5-wayland qt6-wayland swww ttf-jetbrains-mono wireplumber \ # qt5-wayland / qt6-wayland — Qt platform plugins 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 xdg-desktop-portal-hyprland xdg-utils \ # 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 xorg-xinit papirus-icon-theme \ # xorg-server / xorg-xinit — X server for XWayland (legacy X11 apps) # papirus-icon-theme — icon theme used system-wide and by udiskie cool-retro-term qalculate-gtk iwd dbus \ # 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 tumbler thunar-archive-plugin thunar-shares-plugin thunar-volman \ # 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 pcmanfm-qt udisks2 ly kew \ # 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 pavucontrol playerctl wf-recorder sound-theme-freedesktop # 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 # --------------------------------------------------------------------------- # 3. Enable essential services # --------------------------------------------------------------------------- log "Enabling essential services..." # NetworkManager must be active on boot for network connectivity. sudo systemctl enable 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. sudo systemctl enable ly@tty1.service # udisks2 provides the D-Bus API for block devices; required by udiskie for # automatic USB/external drive mounting. sudo systemctl enable 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) sudo systemctl enable bluez # bluetooth.service: high-level service handling pairing and profiles sudo systemctl enable bluetooth.service # iwd: modern Wi-Fi daemon from Intel; used by iwmenu for the bar Wi-Fi picker sudo systemctl enable 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..." sudo systemctl enable udiskie.service sudo systemctl start 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."