Write the Chrome settings Google does not sync: vertical tabs, side panel - #33
Write the Chrome settings Google does not sync: vertical tabs, side panel#33landsman wants to merge 2 commits into
Conversation
…anel Chrome syncs bookmarks, extensions, passwords and most of the Settings page, but a handful of window-chrome toggles are per-installation and never leave the machine. Vertical tabs is the one that hurts: every new Mac starts with the horizontal strip again, and the fix is a menu item nobody remembers the name of. So `make chrome` writes them, the same way `make macos` writes the System Settings panes. Not a stow package: Chrome keeps them in `Default/Preferences`, one JSON blob that also holds site permissions, engagement scores, an upload seed and the last window rectangle. Symlinking that into git would track the noise and publish the rest, so only the four keys named in the script are patched and the rest of the file is left exactly as the machine has it. Two things the script refuses to do quietly. It will not write while Chrome is running, because Chrome holds the file in memory and rewrites it on exit — the change would disappear hours later, which is the worst kind of no-op. And it writes through a temp file and a rename, so an interrupted run leaves the old Preferences intact rather than half a JSON document. python3 rather than jq: it is on macOS and on both runners, and jq is not in the Brewfile.
How to test this
Set the path once. macOS: prefs="$HOME/Library/Application Support/Google/Chrome/Default/Preferences"Linux: prefs="$HOME/.config/google-chrome/Default/Preferences"1. Back up firstThe script patches four keys and leaves the rest of the file alone, but that file also holds every site permission you have ever granted. Restoring it is a cp "$prefs" /tmp/Preferences.bak2. The guard, with Chrome openThis is the failure this whole script is shaped around: Chrome holds make chromeExpected — it refuses and exits non-zero: If it instead reports 3. Break the settings, so a no-op cannot passRunning the script against a profile that already matches proves nothing. In Chrome:
Quit Chrome completely — ⌘Q on macOS, not just closing the window. A lingering window means the file on disk never changed and you are about to test nothing. Confirm it really is gone before continuing: pgrep -x "Google Chrome" || pgrep -x chrome || echo "not running"
python3 -c 'import json,sys;print(json.load(open(sys.argv[1]))["vertical_tabs"])' "$prefs"
# {'enabled': False, ..., 'uncollapsed_width': <whatever you dragged it to>}4. Run itmake chromeExpected: 5. Check what actually movedThe point is that it changed four keys and nothing else. Diff the backup against the result, both pretty-printed: diff <(python3 -m json.tool /tmp/Preferences.bak) <(python3 -m json.tool "$prefs")Expected: only Then run it a second time and diff again: the output must be empty. Idempotence is what makes this safe to leave in the install sequence. 6. Reopen ChromeVertical tabs are back, the strip is 240 wide, the side panel opens on the left. That last hop matters on its own — it proves Chrome accepted the edited file rather than discarding it as tampered-with, which is the failure mode these keys would have if Chrome tracked them in RestoreWith Chrome closed: cp /tmp/Preferences.bak "$prefs"LinuxSame six steps against the Linux
|
Chrome syncs bookmarks, extensions, passwords and most of the Settings page, but a handful of window-chrome toggles are per-installation and never leave the machine. Vertical tabs is the one that hurts — every new Mac starts with the horizontal strip again.
make chromewrites them, the same waymake macoswrites the System Settings panes.Everything else worth having — pinned toolbar actions, bookmark bar, theme, languages — already sits under
account_valuesin the profile, so Chrome syncs it and it would only be noise here.Why a script and not stow
Chrome keeps these in
Default/Preferences: one JSON blob that also holds site permissions, engagement scores, an upload seed and the last window rectangle. Symlinking it into git would track the noise and publish the rest, so only the four keys named in the script are patched and the rest of the file is left as the machine has it. Same reasoning asbin/macos/defaults.sh.Two refusals, both deliberate:
Preferencesintact rather than half a JSON document.python3rather thanjq: it ships with macOS and with both runners, andjqis not in the Brewfile.Checks
bin/chrome/prefs.test.shruns against a throwaway profile via$CHROME_PREFS, with apgrepstub onPATH— so it never touches the real Chrome profile and gives the same answer on a runner with no Chrome at all. It covers: the file stays valid JSON, sibling and unrelated keys survive, a missing parent is created, the run is idempotent, the guard refuses while Chrome runs, and--dry-runreaches nothing.make qapasses on this branch.