OFFSET偏移
← 文章目录OFFSET / FIELD NOTESNO. 078

从设置 diff 到声明与扩展

导出差异、核对 schema 键和类型,再声明软件包与扩展启用列表。

所在专题NixOS 上的 GNOME 声明式桌面 ↗
约 9 分钟阅读开始阅读

核验范围:2026 年 10 月查询的 nixpkgs nixos-unstable 模块与上游文档。分组列表、包数和服务默认值会随 revision 改变;部署时应以项目锁定的 nixpkgs 和 Home Manager 源码为准。本文没有构建、激活或桌面运行测试。

「在 GNOME 设置里改了一堆东西,怎么让它换机后还在?」完整答案是一条四步工作流:导出 diff → 查键名 → 写声明 →(要装东西就)找包名/装扩展。下面是可审阅的命令示例,底层机制对照 nixpkgs 源码;没有在目标桌面执行验证。

1. 导出 diff 配置#

dconf 数据库(~/.config/dconf/user)保存显式写入的用户键值,不一定都异于默认值。两次导出相减可以观察这段时间里的数据库变化;后台应用同时写入的状态也会出现在 diff 中:

dconf dump / > before.txt      # 改动前导出
# ……在 GNOME 设置里改几个选项……
dconf dump / > after.txt
diff before.txt after.txt      # 就是你这次改的所有设置

输出格式需要转换 dconf dump 输出是 INI 风格,但 section 是路径,例如 [org/gnome/desktop/interface];extraGSettingsOverrides 使用 schema ID,例如 [org.gnome.desktop.interface]。两者必须按实际 schema/path 映射转换(见 NixOS GSettings 与 dconf 设置管理),筛掉无关状态、核对 schema ID 与类型并添加 schema 提供包后,再写入 host/gnome.nix。

想实时看改的是哪个键:dconf watch /org/gnome/desktop/interface/,开着它再改设置,能抓到键路径。

2. 查找对应的键名#

设置界面只显示翻译后的选项名,不告诉你底层键。三条路:

gsettings list-recursively | grep -i dark        # 全局搜"值/键名"含 dark
gsettings list-keys org.gnome.desktop.interface   # 某 schema 的全部键
gsettings describe org.gnome.desktop.interface color-scheme   # 键的含义
gsettings range org.gnome.desktop.interface color-scheme      # 允许值
dconf list /org/gnome/desktop/interface/          # dconf 路径视角
  • gsettings 是 schema 感知 API(schema.key 记法);dconf 是底层数据库(/org/gnome/... 路径记法)。读同一个库。
  • 不记得 schema 名?gsettings list-schemas | grep -i 关键词。
  • 图形化兜底:dconf-editor 能浏览整棵树 + 搜索,看到每个键的当前值和类型。
  • 源码层面:每个键的定义(默认值、range、description)在 gsettings-desktop-schemas 包的 *.gschema.xml 里——gsettings describe 读的就是它。

3. 安装插件扩展#

扩展在 NixOS 上推荐声明式安装:

# host/gnome.nix(示例)
environment.systemPackages = [ pkgs.gnomeExtensions.kimpanel ];

底层机制(nixpkgs 源码 pkgs/desktops/gnome/extensions/):

  • extensions.json 是从 extensions.gnome.org 爬取的索引,每条含 shell_version_map(扩展支持哪些 GNOME 版本)
  • default.nix 按当前 shell 版本过滤 → buildGnomeExtension.nix 构建 → 安装到 $out/share/gnome-shell/extensions/<uuid>/
  • pkgs.gnomeExtensions 按 nixpkgs 的扩展生成与版本选择策略聚合扩展,键名是可读 pname,不是 uuid
  • GNOME Shell 通过 XDG_DATA_DIRS 扫描 /run/current-system/sw/share/gnome-shell/extensions/ 发现系统级扩展

装完要启用 装进 systemPackages ≠ 已启用。在 GNOME 里开 Extensions 应用手动开,或命令行:gnome-extensions enable <uuid>。新安装的扩展若没有被当前 Shell 发现,通常需重新登录;已发现的兼容扩展可通过启用命令切换。

用户级替代:手动把扩展解压到 ~/.local/share/gnome-shell/extensions/<uuid>/——但这不是声明式,rebuild 不影响、换机丢失。除非扩展没进 nixpkgs,否则别走这条路。

4. 找到包名#

找包名分两问:attrset 里叫什么、在不在 nixpkgs。

nix search nixpkgs gnomeExtensions | grep -i "<关键词>"   # 模糊搜
nix eval nixpkgs#gnomeExtensions --apply builtins.attrNames --json | jq -r '.[]' # 列出全部扩展名
  • 在 extensions.gnome.org 上看到的扩展先记下 UUID(如 kimpanel@kde.org),再到本地源码 pkgs/desktops/gnome/extensions/extensions.json 里按 pname 或 uuid 搜,能直接确认 nixpkgs 收录名和版本。
  • 收录名和显示名常常不一致(Forge、Pop Shell、ArcMenu 都有专门 pname)。nix search 是最快的对齐工具。

从运行偏好到可复用声明 这四个技能合起来就是"GNOME 调优闭环":改 → diff 抓键 → 写进 extraGSettingsOverrides → 需要新能力时 nix search gnomeExtensions 装。全部可重现,不再有"这台机器上配好的,换机就没了"。

关联#

声明启用扩展#

安装包与启用 UUID 是两件事。可以在 Home Manager 中声明启用列表:

dconf.settings."org/gnome/shell" = {
  disable-user-extensions = false;
  enabled-extensions = [ "kimpanel@kde.org" ];
};

该列表会在 activation 写回,应包含需要保留的全部扩展 UUID,而不是每个模块都覆盖成自己的单个扩展。UUID 应从已安装扩展的 metadata.json 或 gnome-extensions list 核实;shell version 不匹配、扩展报错和安装路径问题仍需运行时检查。

参考与延伸

  1. Nixpkgs GNOME 模块 ↗
  2. Nixpkgs GNOME 文档 ↗
  3. GLib GSettings 与 vendor overrides ↗
  4. Home Manager dconf 模块 ↗

根据技术笔记重新整理,示例使用通用名称。

沿专题继续阅读

NixOS 上的 GNOME 声明式桌面

  1. 01GNOME 的声明式桌面管理
  2. 02GNOME 模块选项参考
  3. 03管理 GSettings 默认值与 dconf 状态
  4. 04从设置 diff 到声明与扩展
  5. 05用 Specialisation 构建 GNOME 变体
  6. 06Wayland 会话中的 kmscon 与 uwsm
CONTINUE READING / 下一篇用 Specialisation 构建 GNOME 变体

在父模块图上派生独立系统 toplevel,并明确继承、覆盖与恢复路径。