diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..cb0c855 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,85 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Repository Overview + +This is an Arch Linux Hyprland desktop setup automation repository based on [omarchy.org](https://omarchy.org). It provides a comprehensive collection of shell scripts to set up a fresh Arch Linux installation with the Hyprland window manager and various desktop applications. + +## Project Structure + +### Main Scripts +- `base_install.sh` - The main entry point script (currently empty, but serves as the base installer) +- `scripts/` - Contains all installation and configuration scripts organized by category: + - `config/` - System configuration scripts (keyboard, network, timezones, etc.) + - `desktop/` - Desktop environment installation scripts (Hyprland, themes, applications) + - `aur.sh`, `development.sh`, `firewall.sh`, etc. - Specialized installation scripts + +### Theme System +- `themes/` - Contains multiple theme configurations, each including: + - Color schemes for various applications (alacritty, waybar, mako, etc.) + - Hyprland configuration files (`hyprland.conf`, `hyprlock.conf`) + - Background images and icon themes + - Application-specific styling (CSS, config files) + +Available themes: catppuccin, catppuccin-latte, everforest, gruvbox, kanagawa, matte-black, nord, osaka-jade, ristretto, rose-pine, tokyo-night + +## Development Commands + +This repository consists entirely of shell scripts for system configuration. There are no build, test, or lint commands as this is a collection of installation scripts. + +### Running Scripts +```bash +# Make scripts executable +chmod +x script_name.sh + +# Run installation scripts +./base_install.sh +./scripts/desktop/hyprlandia.sh +./scripts/desktop/theme.sh +``` + +## Architecture and Key Components + +### Package Management +All scripts use `yay` (AUR helper) for package installation with standard flags: +- `--noconfirm` - Non-interactive installation +- `--needed` - Only install if not already present + +### Theme Management System +The theme system uses symlinks to manage active themes: +- Themes are linked from `~/.local/share/omarchy/themes/` to `~/.config/omarchy/themes/` +- Active theme is symlinked to `~/.config/omarchy/current/theme` +- Individual application configs are symlinked from the current theme + +### Configuration Approach +- Configurations are copied from `~/.local/share/omarchy/config/` to `~/.config/` +- GPG configurations are set up system-wide in `/etc/gnupg/` +- Git aliases and user information are configured globally +- PAM faillock settings are modified for security + +### Key Installation Categories +1. **System Config** - Keyboard layout detection, network setup, timezone configuration +2. **Desktop Environment** - Hyprland compositor and related tools +3. **Applications** - File managers, media players, web browsers +4. **Development Tools** - Available via `development.sh` +5. **Theming** - Comprehensive theme support across all applications + +### GPU-Aware Installation +Scripts detect GPU type and install appropriate software: +- NVIDIA GPUs: `wf-recorder` for screen recording +- Other GPUs: `wl-screenrec` for screen recording + +## Working with Themes + +Each theme directory contains configuration files for: +- Terminal emulator (alacritty) +- Status bar (waybar) +- Notifications (mako) +- Application launcher (walker) +- Screen locker (hyprlock) +- System monitor (btop) +- Text editor (neovim) +- Volume/brightness OSD (swayosd) + +Theme switching is handled through the symlink system managed by `scripts/desktop/theme.sh`. \ No newline at end of file diff --git a/base_install.sh b/base_install.sh index e69de29..08ac6de 100644 --- a/base_install.sh +++ b/base_install.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +# Arch Hyprland Setup - Base Installer +# Runs all installation scripts in the correct order + +set -e # Exit on any error + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SCRIPTS_DIR="$SCRIPT_DIR/scripts" + +echo "Starting Arch Hyprland Setup..." + +# Function to run a script and check for errors +run_script() { + local script="$1" + local name="$2" + + if [[ -f "$script" ]]; then + echo "Running $name..." + chmod +x "$script" + bash "$script" + echo " $name completed" + else + echo "� Warning: $name not found at $script" + fi +} + +# Step 1: Install AUR helper (yay) +run_script "$SCRIPTS_DIR/aur.sh" "AUR helper installation" + +# Step 2: System configuration +echo "Configuring system settings..." +run_script "$SCRIPTS_DIR/config/detect-keyboard-layout.sh" "Keyboard layout detection" +run_script "$SCRIPTS_DIR/config/network.sh" "Network configuration" +run_script "$SCRIPTS_DIR/config/nvidia.sh" "NVIDIA configuration" +run_script "$SCRIPTS_DIR/config/power.sh" "Power management" +run_script "$SCRIPTS_DIR/config/fix-fkeys.sh" "Function keys configuration" +run_script "$SCRIPTS_DIR/config/config.sh" "General system configuration" + +# Step 3: Desktop environment +echo "Installing desktop environment..." +run_script "$SCRIPTS_DIR/desktop/fonts.sh" "Font installation" +run_script "$SCRIPTS_DIR/desktop/hyprlandia.sh" "Hyprland installation" +run_script "$SCRIPTS_DIR/desktop/uwsm.sh" "Universal Wayland Session Manager" +run_script "$SCRIPTS_DIR/desktop/desktop.sh" "Desktop applications" +run_script "$SCRIPTS_DIR/desktop/bluetooth.sh" "Bluetooth setup" +run_script "$SCRIPTS_DIR/desktop/theme.sh" "Theme configuration" + +# Step 4: Additional software and configurations +echo "Installing additional software..." +run_script "$SCRIPTS_DIR/development.sh" "Development tools" +run_script "$SCRIPTS_DIR/firewall.sh" "Firewall configuration" +run_script "$SCRIPTS_DIR/mimetypes.sh" "MIME types configuration" +run_script "$SCRIPTS_DIR/xtras.sh" "Extra applications" + +echo "<� Arch Hyprland Setup completed successfully!" +echo "Please reboot your system to ensure all changes take effect." \ No newline at end of file diff --git a/scripts/config/identification.sh b/scripts/config/identification.sh deleted file mode 100644 index 94e9d7b..0000000 --- a/scripts/config/identification.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -export OMARCHY_USER_NAME=$(gum input --placeholder "Enter full name" --prompt "Name> ") -export OMARCHY_USER_EMAIL=$(gum input --placeholder "Enter email address" --prompt "Email> ") diff --git a/scripts/config/login.sh b/scripts/config/login.sh deleted file mode 100644 index 774fa5e..0000000 --- a/scripts/config/login.sh +++ /dev/null @@ -1,267 +0,0 @@ -#!/bin/bash - -# Hyprland launched via UWSM and login directly as user, rely on disk encryption + hyprlock for security -if ! command -v uwsm &>/dev/null || ! command -v plymouth &>/dev/null; then - yay -S --noconfirm --needed uwsm plymouth -fi - -# ============================================================================== -# PLYMOUTH SETUP -# ============================================================================== - -if ! grep -Eq '^HOOKS=.*plymouth' /etc/mkinitcpio.conf; then - # Backup original mkinitcpio.conf just in case - backup_timestamp=$(date +"%Y%m%d%H%M%S") - sudo cp /etc/mkinitcpio.conf "/etc/mkinitcpio.conf.bak.${backup_timestamp}" - - # Add plymouth to HOOKS array after 'base udev' or 'base systemd' - if grep "^HOOKS=" /etc/mkinitcpio.conf | grep -q "base systemd"; then - sudo sed -i '/^HOOKS=/s/base systemd/base systemd plymouth/' /etc/mkinitcpio.conf - elif grep "^HOOKS=" /etc/mkinitcpio.conf | grep -q "base udev"; then - sudo sed -i '/^HOOKS=/s/base udev/base udev plymouth/' /etc/mkinitcpio.conf - else - echo "Couldn't add the Plymouth hook" - fi - - # Regenerate initramfs - sudo mkinitcpio -P -fi - -# Add kernel parameters for Plymouth -if [ -d "/boot/loader/entries" ]; then # systemd-boot - echo "Detected systemd-boot" - - for entry in /boot/loader/entries/*.conf; do - if [ -f "$entry" ]; then - # Skip fallback entries - if [[ "$(basename "$entry")" == *"fallback"* ]]; then - echo "Skipped: $(basename "$entry") (fallback entry)" - continue - fi - - # Skip if splash it already present for some reason - if ! grep -q "splash" "$entry"; then - sudo sed -i '/^options/ s/$/ splash quiet/' "$entry" - else - echo "Skipped: $(basename "$entry") (splash already present)" - fi - fi - done -elif [ -f "/etc/default/grub" ]; then # Grub - echo "Detected grub" - - # Backup GRUB config before modifying - backup_timestamp=$(date +"%Y%m%d%H%M%S") - sudo cp /etc/default/grub "/etc/default/grub.bak.${backup_timestamp}" - - # Check if splash is already in GRUB_CMDLINE_LINUX_DEFAULT - if ! grep -q "GRUB_CMDLINE_LINUX_DEFAULT.*splash" /etc/default/grub; then - # Get current GRUB_CMDLINE_LINUX_DEFAULT value - current_cmdline=$(grep "^GRUB_CMDLINE_LINUX_DEFAULT=" /etc/default/grub | cut -d'"' -f2) - - # Add splash and quiet if not present - new_cmdline="$current_cmdline" - if [[ ! "$current_cmdline" =~ splash ]]; then - new_cmdline="$new_cmdline splash" - fi - if [[ ! "$current_cmdline" =~ quiet ]]; then - new_cmdline="$new_cmdline quiet" - fi - - # Trim any leading/trailing spaces - new_cmdline=$(echo "$new_cmdline" | xargs) - - sudo sed -i "s/^GRUB_CMDLINE_LINUX_DEFAULT=\".*\"/GRUB_CMDLINE_LINUX_DEFAULT=\"$new_cmdline\"/" /etc/default/grub - - # Regenerate grub config - sudo grub-mkconfig -o /boot/grub/grub.cfg - else - echo "GRUB already configured with splash kernel parameters" - fi -elif [ -d "/etc/cmdline.d" ]; then # UKI - echo "Detected a UKI setup" - # Relying on mkinitcpio to assemble a UKI - # https://wiki.archlinux.org/title/Unified_kernel_image - if ! grep -q splash /etc/cmdline.d/*.conf; then - # Need splash, create the omarchy file - echo "splash" | sudo tee -a /etc/cmdline.d/omarchy.conf - fi - if ! grep -q quiet /etc/cmdline.d/*.conf; then - # Need quiet, create or append the omarchy file - echo "quiet" | sudo tee -a /etc/cmdline.d/omarchy.conf - fi -elif [ -f "/etc/kernel/cmdline" ]; then # UKI Alternate - # Alternate UKI kernel cmdline location - echo "Detected a UKI setup" - - # Backup kernel cmdline config before modifying - backup_timestamp=$(date +"%Y%m%d%H%M%S") - sudo cp /etc/kernel/cmdline "/etc/kernel/cmdline.bak.${backup_timestamp}" - - current_cmdline=$(cat /etc/kernel/cmdline) - - # Add splash and quiet if not present - new_cmdline="$current_cmdline" - if [[ ! "$current_cmdline" =~ splash ]]; then - new_cmdline="$new_cmdline splash" - fi - if [[ ! "$current_cmdline" =~ quiet ]]; then - new_cmdline="$new_cmdline quiet" - fi - - # Trim any leading/trailing spaces - new_cmdline=$(echo "$new_cmdline" | xargs) - - # Write new file - echo $new_cmdline | sudo tee /etc/kernel/cmdline -else - echo "" - echo " None of systemd-boot, GRUB, or UKI detected. Please manually add these kernel parameters:" - echo " - splash (to see the graphical splash screen)" - echo " - quiet (for silent boot)" - echo "" -fi - -if [ "$(plymouth-set-default-theme)" != "omarchy" ]; then - sudo cp -r "$HOME/.local/share/omarchy/default/plymouth" /usr/share/plymouth/themes/omarchy/ - sudo plymouth-set-default-theme -R omarchy -fi - -# ============================================================================== -# SEAMLESS LOGIN -# ============================================================================== - -if [ ! -x /usr/local/bin/seamless-login ]; then - # Compile the seamless login helper -- needed to prevent seeing terminal between loader and desktop - cat <<'CCODE' >/tmp/seamless-login.c -/* -* Seamless Login - Minimal SDDM-style Plymouth transition -* Replicates SDDM's VT management for seamless auto-login -*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int main(int argc, char *argv[]) { - int vt_fd; - int vt_num = 1; // TTY1 - char vt_path[32]; - - if (argc < 2) { - fprintf(stderr, "Usage: %s \n", argv[0]); - return 1; - } - - // Open the VT (simple approach like SDDM) - snprintf(vt_path, sizeof(vt_path), "/dev/tty%d", vt_num); - vt_fd = open(vt_path, O_RDWR); - if (vt_fd < 0) { - perror("Failed to open VT"); - return 1; - } - - // Activate the VT - if (ioctl(vt_fd, VT_ACTIVATE, vt_num) < 0) { - perror("VT_ACTIVATE failed"); - close(vt_fd); - return 1; - } - - // Wait for VT to be active - if (ioctl(vt_fd, VT_WAITACTIVE, vt_num) < 0) { - perror("VT_WAITACTIVE failed"); - close(vt_fd); - return 1; - } - - // Critical: Set graphics mode to prevent console text - if (ioctl(vt_fd, KDSETMODE, KD_GRAPHICS) < 0) { - perror("KDSETMODE KD_GRAPHICS failed"); - close(vt_fd); - return 1; - } - - // Clear VT and close (like SDDM does) - const char *clear_seq = "\33[H\33[2J"; - if (write(vt_fd, clear_seq, strlen(clear_seq)) < 0) { - perror("Failed to clear VT"); - } - - close(vt_fd); - - // Set working directory to user's home - const char *home = getenv("HOME"); - if (home) chdir(home); - - // Now execute the session command - execvp(argv[1], &argv[1]); - perror("Failed to exec session"); - return 1; -} -CCODE - - gcc -o /tmp/seamless-login /tmp/seamless-login.c - sudo mv /tmp/seamless-login /usr/local/bin/seamless-login - sudo chmod +x /usr/local/bin/seamless-login - rm /tmp/seamless-login.c -fi - -if [ ! -f /etc/systemd/system/omarchy-seamless-login.service ]; then - cat </dev/null; then - yay -S --noconfirm --needed tzupdate - sudo tee /etc/sudoers.d/omarchy-tzupdate >/dev/null < ~/.config/uwsm/env << 'EOF' +# Common environment variables for all graphical sessions +export GTK_THEME=Adwaita:dark +export QT_STYLE_OVERRIDE=Adwaita-Dark +export XCURSOR_THEME=Yaru +export XCURSOR_SIZE=24 +export MOZ_ENABLE_WAYLAND=1 +export QT_QPA_PLATFORM=wayland +export SDL_VIDEODRIVER=wayland +export _JAVA_AWT_WM_NONREPARENTING=1 +export XDG_CURRENT_DESKTOP=Hyprland +export XDG_SESSION_TYPE=wayland +export XDG_SESSION_DESKTOP=Hyprland +EOF + +# Create Hyprland-specific environment variables file +cat > ~/.config/uwsm/env-hyprland << 'EOF' +# Hyprland-specific environment variables +export HYPRLAND_LOG_WLR=1 +export HYPRLAND_NO_RT=1 +EOF + +# Create desktop entry for display manager +sudo mkdir -p /usr/share/wayland-sessions +sudo tee /usr/share/wayland-sessions/hyprland-uwsm.desktop > /dev/null << 'EOF' +[Desktop Entry] +Name=Hyprland (with UWSM) +Comment=Hyprland managed by Universal Wayland Session Manager +Exec=uwsm start hyprland.desktop +Type=Application +DesktopNames=Hyprland +EOF + +# Add UWSM startup to .profile if not already present +if ! grep -q "uwsm check may-start" ~/.profile 2>/dev/null; then + echo "Adding UWSM startup to ~/.profile" + cat >> ~/.profile << 'EOF' + +# Start UWSM if conditions are met +if uwsm check may-start && uwsm select; then + exec uwsm start default +fi +EOF +fi + +# Create a UWSM service to handle Hyprland autostart applications +mkdir -p ~/.config/systemd/user +cat > ~/.config/systemd/user/uwsm-app-daemon.service << 'EOF' +[Unit] +Description=UWSM Application Daemon +PartOf=graphical-session.target +After=graphical-session.target + +[Service] +Type=forking +ExecStart=/bin/bash -c 'uwsm finalize' +RemainAfterExit=yes + +[Install] +WantedBy=graphical-session.target +EOF + +# Enable the UWSM service +systemctl --user enable uwsm-app-daemon.service + +echo "UWSM installation and configuration completed!" +echo "" +echo "Usage:" +echo " - From TTY: The system will automatically start UWSM when logging in" +echo " - From display manager: Select 'Hyprland (with UWSM)' from the session menu" +echo " - Launch applications: Use 'uwsm app -- command' instead of just 'command'" +echo " - Stop session: Use 'uwsm stop' (do not use Hyprland's exit command)" +echo "" +echo "Note: Update your Hyprland config to use 'uwsm app --' for exec-once commands" +echo "Example: exec-once = uwsm app -- waybar" \ No newline at end of file