summaryrefslogtreecommitdiff
path: root/bin/macos-defaults-diff
diff options
context:
space:
mode:
authorIgor Soarez <igor@soarez.org>2026-09-27 10:14:30 +0300
committerIgor Soarez <igor@soarez.org>2026-09-27 10:14:30 +0300
commitbf177c58da897dbd084cc1fe8e6ebd9b61b85830 (patch)
tree6024ee158efdb94856097a9bd42472074e6beb73 /bin/macos-defaults-diff
parentb0714511e8557686cda9e0551324fd273a97e9b1 (diff)
macos: hot corners and tap to click, and a way to find the next key
Three settings this account has always set by hand on every new Mac, now in the script that exists for exactly that: the bottom-right hot corner sleeping the display, tap to click, and three-finger drag on an external trackpad -- the last a gap, since the script set it only for the built-in one. Each of those is written in more than one place because macOS keeps them in more than one place: an external Magic Trackpad has its own domain, and the login window reads com.apple.mouse.tapBehavior rather than either of them, per-host for this machine and globally for any other. Setting one and not the others is why tap to click sometimes survives a reboot and sometimes does not. bin/macos-defaults-diff is the general answer: snapshot, change one setting, and it prints what moved, including the -currentHost domains a plain `defaults read` never shows. It flushes cfprefsd first, since a change made seconds earlier can otherwise be missing from the read meant to reveal it, and it says plainly when nothing changed -- anything behind Privacy & Security lives in the SIP-protected TCC database and cannot be scripted at all.
Diffstat (limited to 'bin/macos-defaults-diff')
-rwxr-xr-xbin/macos-defaults-diff99
1 files changed, 99 insertions, 0 deletions
diff --git a/bin/macos-defaults-diff b/bin/macos-defaults-diff
new file mode 100755
index 0000000..14274e3
--- /dev/null
+++ b/bin/macos-defaults-diff
@@ -0,0 +1,99 @@
+#!/bin/bash
+
+# Find the `defaults` key behind a setting you changed in System Settings, so it
+# can go in macos-defaults.sh instead of being remembered.
+#
+# macos-defaults-diff snapshot, wait while you change one setting,
+# then print what moved
+# macos-defaults-diff snap take the snapshot only
+# macos-defaults-diff show compare now against the last snapshot
+#
+# It reads both the global domains and the per-host ones (`-currentHost`), which
+# is where several trackpad, mouse and font settings live and which a plain
+# `defaults read` never shows.
+#
+# Change ONE setting at a time. macOS writes unrelated keys constantly -- window
+# positions, recent items, sidebar widths -- so a diff after three changes is
+# mostly noise with your key hidden in it.
+#
+# Quit System Settings before the second snapshot. It holds changes in memory
+# and cfprefsd may not have written them yet; the line below flushes that cache.
+#
+# Runs under macOS's /bin/bash 3.2.
+
+set -euo pipefail
+
+if [[ "$(uname)" != "Darwin" ]]; then
+ >&2 echo "macos-defaults-diff: macOS only"
+ exit 1
+fi
+
+dir="${TMPDIR:-/tmp}/macos-defaults-diff"
+mkdir -p "${dir}"
+
+snapshot() {
+ local tag="$1"
+ # cfprefsd caches writes; without this a change made seconds ago can be
+ # missing from the read that is supposed to reveal it.
+ killall cfprefsd 2>/dev/null || true
+ sleep 1
+ defaults read > "${dir}/${tag}.txt" 2>/dev/null || true
+ defaults -currentHost read > "${dir}/${tag}-host.txt" 2>/dev/null || true
+}
+
+report() {
+ if [[ ! -f "${dir}/before.txt" ]]; then
+ >&2 echo "macos-defaults-diff: no snapshot yet -- run 'macos-defaults-diff snap' first"
+ exit 1
+ fi
+ snapshot after
+ local found=""
+ if ! diff -u "${dir}/before.txt" "${dir}/after.txt" > "${dir}/delta.txt" 2>&1; then
+ found=y
+ echo "=== global domains"
+ grep -E '^[+-]' "${dir}/delta.txt" | grep -vE '^(\+\+\+|---)' | sed 's/^/ /'
+ fi
+ if ! diff -u "${dir}/before-host.txt" "${dir}/after-host.txt" > "${dir}/delta-host.txt" 2>&1; then
+ found=y
+ echo "=== this host only -- these need 'defaults -currentHost write'"
+ grep -E '^[+-]' "${dir}/delta-host.txt" | grep -vE '^(\+\+\+|---)' | sed 's/^/ /'
+ fi
+ if [[ -z "${found}" ]]; then
+ echo "nothing changed."
+ echo "Some settings are not in defaults at all: anything behind Privacy &"
+ echo "Security lives in the SIP-protected TCC database, and a few panes use"
+ echo "private APIs. Those cannot be scripted -- note them in macos-defaults.sh"
+ echo "as manual steps instead."
+ return
+ fi
+ echo
+ echo "The domain is the nearest heading above the changed line in:"
+ echo " ${dir}/delta.txt"
+ echo "Write it as: defaults write <domain> \"<key>\" -bool/-int/-string <value>"
+ echo "then add it to macos-defaults.sh, and restart whatever owns it"
+ echo "(killall Dock, killall Finder, or log out)."
+}
+
+case "${1:-}" in
+ snap)
+ snapshot before
+ echo "snapshot taken. Change one setting, then: macos-defaults-diff show"
+ ;;
+ show)
+ report
+ ;;
+ "")
+ snapshot before
+ echo "Snapshot taken. Now change ONE setting in System Settings, quit it,"
+ printf 'then press Enter: '
+ read -r _
+ report
+ ;;
+ -h|--help)
+ sed -n '3,21p' "$0" | sed 's/^# \{0,1\}//'
+ ;;
+ *)
+ >&2 echo "macos-defaults-diff: unknown argument: $1"
+ exit 1
+ ;;
+esac