OFFSET偏移
← All articlesOFFSET / FIELD NOTESNO. 077

Managing GSettings defaults and dconf state

Distinguish schema defaults, vendor overrides, and the user database to choose the right declarative interface.

English translation · Code and commands follow the Chinese original.

IN THESE READING PATHSA declarative GNOME desktop on NixOS ↗
About 4 min readStart reading

Verification scope: the nixpkgs nixos-unstable modules and upstream documentation consulted in October 2026. Group lists, package counts, and service defaults change with the revision; when deploying, use the nixpkgs and Home Manager source pinned by your project as the authority. No build, activation, or desktop runtime tests were performed for this article.

The problem#

Where does GNOME store its settings, such as themes, wallpaper, peripherals, and Night Light? Will a rebuild lose them? How can they become declarative and reproducible?

Storage mechanism: dconf#

GNOME stores its configuration in dconf, a key-value database whose physical file is ~/.config/dconf/user (binary). The dconf and gsettings command-line tools access it.

  • dconf dump / exports the key-value pairs explicitly saved in the user database; this is not the same as all effective settings, nor does it guarantee that every value differs from its schema default
  • dconf read /path/to/key reads a single value
  • The GNOME Settings interface changes this database

The key property: it is runtime state, outside /nix/store; rebuilds preserve it, but it is not tracked in git.

Three levels of precedence#

Three layers determine a GSettings key’s value, from lowest to highest priority:

1. schema 默认值(包自带的 XML schema)
2. GSettings override(NixOS 生成的"系统默认",如壁纸、favorite-apps)
3. 用户 dconf 数据库值  ← 优先级最高

What this means NixOS’s extraGSettingsOverrides sets layer 2 defaults: a new machine automatically gets these settings after a rebuild, but existing values in the current user’s dconf database take precedence and are not reverted. These are therefore "persistent defaults" rather than "enforced locks".

Two declarative interfaces on the NixOS side#

services.desktopManager.gnome.extraGSettingsOverrides (NixOS layer, overridable defaults)

services.desktopManager.gnome.extraGSettingsOverridePackages = [
  pkgs.gsettings-desktop-schemas
  pkgs.gnome-settings-daemon
];
services.desktopManager.gnome.extraGSettingsOverrides = ''
  [org.gnome.desktop.interface]
  show-battery-percentage=true
  clock-show-weekday=true

  [org.gnome.settings-daemon.plugins.color]
  night-light-enabled=true
  night-light-schedule-from=22.0
'';

home-manager dconf.settings (home layer, written back at activation)

# home/theme.nix 的用法
dconf.settings = {
  "org/gnome/desktop/interface" = {
    color-scheme = "prefer-dark";
    gtk-theme = "adw-gtk3-dark";
  };
};

The distinction matters

  • extraGSettingsOverrides: defaults; subsequent manual changes by the user are not overwritten (permissive)
  • home-manager dconf.settings: writes the declared keys during every Home Manager activation, restoring declared values over the user’s manual changes (write-back at activation)

Use Home Manager for themes that should be written back at activation, and extraGSettingsOverrides for default preferences that users may adjust. Home Manager’s write-back is not a continuous lock: users can still make changes afterward, and the next activation reapplies the declaration. To actually restrict user changes, use dconf’s system profile/locks mechanism.

A method for persistence#

Turn manually adjusted settings into declarations:

dconf dump / > user-settings.ini   # 导出用户数据库显式保存的值
  1. Select the settings the user deliberately changed, such as themes, peripherals, and behavioral preferences
  2. Distinguish application state from stable preferences: window dimensions are usually not migrated; whether to migrate keyboard layouts, shortcuts, or the application grid layout depends on the migration’s purpose, so do not exclude them categorically
  3. Check whether another declaration already manages the setting, such as themes in theme.nix; avoid duplication
  4. Use gsettings to find the corresponding schema ID, key name, and type. Convert dconf path groups into schema groups, then put them in extraGSettingsOverrides (overridable defaults); include the packages that provide those schemas

Choosing the right level

  • Appearance/interaction preferences → extraGSettingsOverrides (reproducible defaults)
  • Reapply at every activation → Home Manager dconf.settings
  • Actually restrict user changes → dconf system profile/locks
  • Internal application state → decide according to the migration goal; avoid putting all frequently changing runtime state into declarations

Related articles#

Export formats and checking effective values#

A dconf dump / section such as [org/gnome/desktop/interface] is a database path, whereas a GSettings override uses [org.gnome.desktop.interface], a schema ID. Schemas may use different paths or be relocatable, so you cannot mechanically replace every slash with a dot. Use gsettings list-schemas, gsettings list-keys, gsettings describe, and gsettings range to establish the mapping.

If an existing user value masks a new default, back up first, then use gsettings reset <SCHEMA_ID> <KEY> to clear the user value for that specific key. Do not reset the entire dconf database just to apply one theme. After building, you still need activation/a new login and a check with gsettings get to verify the effective value.

References & further reading

  1. Nixpkgs GNOME module ↗
  2. Nixpkgs GNOME documentation ↗
  3. GLib GSettings and vendor overrides ↗
  4. Home Manager dconf module ↗
  5. Managing GNOME dconf defaults ↗

Adapted from technical notes. Examples use generic names.

Continue along a reading path

A declarative GNOME desktop on NixOS

  1. 01Declarative GNOME desktop management
  2. 02GNOME module options reference
  3. 03Managing GSettings defaults and dconf state
  4. 04From settings diffs to declarations and extensions
  5. 05Building GNOME variants with Specialisation
  6. 06kmscon and uwsm in Wayland sessions
CONTINUE READING / NEXT ARTICLEFrom settings diffs to declarations and extensions

Export differences, verify schema keys and types, then declare packages and the enabled-extension list.