#!/bin/bash # ============================================================================= # hyprlua.sh — HyprLua Desktop Environment installer (Lua-based config) # ============================================================================= # Part of the Dotfiles setup system for Arch Linux. # # HyprLua is the primary / recommended Hyprland variant in this Dotfiles repo. # It uses a Lua configuration file (hyprland.lua) instead of hyprlang (.conf), # enabling programmatic config generation, per-device overrides via Lua modules, # and more maintainable keybind/rule definitions. # # Differences from hyprland.sh (the legacy .conf variant): # - Config source paths point to desktopenvs/hyprlua/ # - Device-specific overrides live in ~/.config/hypr/usr/ (Lua modules # loaded via require("usr.*")), not at ~/.config/ root # - Adds python-opencv + v4l-utils for the webcam presence-detection daemon # - Tablet mode also installs evdev-right-click-emulation from AUR # - gsettings sets prefer-dark globally (relevant for GTK apps under Hyprland) # - qt6ct is NOT installed (hyprlua dropped it from the package list) # - Adds --needed flag to yay to skip already-installed AUR packages # # High-level install flow: # 1. System update + Flatpak # 2. pacman packages (compositor, audio, networking, tools, fonts, webcam) # 3. systemd service enablement # 4. AUR packages via yay # 5. EWW bar (form-factor selection + Rust compilation) # 6. Themes, ly config, terminal symlink, SSH askpass, dark-mode preference # 7. Nordzy left-hand cursor theme # 8. Bluetooth / iwd services # 9. Config file deployment (hyprlua source tree) # 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 on any error — partial DE installs leave a broken system. set -e # Load shared logging helpers (log, warn, err) from the setup library. source "$(dirname "${BASH_SOURCE[0]}")/../lib/logging.sh" log "Starting HyprLua installer (Lua-based config)..." # --------------------------------------------------------------------------- # 1. Update system and install Flatpak # --------------------------------------------------------------------------- # Full system upgrade before package installs to avoid Arch partial-upgrade # issues (library ABI mismatches between un-upgraded and newly installed pkgs). 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`). HYPRLUA_PACKAGES=( hyprland # Wayland compositor / window manager hyprcursor # hardware-accelerated cursor rendering for Hyprland wl-clipboard # wl-copy / wl-paste; Wayland clipboard CLI tools hyprpaper # wallpaper utility with per-monitor support hyprlock # GPU-accelerated screen locker (Hyprland-native) wofi # Wayland application launcher (rofi alternative) kitty # GPU-accelerated terminal (default in this setup) dunst # lightweight, scriptable notification daemon nwg-dock-hyprland # dock/taskbar with Hyprland workspace awareness nwg-drawer # grid application drawer / launcher nwg-menu # GTK application menu for the panel button nwg-look # GTK/cursor/icon theme picker for wlroots sessions # Build toolchain required for EWW (Rust) and AUR package compilation python cmake meson cpio pkgconf ruby-pkg-config hyprsunset # blue-light filter / night-mode daemon hypridle # idle daemon triggering lock/suspend after inactivity ksshaskpass # Qt SSH passphrase dialog registered as ssh-askpass nm-connection-editor # GTK editor for NetworkManager connection profiles network-manager-applet # tray applet showing network connection status blueman # GTK Bluetooth manager with tray icon support bluez # core Linux Bluetooth protocol stack pipewire # modern audio/video routing daemon (replaces PulseAudio) alsa-utils # low-level ALSA CLI tools (amixer, aplay, arecord) firefox # web browser greetd-tuigreet # TUI login greeter (text-based, no GPU requirement) grim # Wayland screenshot capture tool slurp # interactive rectangular region selector for screenshots gst-plugin-pipewire # GStreamer plugin routing through PipeWire imagemagick # image processing toolkit for screenshot effects nerd-fonts # all Nerd Font families (icon glyphs in EWW bar) otf-font-awesome # Font Awesome glyph set for bar and notifications # Compatibility shims letting ALSA, JACK, and PulseAudio apps route through # PipeWire transparently without needing to be recompiled pipewire-alsa pipewire-jack pipewire-pulse qt5-wayland # Qt5 Wayland platform plugin for native rendering qt6-wayland # Qt6 Wayland platform plugin for native rendering swww # smooth animated wallpaper daemon for wlroots ttf-jetbrains-mono # monospace coding font used in terminals/bar wireplumber # PipeWire session and policy manager xdg-desktop-portal-hyprland # Hyprland XDG portal (screen share, file pick) xdg-utils # xdg-open and MIME handling utilities # Note: qt6ct is NOT included in hyprlua (differs from hyprland.sh) 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 # full-featured GTK calculator with unit conversion iwd # Intel Wireless Daemon (lighter Wi-Fi stack than wpa_supplicant) dbus # D-Bus inter-process communication daemon thunar # lightweight GTK file manager tumbler # D-Bus thumbnail service for Thunar thunar-archive-plugin # archive (zip/tar) right-click integration thunar-shares-plugin # Samba share management in Thunar thunar-volman # automatic volume/device mounting in Thunar hyprpicker # colour picker outputting hex/rgb/hsl values pcmanfm-qt # Qt file manager (kept as fallback / alternative) udisks2 # D-Bus daemon for querying and managing storage devices ly # minimal TUI display manager (takes over tty1 from getty) kew # terminal-based music player hyprpolkitagent # Hyprland-native Polkit authentication agent pavucontrol # PulseAudio/PipeWire GUI volume mixer playerctl # MPRIS media player CLI controller wf-recorder # screen recorder for wlroots-based compositors sound-theme-freedesktop # standard freedesktop sound event samples python-opencv # OpenCV Python bindings; webcam presence-detection daemon v4l-utils # Video4Linux2 tools for enumerating and configuring webcams ) sudo pacman -Syu --noconfirm --needed -- "${HYPRLUA_PACKAGES[@]}" # --------------------------------------------------------------------------- # 3. Enable essential services # --------------------------------------------------------------------------- log "Enabling essential services..." # NetworkManager: manages all network connections (wired, Wi-Fi, VPN). sudo systemctl enable NetworkManager.service # Disable the default getty login prompt on tty1 so ly can own that TTY. # '|| true' prevents abort if the unit is already disabled. sudo systemctl disable getty@tty1.service || true # ly: TUI display manager that presents the login screen on tty1. sudo systemctl enable ly@tty1.service # udisks2: D-Bus block-device service required by udiskie for auto-mounting. sudo systemctl enable udisks2.service # --------------------------------------------------------------------------- # 4. Install AUR packages # --------------------------------------------------------------------------- log "Installing AUR packages..." # Pin the stable Rust toolchain so EWW and AUR Rust packages compile cleanly. rustup default stable # yay flags: # --answerdiff None — skip PKGBUILD diff display (non-interactive) # --answerclean All — always clean build directories # --noconfirm — suppress all confirmation prompts # --needed — skip packages that are already up-to-date (added vs # hyprland.sh to avoid redundant AUR rebuilds) # # Packages: # hyprland-workspaces — EWW workspace widget (reads Hyprland IPC) # vicinae-bin — pre-built vicinae (vim-modal keybind layer) # bluetuith — TUI Bluetooth manager (text-based device control) # wvkbd — on-screen virtual keyboard for Wayland (tablet use) # iwmenu — wofi/dmenu Wi-Fi picker driven by iwd # pinta — accessible image editor (Paint.NET-like) # walker-bin — fast application launcher (pre-built binary) # ulauncher — extensible launcher with plugin support # bzmenu — quick Bluetooth connect menu for the bar # udiskie — auto-mounter with tray icon (built on udisks2) # wofi-calc — inline calculator inside wofi # bri — brightness control helper for bar widgets # chamel — colour-palette / theme switcher yay -Syu --answerdiff None --answerclean All --noconfirm --needed \ hyprland-workspaces vicinae-bin bluetuith wvkbd iwmenu pinta \ walker-bin ulauncher bzmenu udiskie \ wofi-calc bri chamel # hyprmoncfg if custom script no worky # --------------------------------------------------------------------------- # 5. EWW bar selection and compilation # --------------------------------------------------------------------------- # EWW (Elkowar's Wacky Widgets) powers the custom status bar. # Three form-factor layouts ship in the Dotfiles: # eww/ — Notebook: includes battery percentage widget # eww-nobattery/ — Desktop PC: no battery widget # eww-touch/ — Tablet: larger touch targets + right-click emulation log "Setting up EWW bar..." # Remove any existing EWW config to avoid leftover widget definitions. rm -rf ~/.config/eww # Single-keystroke form-factor selection (no Enter required). read -n1 -p "Install eww bar for PC, Notebook or Tablet [P/N/T]: " doit echo # Newline after single-char read case $doit in # Notebook: battery-aware layout n|N) cp -rf ~/Dotfiles/desktopenvs/hyprlua/eww/ ~/.config/ ;; # Desktop PC: no battery widget p|P) cp -rf ~/Dotfiles/desktopenvs/hyprlua/eww-nobattery/ ~/.config/eww ;; # Tablet: touch layout + right-click emulation daemon t|T) cp -rf ~/Dotfiles/desktopenvs/hyprlua/eww-touch/ ~/.config/eww # evdev-right-click-emulation enables long-press → right-click on touch # screens; its systemd service must be started alongside the session. yay -S evdev-right-click-emulation sudo systemctl enable --now evdev-rce.service ;; # Unrecognised key: leave ~/.config/eww absent; user must copy manually. *) warn "No valid choice — skipping EWW copy. Run manually later." ;; esac log "Compiling EWW..." # EWW is not packaged in the official repos; we compile from source. # ~/install-tmp is the staging directory for source trees fetched during install. mkdir -p ~/install-tmp cd ~/install-tmp git clone https://github.com/elkowar/eww cd eww # --release → produce an optimised binary (noticeably faster UI) # --no-default-features → exclude the X11 backend (we only target Wayland) # --features=wayland → enable the Wayland back-end explicitly cargo build --release --no-default-features --features=wayland chmod +x target/release/eww # Install system-wide so autostart entries and scripts can invoke 'eww' directly. sudo cp target/release/eww /usr/bin/ cd ~ # Return home so subsequent relative paths resolve correctly # --------------------------------------------------------------------------- # 6. Theme and icon setup # --------------------------------------------------------------------------- log "Installing themes and icons..." # Install the cyberqueer GTK theme system-wide for GTK2/3/4 application styling. sudo cp -r ~/Dotfiles/gtk-themes/cyberqueer /usr/share/themes # Install the matching btop resource-monitor colour theme. sudo cp ~/Dotfiles/desktopenvs/hyprlua/btop/themes/cyberqueer.theme /usr/share/btop/themes # Deploy the ly display-manager configuration (login screen appearance). sudo cp -f ~/Dotfiles/etc-ly-config.ini /etc/ly/config.ini # Register kitty as the system terminal for xdg-terminal-exec so file managers # and scripts that open "a terminal here" consistently launch kitty. sudo ln -sf /usr/bin/kitty /usr/bin/xdg-terminal-exec # Register ksshaskpass as the SSH passphrase GUI helper. # SSH clients look for /usr/lib/ssh/ssh-askpass when they need a passphrase # but have no controlling terminal available (e.g. git push from a bar widget). sudo ln -sf /usr/bin/ksshaskpass /usr/lib/ssh/ssh-askpass # Qt theming via qt-themes/cyberqueer is commented out (kept for reference); # the Qt5 / Qt6 colour scheme is currently handled via qt6ct manual setup. #bash ~/Dotfiles/qt-themes/cyberqueer/enable.sh # Instruct GTK apps that prefer the system colour-scheme to use dark mode. # This is particularly important under Hyprland where there is no GNOME # settings daemon propagating the user's preference automatically. gsettings set org.gnome.desktop.interface color-scheme 'prefer-dark' # --------------------------------------------------------------------------- # 7. Cursor setup # --------------------------------------------------------------------------- # Nordzy-cursors-lefthand is a Nord-palette left-handed cursor theme. # Downloaded directly from GitHub Releases for a pinned version; the AUR # build can lag behind upstream. 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 into ~/.icons/ so both Hyprland (hyprcursor) and GTK apps can find it. 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 daemon; powers adapters and makes them available on boot sudo systemctl enable bluez # bluetooth.service: handles pairing, profiles, and device reconnection sudo systemctl enable bluetooth.service # iwd: Intel Wireless Daemon; the Wi-Fi back-end used by iwmenu in the bar sudo systemctl enable iwd.service #systemctl --user enable --now hyprmoncfgd # --------------------------------------------------------------------------- # 9. Hyprland plugins (must be run inside a live Hyprland session) # --------------------------------------------------------------------------- # hyprpm links against the exact running compositor binary, so it cannot be # invoked from the installer. After first login, run: # hyprpm update # hyprpm add https://github.com/hyprwm/hyprland-plugins # --------------------------------------------------------------------------- # 10. Copy configs # --------------------------------------------------------------------------- log "Copying configs..." # Deploy each config directory from the hyprlua Dotfiles source. # The wipe-then-copy pattern ensures no stale files from older installs remain. 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/hyprlua/"$cfg" ~/.config/ done # In hyprlua, device-specific overrides (monitors, keybinds, autostart, etc.) # live inside ~/.config/hypr/usr/ as Lua modules loaded by hyprland.lua via # require("usr.*"). The usr/ directory is already bundled inside the hypr/ # directory copied above, so no separate step is needed here. # After install, customise ~/.config/hypr/usr/ per device as needed. # Shared colour palette used by EWW bar, 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 for 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 on the Nextcloud theming background API endpoint. wget "https://cloud.abdelbaki.eu/apps/theming/image/background?v=15" -O ~/Pictures/background.jpg # --------------------------------------------------------------------------- # 12. Python venv for scripts # --------------------------------------------------------------------------- # Helper scripts (weather widget, speed test, unit converter, timer, etc.) need # these third-party Python libraries. An isolated venv keeps them separate from # system Python packages managed by pacman to avoid conflicts. log "Setting up Python venv for scripts..." python -m venv ~/.config/python-script ~/.config/python-script/bin/pip install \ speedtest-cli `# Internet speed test (EWW bar widget)` \ requests `# HTTP client for API-driven widgets` \ pint `# Unit conversion library` \ simpleeval `# Safe maths expression evaluator (wofi-calc)` \ parsedatetime `# Natural-language date/time parser for timer scripts` # --------------------------------------------------------------------------- # 13. Udiskie icon fix # --------------------------------------------------------------------------- # udiskie expects freedesktop icon names (udiskie-checkbox-checked, etc.) that # Papirus-Dark does not ship under those exact names. We symlink Papirus-Dark's # existing checkbox SVGs into the hicolor fallback theme under the names udiskie # expects, then rebuild the cache so GTK picks them up immediately. 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 GTK icon cache so apps find the new symlinks without restart. 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 auto-mounts removable drives and shows a tray icon for each volume. # Enable the systemd unit for future boots and start it immediately so USB # devices inserted during this session are handled right away. log "Enabling udiskie service..." sudo systemctl enable udiskie.service sudo systemctl start udiskie.service # --------------------------------------------------------------------------- # 15. Install config updater and theme script # --------------------------------------------------------------------------- # config-updater selectively re-syncs config files from the Dotfiles repo # without re-running the full installer. updater.conf lists which files are # managed; update-configs.sh performs the sync. # # Symlinks are used (not copies) so that pulling the latest Dotfiles with # 'git pull' takes effect immediately on the next sync run. log "Installing config updater and theme script..." mkdir -p ~/.config/config-updater ln -sf ~/Dotfiles/desktopenvs/hyprlua/config-updater/updater.conf ~/.config/config-updater/updater.conf ln -sf ~/Dotfiles/desktopenvs/hyprlua/config-updater/update-configs.sh ~/update-configs.sh # apply-theme.sh applies the cyberqueer palette across all running apps # (reloads dunst, refreshes EWW variables, sets GTK/Qt themes). # Copied rather than symlinked so it is available even when ~/Dotfiles is absent. cp ~/Dotfiles/apply-theme.sh ~/apply-theme.sh chmod +x ~/apply-theme.sh log "HyprLua installation complete. Reboot to start."