#!/usr/bin/env bash # =========================================================================== # Stage 09: Desktop Configuration # Keybindings, hotkey scripts, Ghostty, fonts, and desktop theme. # =========================================================================== # On Pop!_OS, Julian uses COSMIC desktop (Rust-based, System76's own DE). # Fedora ships with GNOME by default. This stage provides keybinding config # for both GNOME (via gsettings) and a fallback swhkd/keyd approach. # # If you install a different DE (KDE, COSMIC via COPR, Sway/Hyprland), # adjust this stage accordingly. # =========================================================================== CONFIG_DIR="${SCRIPT_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}/config" # Detect desktop environment DE="${XDG_CURRENT_DESKTOP:-unknown}" # =========================================================================== # 1. Hotkey Scripts (from hotkeys repo) # =========================================================================== # These are shell scripts that use selected text for quick actions. # They rely on: wl-clipboard, wtype, wofi, jq, xdg-open # Installed from ~/Development/hotkeys/ (cloned in stage 07). info "Setting up hotkey scripts..." HOTKEYS_DIR="$HOME/Development/hotkeys" if [ -d "$HOTKEYS_DIR" ]; then # Create a symlink or copy to ~/.local/bin for PATH access for script in google.sh scholar.sh dictionary.sh pdf.sh emoji.sh hotstrings.sh; do if [ -f "$HOTKEYS_DIR/$script" ]; then ln -sf "$HOTKEYS_DIR/$script" "$HOME/.local/bin/${script%.sh}" 2>/dev/null || true fi done ok "Hotkey scripts linked to ~/.local/bin/" else warn "hotkeys repo not cloned yet. Run stage 07 first." fi # =========================================================================== # 2. Desktop Environment Keybindings # =========================================================================== # Map Julian's COSMIC keybindings to the current DE. case "$DE" in *GNOME*|*gnome*) info "Configuring GNOME keybindings..." # ---- Custom keybindings (hotkey scripts) ---- # Map Ctrl+Alt+{G,S,D,E,A,O} to the hotkey scripts gsettings set org.gnome.settings-daemon.plugins.media-keys custom-keybindings "[]" _add_gnome_kb() { local name="$1" local binding="$2" local command="$3" local path="/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/${name}/" gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:"${path}" \ name "${name}" 2>/dev/null || true gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:"${path}" \ binding "${binding}" 2>/dev/null || true gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:"${path}" \ command "${command}" 2>/dev/null || true } _add_gnome_kb "google" "g" "$HOME/.local/bin/google" _add_gnome_kb "scholar" "s" "$HOME/.local/bin/scholar" _add_gnome_kb "dictionary" "d" "$HOME/.local/bin/dictionary" _add_gnome_kb "emoji" "e" "$HOME/.local/bin/emoji" _add_gnome_kb "hotstrings" "a" "$HOME/.local/bin/hotstrings" _add_gnome_kb "pdf" "o" "$HOME/.local/bin/pdf" # ---- Collect all custom paths into array for gsettings ---- KB_PATHS="[" for n in google scholar dictionary emoji hotstrings pdf; do KB_PATHS+="'/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/${n}/', " done KB_PATHS="${KB_PATHS%, }]" gsettings set org.gnome.settings-daemon.plugins.media-keys custom-keybindings "${KB_PATHS}" # ---- GNOME-specific shortcuts ---- # Super+L → lock (default on GNOME too) # Super+Q → close window (default is Alt+F4; set Super+Q too) gsettings set org.gnome.desktop.wm.keybindings close "['q', 'F4']" 2>/dev/null || true ok "GNOME keybindings configured." ;; *COSMIC*) info "Configuring COSMIC keybindings..." # On COSMIC, keybindings are stored in: # ~/.config/cosmic/com.system76.CosmicSettings.Shortcuts/v1/custom # This is a RON (Rust Object Notation) file. # We deploy our custom bindings from the config template. if [ -f "$CONFIG_DIR/cosmic/custom-shortcuts.ron" ]; then mkdir -p "$HOME/.config/cosmic/com.system76.CosmicSettings.Shortcuts/v1" cp "$CONFIG_DIR/cosmic/custom-shortcuts.ron" \ "$HOME/.config/cosmic/com.system76.CosmicSettings.Shortcuts/v1/custom" # Set terminal command (COSMIC desktop) echo '{ Terminal: "/usr/bin/ghostty --gtk-single-instance=true", }' > "$HOME/.config/cosmic/com.system76.CosmicSettings.Shortcuts/v1/system_actions" ok "COSMIC keybindings deployed." else warn "COSMIC shortcuts template not found. Run 'cp config/cosmic/* ~/.config/cosmic/' manually." fi ;; *Hyprland*|*sway*|*Sway*) info "Configuring Wayland compositor keybindings..." warn "No automatic config for ${DE}. Apply manually from config/hotkeys/hyprland.conf or config/hotkeys/sway.config" warn "See hotkeys/README.md for config examples." ;; *KDE*|*Plasma*) info "KDE Plasma detected. Applying keybindings via kwriteconfig..." warn "KDE keybinding automation not yet implemented. Configure manually via System Settings > Shortcuts." ;; *) warn "Unknown DE: ${DE}. Keybindings must be configured manually." warn "Reference: Ctrl+Alt+G/S/D/E/A/O → hotkey scripts in ~/Development/hotkeys/" ;; esac # =========================================================================== # 4. Ghostty terminal config # =========================================================================== info "Deploying Ghostty config..." mkdir -p "$HOME/.config/ghostty" if [ -f "$CONFIG_DIR/ghostty/config" ]; then cp "$CONFIG_DIR/ghostty/config" "$HOME/.config/ghostty/config" ok "Ghostty config deployed." fi # =========================================================================== # 5. Autostart applications # =========================================================================== info "Configuring autostart applications..." AUTOSTART_DIR="$HOME/.config/autostart" mkdir -p "$AUTOSTART_DIR" autostart_app() { local app_name="$1" local desktop_file="$2" local target="$AUTOSTART_DIR/$app_name.desktop" if [ -f "$target" ]; then ok " Autostart '$app_name' already configured." return fi # Look for the desktop file in standard locations local found="" for dir in /usr/share/applications /var/lib/flatpak/exports/share/applications ~/.local/share/applications; do if [ -f "$dir/$desktop_file" ]; then found="$dir/$desktop_file" break fi done if [ -n "$found" ]; then cp "$found" "$target" ok " Autostart '$app_name' configured." else warn " Desktop file for '$app_name' not found. Create manually: $target" fi } # Apps to autostart at login autostart_app "firefox" "org.mozilla.firefox.desktop" autostart_app "ghostty" "com.mitchellh.ghostty.desktop" autostart_app "nextcloud" "com.nextcloud.desktopclient.nextcloud.desktop" autostart_app "obsidian" "md.obsidian.Obsidian.desktop" autostart_app "thunderbird" "net.thunderbird.Thunderbird.desktop" # =========================================================================== # 6. Fonts (Nerd Fonts for terminal + dev) # =========================================================================== info "Installing Nerd Fonts..." FONT_DIR="$HOME/.local/share/fonts" mkdir -p "$FONT_DIR" # MesloLGS NF — recommended for Powerlevel10k # This is the font used on the Pop machine (MesloLGS NF Regular). install_nerd_font() { local font_name="$1" local font_dir="$FONT_DIR" # Check if already installed if ls "$font_dir"/*"$font_name"* 2>/dev/null | grep -q .; then ok "Font '$font_name' already installed." return fi info "Downloading $font_name Nerd Font..." local tmpdir tmpdir=$(mktemp -d) # Download from Nerd Fonts GitHub releases curl -fsSL "https://github.com/ryanoasis/nerd-fonts/releases/latest/download/${font_name}.zip" \ -o "$tmpdir/${font_name}.zip" 2>/dev/null && { unzip -o "$tmpdir/${font_name}.zip" -d "$tmpdir" 2>/dev/null cp "$tmpdir"/*.ttf "$font_dir"/ 2>/dev/null || true ok "Font '$font_name' installed." } || warn "Font download failed for $font_name." rm -rf "$tmpdir" } # On Pop, these were found: # MesloLGS NF (Regular, Bold, Italic, Bold Italic) # FiraCode Nerd Font Propo # ApercuMonoPro-Regular.otf (proprietary — not distributed) install_nerd_font "Meslo" install_nerd_font "FiraCode" # Rebuild font cache fc-cache -f "$FONT_DIR" 2>/dev/null || true ok "Font cache rebuilt." # =========================================================================== # 7. GTK Theme (dark mode + Papirus icons) # =========================================================================== info "Setting GTK theme and icons..." gsettings set org.gnome.desktop.interface color-scheme 'prefer-dark' 2>/dev/null || true gsettings set org.gnome.desktop.interface gtk-theme 'adw-gtk3-dark' 2>/dev/null || true gsettings set org.gnome.desktop.interface icon-theme 'Papirus-Dark' 2>/dev/null || true ok "GTK dark theme + Papirus icons set." # =========================================================================== # 8. Solaar (Logitech peripherals) config # =========================================================================== # The Pop machine had config for MX Keys Mini + MX Master 3. # Solaar config is auto-generated when you pair devices. The config # template (if supplied) can be placed at ~/.config/solaar/config.yaml info "Solaar config will be generated automatically when you pair devices." ok "Stage 09 complete: desktop configured."