thinkpad: declarative dconf — keyfile → file-db layered under the user-db #72

Merged
chad merged 1 commit from glen/thinkpad-dconf into main 2026-10-15 11:44:59 -04:00
Collaborator

GNOME/GTK settings become declarative using only the existing [[files]]/[[units]], with no engine change. dconf's own ~/.config/dconf/user is a mutable binary database the desktop rewrites on every toggle, so it can't be a store symlink. Instead, the declared settings become a layer under it.

How it works

  • files/.config/dconf/bubblebox.d/00-thinkpad is a curated dconf keyfile (46 keys covering interface/theme, keyboard + caps↔esc, wm buttons and keybindings, the Vicinae Super+Space custom shortcut, power/idle, night light, shell extensions + favorites, Ptyxis and file-chooser). It holds preferences only, with no app state such as window sizes, timestamps or portal grants. Every value matches what's on think today.
  • files/.config/dconf/bubblebox.profile lists user-db:user, then file-db:~/.local/state/dconf/bubblebox, then Fedora's stock system-dbs.
  • files/.config/environment.d/20-dconf.conf sets DCONF_PROFILE, so the systemd user manager, D-Bus-activated readers (gsd-*, portals, dconf-service) and the session all see it.
  • units/dconf-bubblebox-compile.{service,path} runs dconf compile (temp file + rename) at login and whenever the keyfile symlink changes. cjust bubblebox-apply also starts it directly.
  • Semantics match NixOS system dconf: declared values are defaults. A Settings change wins, dconf reset falls back to the repo value, and a key removed from the file stops being a default. generations switch rolls the layer back like any other file.
  • dconf-bubblebox ([[files]]) has three commands. status shows shadowed keys (personal copy == declared) and overridden keys (local value differs). adopt backs up the user-db, then resets shadow copies so the layer shows through; it refuses unless the profile is live in the session. accept <key> drops one override.
  • The daily thinkpad-bubblebox-check now pings once per distinct state when a declared key is overridden with a different value.
  • Retired imperative gsettings writes: the gnome-right-click-resize recipe, and the icon-theme write in cjust icons, which would otherwise plant an override over the declared Papirus-Dark.

Verified on think (GNOME session)

  • The keyfile compiles. The compile unit's command produces a valid db, and gsettings reads declared values through the profile from an empty user-db.
  • Live single-key check (user-db backed up first): after dconf reset, the stock profile returns nothing, the bubblebox profile returns the declared true, and gsettings agrees. The value was then restored.
  • dconf-bubblebox status against the real user-db finds 46 declared keys: 46 shadowed and 0 overridden (the curation matches exactly).
  • bubblebox --profile <this> plan against the live system shows only the expected new links/units plus enables. No conflicts, generation 57641124 → a490c78e.
  • systemd-analyze --user verify passes for both units.

Not yet verified: the environment.d → logged-in session path (gsd/portals actually reading the file-db) needs a real logout/login. Rollout:

  1. Pull, then cjust bubblebox-apply.
  2. Log out and back in.
  3. Run systemctl --user show-environment | grep DCONF and dconf-bubblebox status (expect 46 shadowed).
  4. Run dconf-bubblebox adopt, then spot-check that Settings still shows the same values.

Rollback is generations switch <prev> plus a re-login; the adopt backup sits at ~/.config/dconf/user.pre-adopt.*.

GNOME/GTK settings become declarative using only the existing `[[files]]`/`[[units]]`, with no engine change. dconf's own `~/.config/dconf/user` is a mutable binary database the desktop rewrites on every toggle, so it can't be a store symlink. Instead, the declared settings become a **layer** under it. **How it works** - `files/.config/dconf/bubblebox.d/00-thinkpad` is a curated dconf keyfile (46 keys covering interface/theme, keyboard + caps↔esc, wm buttons and keybindings, the Vicinae Super+Space custom shortcut, power/idle, night light, shell extensions + favorites, Ptyxis and file-chooser). It holds preferences only, with no app state such as window sizes, timestamps or portal grants. Every value matches what's on think today. - `files/.config/dconf/bubblebox.profile` lists `user-db:user`, then `file-db:~/.local/state/dconf/bubblebox`, then Fedora's stock `system-db`s. - `files/.config/environment.d/20-dconf.conf` sets `DCONF_PROFILE`, so the systemd user manager, D-Bus-activated readers (gsd-*, portals, dconf-service) and the session all see it. - `units/dconf-bubblebox-compile.{service,path}` runs `dconf compile` (temp file + rename) at login and whenever the keyfile symlink changes. `cjust bubblebox-apply` also starts it directly. - **Semantics** match NixOS system dconf: declared values are defaults. A Settings change wins, `dconf reset` falls back to the repo value, and a key removed from the file stops being a default. `generations switch` rolls the layer back like any other file. - `dconf-bubblebox` (`[[files]]`) has three commands. `status` shows shadowed keys (personal copy == declared) and overridden keys (local value differs). `adopt` backs up the user-db, then resets shadow copies so the layer shows through; it refuses unless the profile is live in the session. `accept <key>` drops one override. - The daily `thinkpad-bubblebox-check` now pings once per distinct state when a declared key is **overridden** with a different value. - Retired imperative gsettings writes: the `gnome-right-click-resize` recipe, and the icon-theme write in `cjust icons`, which would otherwise plant an override over the declared `Papirus-Dark`. **Verified on think (GNOME session)** - The keyfile compiles. The compile unit's command produces a valid db, and `gsettings` reads declared values through the profile from an empty user-db. - Live single-key check (user-db backed up first): after `dconf reset`, the stock profile returns nothing, the bubblebox profile returns the declared `true`, and `gsettings` agrees. The value was then restored. - `dconf-bubblebox status` against the real user-db finds 46 declared keys: **46 shadowed and 0 overridden** (the curation matches exactly). - `bubblebox --profile <this> plan` against the live system shows only the expected new links/units plus enables. No conflicts, generation `57641124 → a490c78e`. - `systemd-analyze --user verify` passes for both units. **Not yet verified:** the `environment.d` → logged-in session path (gsd/portals actually reading the file-db) needs a real logout/login. Rollout: 1. Pull, then `cjust bubblebox-apply`. 2. Log out and back in. 3. Run `systemctl --user show-environment | grep DCONF` and `dconf-bubblebox status` (expect 46 shadowed). 4. Run `dconf-bubblebox adopt`, then spot-check that Settings still shows the same values. Rollback is `generations switch <prev>` plus a re-login; the adopt backup sits at `~/.config/dconf/user.pre-adopt.*`.
thinkpad: declarative dconf — keyfile → file-db layered under the user-db
All checks were successful
ci / check (pull_request) Successful in 17s
ci / thinkpad-image (pull_request) Successful in 4m49s
df4a360eeb
chad merged commit 7b6c669d69 into main 2026-10-15 11:44:59 -04:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
chad/cn!72
No description provided.