#!/usr/bin/env bash # lib/macos.sh — macOS system preferences. # Sourced by `ssr restore`. Each setting is idempotent. ssr::macos::apply_defaults() { local script="${1:-${SSR_MACOS_DEFAULTS:-$SSR_ROOT/config/macos-defaults.sh}}" if [[ ! -f "$script" ]]; then ssr::warn "macOS defaults script missing: $script (skipping)" return 0 fi ssr::log "Applying macOS defaults from $script" # shellcheck disable=SC1090 bash "$script" ssr::ok "macOS defaults applied" } ssr::macos::install_rosetta() { if /usr/bin/arch -x86_64 /usr/bin/true >/dev/null 2>&1; then return 0 fi if [[ "$(uname -m)" != "arm64" ]]; then return 0 fi ssr::log "Installing Rosetta 2" sudo softwareupdate --install-rosetta --agree-to-license } # Allows non-App-Store apps to run. Requires sudo. Skipped unless explicitly # enabled, because disabling Gatekeeper has security implications. ssr::macos::disable_gatekeeper() { [[ "${SSR_DISABLE_GATEKEEPER:-false}" == "true" ]] || return 0 ssr::warn "Disabling Gatekeeper (SSR_DISABLE_GATEKEEPER=true)" sudo spctl --global-disable } # Restart macOS UI services that read preference files restored by Mackup. # Called after mackup restore so Dock/Finder/menubar pick up the new plists. ssr::macos::restart_ui() { ssr::log "Restarting UI services (Dock, Finder, SystemUIServer, cfprefsd)" local svc for svc in cfprefsd Dock Finder SystemUIServer; do killall "$svc" 2>/dev/null || true done # Brief pause so cfprefsd flushes its cache before Dock re-reads prefs. sleep 2 ssr::ok "UI services restarted — Dock and Finder will refresh." } ssr::macos::open_installed_casks() { [[ "${SSR_OPEN_CASKS:-false}" == "true" ]] || return 0 local cask_dir cask_dir="$(brew --caskroom 2>/dev/null)" || return 0 [[ -d "$cask_dir" ]] || return 0 ssr::log "Opening installed cask apps for first-run config" find "$cask_dir" -maxdepth 3 -iname '*.app' -print0 \ | while IFS= read -r -d '' app; do open "$app" || true done }