Flattening/consolidating dconf options with `home-manager` and flakes

I’m not sure whether or not this is possible with home-manager, and I’m not familiar enough with NixOS/Nix to interpret most of the things going on in the background here. I’ve done my best, but bear with me:

I would like to configure some dconf options (for the purposes of this post, I’ll limit it to two example gnome extensions) in my nix config, which uses home-manager and flakes.

What works:

dconf.settings = {
  # Extensions
  "org/gnome/shell" = {
    disable-user-extensions = false;
    disabled-extensions = [
      "disabled"
    ];
    enabled-extensions = [
      "forge@jmmaranan.com"
      "Vitals@CoreCoding.com"
      "drive-menu@gnome-shell-extensions.gcampax.github.com"
      "ddterm@amezin.github.com"
      "supergfxctl-gex@asus-linux.org"
      "espresso@coadmunkee.github.com"
      "ddterm@amezin.github.com"
      "blur-my-shell@aunetx"
      "just-perfection-desktop@just-perfection"
    ];
  };
  "org/gnome/shell/extensions/vitals" = {
      show-battery = true;
      hot-sensors = [
        "_memory_usage_"
        "_processor_usage_"
        "_battery_state_"
        "_battery_rate_"
      ];
  };
  "org/gnome/shell/extensions/espresso" = {
    show-notifications = false;
  };
  "org/gnome/shell/extensions/just-perfection" = {
    app-menu = false;
    activities-button = false;
    dash = false;
    workspace-switcher-should-show = true;
    startup-status = 0;
  };
}

This works, but I’d like to consolidate things a little bit. Is it possible to do something like this:

What doesn’t work

dconf.settings = {
  # Extensions
  "org/gnome/shell" = {
    disable-user-extensions = false;
    disabled-extensions = ["disabled"];
    enabled-extensions = [
      "forge@jmmaranan.com"
      "Vitals@CoreCoding.com"
      "drive-menu@gnome-shell-extensions.gcampax.github.com"
      "ddterm@amezin.github.com"
      "supergfxctl-gex@asus-linux.org"
      "espresso@coadmunkee.github.com"
      "ddterm@amezin.github.com"
      "blur-my-shell@aunetx"
      "just-perfection-desktop@just-perfection"
    ];
    "extensions" = {
      "vitals" = {
        show-battery = true;
        hot-sensors = [
          "_memory_usage_"
          "_processor_usage_"
          "_battery_state_"
          "_battery_rate_"
        ];
      };
      "espresso" = {
        show-notifications = false;
      };
      "just-perfection" = {
        app-menu = false;
        activities-button = false;
        dash = false;
        workspace-switcher-should-show = true;
        startup-status = 0;
      };
    };
  };
};

This nested configuration exits with the following error:

 error: A definition for option `dconf.settings."org/gnome/shell".extensions' is not of type `GVariant value'. Definition values:
       - In `/nix/store/cvnfsq579picrkmw3kz8l12wm9n8lfyh-source/home/home.nix':
           {
             espresso = {
               show-notifications = false;
             };
             just-perfection = {
           ...

…And taking just-perfection as an example, from my understanding and a conversation in the community discord means that home-manager translates this to:

  • Dconf key
  • Path: org/gnome/shell
  • Name: extensions
  • Value:
"vitals" = {
  show-battery = true;
  hot-sensors = [
    "_memory_usage_"
    "_processor_usage_"
    "_battery_state_"
    "_battery_rate_"
  ];
};
"espresso" = {
  show-notifications = false;
};
"just-perfection" = {
  app-menu = false;
  activities-button = false;
  dash = false;
  workspace-switcher-should-show = true;
  startup-status = 0;
};

Instead of what I would expect:

  • Dconf key 1

  • Path: org/gnome/shell/extensions/just-perfection

  • Name: app-menu

  • Value: false

  • Dconf key 2

  • Path: org/gnome/shell/extensions/just-perfection

  • Name: activities-button

  • Value: false

…etc etc. Keep in mind that I’m using just-perfecion as the example in both cases, the first is just interpreted weirdly.

Where did it go wrong?

It looks like home-manager doesn’t flatten the path as I would intuitively expect - org/gnome/shell, extensions, just-perfection and app-menu flatten into org/gnome/shell.extensions = just-perfection rather than org/gnome/shell/extensions/just-perfection.app-menu = false.

From my limited knowledge, it looks like home-manager’s dconf module can only handle one level of flattening at a time - it flattens just-perfection to org/gnome/shell/extensions just fine, but attempting to flatten twice - first extensions to org/gnome/shell, then just-perfection to it’s result (org/gnome/shell/extensions) - fails.

Is this a misconfiguration on my part, a bug/limitation in home-manager, or something else?

Many thanks!
Gramdalf

Apologies for the long, run on, semi-repetitive post - my brain is frazzled at the moment. I wanted to get this post off for now, but I can clarify later on if anything is unclear.

The dconf module just directly maps to a keyfile and from the point of a keyfile (basically an INI file), the section names are just strings.

You could write a code to flatten the hierarchical attrsets but then it would become ambiguous if we also wanted to support GVariant dictionaries.