Verified after a reboot: desktoppr reports the configured image. The in-session read-back lags behind the wallpaper store, so the retry loop only logs it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XsESshRCoBoUVWV9qKURUF
76 lines
4.1 KiB
Nix
76 lines
4.1 KiB
Nix
# User profile templates, applied on the booted image inside the logged-in
|
|
# user's session through the guest agent (after generalize with autoLogon).
|
|
# settings — { hideWidgets, wallpaper, dockApps, dockAutohide, showHiddenFiles }
|
|
{ pkgs, lib, ... }:
|
|
let
|
|
# Apple Events (osascript → System Events) need per-app automation consent that a
|
|
# headless session cannot grant; desktoppr sets the wallpaper through NSWorkspace
|
|
# inside the user's session instead (scriptingosx/desktoppr, pinned).
|
|
desktoppr = pkgs.fetchurl {
|
|
url = "https://github.com/scriptingosx/desktoppr/releases/download/v0.5/desktoppr-0.5-218.pkg";
|
|
hash = "sha256-HPtn1wI7xrx7HjyMz1yJGhutIodt938/vHfSeHfMe50=";
|
|
};
|
|
in
|
|
rec {
|
|
settings = {
|
|
hideWidgets ? true, # no desktop widgets (Sonoma+)
|
|
wallpaper ? null, # image file (drv/path) set as the desktop picture
|
|
dockApps ? null, # list of app paths, e.g. [ "/System/Applications/Utilities/Terminal.app" ]; null = untouched
|
|
dockAutohide ? false,
|
|
showHiddenFiles ? false,
|
|
darkMode ? null, # true/false/null
|
|
}: {
|
|
name = "profile";
|
|
files = lib.optionals (wallpaper != null) [
|
|
{ source = wallpaper; name = "wallpaper.${lib.last (lib.splitString "." (baseNameOf (toString wallpaper)))}"; }
|
|
{ source = desktoppr; name = "desktoppr.pkg"; }
|
|
];
|
|
bootScript = ''
|
|
set -x
|
|
[ -n "$CONSOLE_USER" ] || { echo "vmix: profile needs a logged-in user (generalize with autoLogon)"; exit 1; }
|
|
H=$(dscl . -read "/Users/$CONSOLE_USER" NFSHomeDirectory | awk '{print $2}')
|
|
D() { as_user defaults write "$@"; }
|
|
${lib.optionalString hideWidgets ''
|
|
D com.apple.WindowManager StandardHideWidgets -int 1
|
|
D com.apple.WindowManager StageManagerHideWidgets -int 1
|
|
D com.apple.widgets widgetAppearance -int 0
|
|
''}
|
|
|
|
${lib.optionalString (dockApps != null) ''
|
|
D com.apple.dock persistent-apps -array
|
|
${lib.concatMapStringsSep "\n" (a: ''
|
|
D com.apple.dock persistent-apps -array-add "<dict><key>tile-type</key><string>file-tile</string><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>file://${a}/</string><key>_CFURLStringType</key><integer>15</integer></dict></dict></dict>"
|
|
'') dockApps}
|
|
''}
|
|
${lib.optionalString dockAutohide ''D com.apple.dock autohide -bool true''}
|
|
${lib.optionalString showHiddenFiles ''D com.apple.finder AppleShowAllFiles -bool true''}
|
|
${lib.optionalString (darkMode != null) (if darkMode
|
|
then ''D -g AppleInterfaceStyle Dark''
|
|
else ''as_user defaults delete -g AppleInterfaceStyle 2>/dev/null || true'')}
|
|
as_user killall Dock Finder WindowManager 2>/dev/null || true
|
|
sleep 10
|
|
# wallpaper last: WindowManager re-applies its desktop configuration when the
|
|
# widget/dock settings above change, which reverts a choice made before it
|
|
${lib.optionalString (wallpaper != null) ''
|
|
# WallpaperAgent only keeps choices whose file lives in the user's own space
|
|
# ("No files include in the descriptor" for /Library/Desktop Pictures)
|
|
HP="$H/Pictures"; mkdir -p "$HP"
|
|
W="$HP/vmix-wallpaper.${lib.last (lib.splitString "." (baseNameOf (toString wallpaper)))}"
|
|
cp "$V/wallpaper".* "$W"; chown "$CONSOLE_USER" "$HP" "$W"; chmod 644 "$W"
|
|
installer -pkg "$V/desktoppr.pkg" -target / >/dev/null || echo "vmix: WARNING: desktoppr install failed"
|
|
# WallpaperAgent drops choices made while it is still initialising the
|
|
# session's store right after login: wait for the store, set, verify, retry
|
|
ST="$H/Library/Application Support/com.apple.wallpaper/Store/Index.plist"
|
|
for i in $(seq 1 60); do [ -f "$ST" ] && break; sleep 2; done; sleep 15
|
|
for try in 1 2 3; do
|
|
as_user /usr/local/bin/desktoppr "$W" || echo "vmix: WARNING: could not set the wallpaper"
|
|
sleep 30
|
|
CUR=$(as_user /usr/local/bin/desktoppr 2>/dev/null)
|
|
[ "$CUR" = "$W" ] && break
|
|
echo "vmix: wallpaper read-back says $CUR (lags behind the store), retrying"
|
|
done
|
|
echo "vmix: wallpaper read-back: $CUR (the store choice is what the next login uses)"
|
|
''}
|
|
'';
|
|
};
|
|
}
|