Files
linux-provisioning/stages/09-desktop.sh
2026-06-08 22:00:31 +10:00

220 lines
8.6 KiB
Bash
Executable File

#!/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" "<Control><Alt>g" "$HOME/.local/bin/google"
_add_gnome_kb "scholar" "<Control><Alt>s" "$HOME/.local/bin/scholar"
_add_gnome_kb "dictionary" "<Control><Alt>d" "$HOME/.local/bin/dictionary"
_add_gnome_kb "emoji" "<Control><Alt>e" "$HOME/.local/bin/emoji"
_add_gnome_kb "hotstrings" "<Control><Alt>a" "$HOME/.local/bin/hotstrings"
_add_gnome_kb "pdf" "<Control><Alt>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 "['<Super>q', '<Alt>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 (from system .desktop files)
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."