Skip to content

fix(dock): clear stale CurrentHost shadow so Dock reads AnyHost value#4

Merged
ratazzi merged 2 commits intomasterfrom
fix/dock-autohide-read-anyhost
Apr 16, 2026
Merged

fix(dock): clear stale CurrentHost shadow so Dock reads AnyHost value#4
ratazzi merged 2 commits intomasterfrom
fix/dock-autohide-read-anyhost

Conversation

@ratazzi
Copy link
Copy Markdown
Owner

@ratazzi ratazzi commented Apr 16, 2026

Summary

  • Fixes Autohide dock isn't working #3: autohide/magnification/etc. declared via macos_dock now actually take effect on machines that still carry ByHost (CurrentHost) residue. Dock reads the CurrentHost domain first at runtime, so writing AnyHost alone was not enough — the live Dock process kept using the stale shadow.
  • Adds shadow-aware idempotency and a CurrentHost cleanup write path so the resource is self-healing, and fixes a latent use-after-free triggered by logging a freed plist value when largesize is stored as a string.
  • Adds diagnostics to the hola dock exporter so users notice residue even from the read-only command, without polluting the exported DSL (warnings go to stderr, DSL goes to stdout).

Commits

  • fix(dock): clear stale CurrentHost shadow so Dock reads AnyHost value — the actual behavioral fix (shadow cleanup on write, currentHostHasShadow in needs_change, CurrentHost sync error propagation, UAF fix). Fixes Autohide dock isn't working #3.
  • feat(dock): warn on stale CurrentHost preference residuehola dock now reads both domains for comparison, warns on mismatch, falls back to CurrentHost when AnyHost is unset for legacy installs, and routes the final DSL to stdout.

Test plan

  • zig build / zig build test
  • Repro scenario: defaults write com.apple.dock autohide -bool false && defaults -currentHost write com.apple.dock autohide -bool false (both already match target autohide false) → hola provision triggers shadow=true, needs_change=true, cleanup runs, defaults -currentHost read com.apple.dock autohide reports "does not exist".
  • Dock right-click menu flips from "Turn Hiding On" to "Turn Hiding Off" after provision when target is autohide true.
  • hola dock > out 2> err produces a clean DSL in stdout and warnings only in stderr.
  • Provision pretty TUI output unchanged — no stderr pollution (all resource logs go through logger, not std.debug.print).

ratazzi added 2 commits April 16, 2026 23:10
defaults(1) and System Settings store com.apple.dock values in the
AnyHost domain, but Dock at runtime reads the CurrentHost (ByHost)
domain first when a value exists there. On machines with ByHost residue
(stale values from OS migrations or Host UUID changes), writing only
AnyHost is not enough: Dock keeps using the shadow and ignores the
declared configuration.

- Align macos_dock read/write with AnyHost (matches the apps-write path
  that was already using AnyHost via CFPreferencesSetAppValue).
- On every write, also clear the same CurrentHost key
  (CFPreferencesSetValue(..., null, ..., CurrentHost)) and synchronize
  both domains; propagate the CurrentHost sync failure instead of
  swallowing it so cleanup failures aren't reported as success.
- Add currentHostHasShadow(key) and OR it into needs_change for all five
  managed scalars (tilesize, orientation, autohide, magnification,
  largesize). Machines where AnyHost already matches the target but
  CurrentHost still shadows now trigger the write path to self-heal.
- Fix use-after-free when logging current_*_value: lift defer
  val.deinit() from the inner blk scope to the outer if scope so the
  value stays valid during logger.debug (previously crashed with
  largesize stored as a string in the plist).

Fixes #3
Add diagnostics to the hola dock exporter so users notice ByHost
residue that macos_dock will self-heal on the next provision, even
when they only run the read-only exporter.

- Refactor into readDockPrefFromHost / scalarValuesEqual /
  fmtScalarValue / defaultsTypeFlag helpers so both AnyHost and
  CurrentHost can be read for comparison.
- Warn to stderr when AnyHost and CurrentHost disagree (CurrentHost
  stale, AnyHost authoritative) and hint the defaults -currentHost
  delete command.
- When AnyHost is unset but CurrentHost still holds a value, fall back
  to CurrentHost for compatibility and hint a defaults write migration
  so legacy ByHost-only installs still export the live config instead
  of the hardcoded defaults.
- Route the final DSL to stdout via std.fs.File.stdout so the stderr
  warnings no longer pollute or shadow the exported text when the
  user redirects command output.
@ratazzi ratazzi merged commit 1a49a1b into master Apr 16, 2026
9 checks passed
@ratazzi ratazzi deleted the fix/dock-autohide-read-anyhost branch April 16, 2026 15:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Autohide dock isn't working

1 participant