Set a dconf key without double quotes

I am trying to set the weather provider for the Gnome Weather app with the following home-manager code snippet:

"org/gnome/shell/weather" = {
  locations = "[<(uint32 2, <('London', 'EGWU', true, [(0.89971722940307675, -0.007272211034407213)], [(0.89884456477707964, -0.0020362232784242244)])>)>]";
};

When I check the dconf keyvalue with the following command dconf read /org/gnome/shell/weather/locations I get the following result:

"[<(uint32 2, <('London', 'EGWU', true, [(0.89971722940307675, -0.007272211034407213)], [(0.89884456477707964, -0.0020362232784242244)])>)>]

However the correct key value should be as follows (without the double quotes at the beginning and end:

[<(uint32 2, <('London', 'EGWU', true, [(0.89971722940307675, -0.007272211034407213)], [(0.89884456477707964, -0.0020362232784242244)])>)>]

I have a tried a number of approaches but no matter what I do, I can not get rid of the double quotes.

If I try and set the weather provider non-declaractively by using the Gnome Weather application, then the dconf key value is set correctly.

Any assistance would be greatly appreciated.

The format is complex here. Firstly, look at the gvariant section in the https://nix-community.github.io/home-manager/index.html#sec-option-types-gvariant

You need to use these types to represent the data. Which means you need to know how to read the encoded types from dconf dump.

The gist of it is that:

  • there are various numeric types, pretty obvious
  • there are tupes, which are in ()
  • there are lists, known as arrays, in []
  • the <> are nested variant values

So, this structure looks to me like

  • an array of locations (nix lists are mostly converted automatically, but you may need mkArray around types that are not automatically coerced?)
  • each location is a mkVariant of
    • a mkTuple of
      • a mkUInt32
      • a mkVariant of
        • a mkTuple of
          • 2 strings and a bool (which will be converted automatically from nix types)
          • 2 mkArray’s of mkTuples, each with a pair of mkDoubles (which will be converted)

I don’t know why it’s this complex, but that seems to be what it’s expecting.

Converting this to nix (for my location) I get:

    "org/gnome/shell/weather" = {
      locations = [
        (mkVariant (mkTuple [
          (mkUint32 2)
          (mkVariant (mkTuple [
            "Melbourne"
            "YMML"
            true
            [ (mkTuple [ (-0.65740735740229495) 2.5278185274873568 ]) ]
            [ (mkTuple [ (-0.6600253512802865) 2.5301456447922108 ]) ]
          ]))
        ]))
      ];
    };

which works, although the floating point numbers come out different for some reason, and get reset by gnome weather when starting. Not quite sure what’s going on there, or what the numbers are

Specifically, with respect to the numbers, nix sets:

/org/gnome/shell/weather/locations
  [<(uint32 2, <('Melbourne', 'YMML', true, [(-0.65740699999999996, 2.527819)], [(-0.66002499999999997, 2.5301459999999998)])>)>]

which gets reset by gnome-weather to:

/org/gnome/shell/weather/locations
  [<(uint32 2, <('Melbourne', 'YMML', true, [(-0.65740735740229495, 2.5278185274873568)], [(-0.6600253512802865, 2.5301456447922108)])>)>]

Which looks suspiciously like nix is using single-precision floats

Oh, I should have said right up front: there is not, as far as I know, a way to supply a pre-encoded dconf dump string directly. Which would be useful in cases where the type is more complex than really needs to be expressed in nix, and especially because of the float precision issue here.

The conversion can at least be automated with GitHub - gvolpe/dconf2nix: 👣 Convert Dconf files (e.g. Gnome Shell) to Nix, as expected by Home Manager

I had some trouble with that tool when I last tried; it gobbled memory until hitting the timeout even when given longer times. I didn’t really bother looking into why, though.

The numbers are lat/long pairs, in radians. Not sure why there are two, maybe it’s a bounding box of map area or something.

@uep and @jtojnar Thank You! Combining both your posts nail it. :tada:

For anyone else who stumbles on this post, in addition to the code above, you also need to include the following code snippet in your home.nix file otherwise you will receive a variable not defined error:

with lib.hm.gvariant;
2 Likes

Yeah. In my case, this is the surrounding block around each of the keys:

  dconf.settings = let inherit (lib.hm.gvariant) mkTuple mkUint32 mkVariant; in {
  …
  };

Same effect, just more specific and (arguably) more in keeping with current idioms.

That got fixed in https://github.com/gvolpe/dconf2nix/pull/80, which is a part of 0.1.1.

Well, the floating precision issue can be worked around by explicitly calling mkDouble with the number as a string, ie:

[ (mkTuple [ (mkDouble "-0.65740735740229495") (mkDouble "2.5278185274873568") ]) ]
[ (mkTuple [ (mkDouble "-0.6600253512802865") (mkDouble "2.5301456447922108") ]) ]

which at least avoids having the dconf values change back and forth all the time.

Hmm… nixpkgs-unstable has 0.0.12; seems like that should be bumped.

https://nixpk.gs/pr-tracker.html?pr=197336

1 Like