Dotfiles/setup/modules/Desktop-Environments/hyprlua.sh

410 lines
22 KiB
Bash
Executable File

#!/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..."
sudo pacman -Syu --noconfirm --needed \
hyprland hyprcursor wl-clipboard hyprpaper hyprlock wofi kitty dunst \
# 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 nwg-drawer nwg-menu nwg-look \
# 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
python cmake meson cpio pkgconf ruby-pkg-config \
# Build toolchain required for EWW (Rust) and AUR package compilation
hyprsunset hypridle ksshaskpass \
# 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 network-manager-applet blueman bluez \
# 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 alsa-utils firefox greetd-tuigreet \
# 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 slurp gst-plugin-pipewire imagemagick \
# 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 otf-font-awesome \
# nerd-fonts — all Nerd Font families (icon glyphs in EWW bar)
# otf-font-awesome — Font Awesome glyph set for bar and notifications
pipewire-alsa pipewire-jack pipewire-pulse \
# Compatibility shims letting ALSA, JACK, and PulseAudio apps route through
# PipeWire transparently without needing to be recompiled
qt5-wayland qt6-wayland swww ttf-jetbrains-mono wireplumber \
# qt5-wayland / qt6-wayland — Qt Wayland platform plugins 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 xdg-utils \
# 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 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 — 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 tumbler thunar-archive-plugin thunar-shares-plugin thunar-volman \
# 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 pcmanfm-qt udisks2 ly kew \
# 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 pavucontrol playerctl wf-recorder sound-theme-freedesktop \
# 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 v4l-utils
# python-opencv — OpenCV Python bindings; used by the webcam presence-
# detection daemon to watch for the user at the desk and
# inhibit idle/screen-lock while they are present
# v4l-utils — Video4Linux2 tools for enumerating and configuring webcams
# ---------------------------------------------------------------------------
# 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."