Nixos options to configure Gnome Keyboard Shortcuts

I’ve been setting up a laptop with NixOS and I’m most familiar with Gnome, so I’ve been using that. I’ve noticed that the Ctrl-Alt-T shortcut that I am used to for launching the terminal doesn’t work under NixOS. I can configure it manually in gnome-control-center, but I would prefer to configure it declaratively. I haven’t been able to find an option to do this in either NixOS or Home-Manager, is there a way to accomplish this in my nix configuration that I am missing?

3 Likes

gnome-settings-daemon is configured through GSettings, ordinarily stored in dconf database.

Usually, the best way to set it declaratively is to set it in the GUI and then look in dconf-editor or the output of dconf dump to see what changed. In my case it were these settings:

[org/gnome/settings-daemon/plugins/media-keys]
custom-keybindings=['/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/']

[org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0]
binding='<Super>t'
command='gnome-terminal'
name='Open terminal'

You can then set the default values in configuration.nix:

{
  services.xserver.desktopManager.gnome3 = {
    extraGSettingsOverridePackages = with pkgs; [ gnome3.gnome-settings-daemon ];
    extraGSettingsOverrides = ''
      [org.gnome.settings-daemon.plugins.media-keys]
      custom-keybindings=['/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/']


      [org.gnome.settings-daemon.plugins.media-keys.custom-keybindings.custom0]
      binding='<Super>t'
      command='gnome-terminal'
      name='Open terminal'
    '';
  };
}

Note you will have to reset them using dconf reset for the defaults to be picked up.

But that might not work since /org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/ is a relocatable schema.

home-manager has a dconf.settings option that should work, though.

3 Likes

Hi, I haven’t been able to try this today unfortunately, but wanted to thank you for your reply. Putting me on the track of looking for GSettings and dconf options is a huge help, and is something that would have taken me hours to figure out on my own.

Thank You!

Just to follow up on this, I did get it working eventually. I had a couple false starts, so I think it’s useful to post this for anyone else trying to do this, and to see if someone suggests something I could do better.

First, to go over my solution:

I adding the following to my Home-manager config:

dconf.settings = {
  "org/gnome/settings-daemon/plugins/media-keys" = {
    custom-keybindings = [
      "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/"
    ];
  };
};

"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0" = {
  binding = "<Primary><Alt>t";
  command = "alacritty";
  name = "open-terminal";
};

I should note, that the leading and trailing / in custom-keybindings was critical. Originally I didn’t have them, and without that I got into a state where gnome would crash as soon as I logged in. This wasn’t something that went away by booting a previous generation, and the only way I recovered was logging in as root, and restoring ~/.config/dconf/user from a previous filesystem snapshot, git stashing my config changes and doing a nixos-rebuild

Per this, I also had to add the below to get Home-manager to actually apply my dconf changes.

services.dbus.packages = [ pkgs.gnome3.dconf ]; 

Other than all that, it was easy… :smile:

2 Likes

(Zombie-ing this thread from last year.)

Does anyone else have declarative GNOME key bindings working successfully?

I tried jtojnar’s instructions to no avail. First of all, it gave an error that services.xserver.desktopManager.gnome3 does not exist, so I had to change it to services.xserver.desktopManager.gnome. Then, no errors, but also no key bindings are created.

I tried mayl’s solution, but when I run home-manager switch it complains with “error: The option `org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0’ does not exist”.

I’m new to NixOS and don’t understand what this error means.

I found the solution. I think mayl simply mis-pasted. I got it to work by adding the following to my home-manager config:

dconf.settings = {
  "org/gnome/settings-daemon/plugins/media-keys" = {
    custom-keybindings = [
      "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/"
    ];
  };
  "org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0" = {
    binding = "<Primary><Alt>t";
    command = "alacritty";
    name = "open-terminal";
  };
};
4 Likes

The following code snippet works on the latest available gnome (40) and NixOS (21.05), and makes it easy to add new shortcuts.

    dconf.settings =
      let
        inherit (builtins) length head tail listToAttrs genList;
        range = a: b: if a < b then [a] ++ range (a+1) b else [];
        globalPath = "org/gnome/settings-daemon/plugins/media-keys";
        path = "${globalPath}/custom-keybindings";
        mkPath = id: "${globalPath}/custom${toString id}";
        isEmpty = list: length list == 0;
        mkSettings = settings:
          let
            checkSettings = { name, command, binding }@this: this;
            aux = i: list:
              if isEmpty list then [] else
                let
                  hd = head list;
                  tl = tail list;
                  name = mkPath i;
                in
                  aux (i+1) tl ++ [ {
                    name = mkPath i;
                    value = checkSettings hd;
                  } ];
            settingsList = (aux 0 settings);
          in
            listToAttrs (settingsList ++ [
              {
                name = globalPath;
                value = {
                  custom-keybindings = genList (i: "/${mkPath i}/") (length settingsList);
                };
              }
            ]);
      in
        mkSettings [
          {
            name = "<Name of the shortcut>";
            command = "<Command to be executed>";
            binding = "<Binding of the shortcut>";
          }
        ]

Just add all the shortcuts as arguments of mkSettings, following the template. You can add as many as you want.

It also provides a check up at build time that all the settings are correct, otherwise it will refuse to build. This is because Gnome Session crashes when the dconf settings are wrongly edited, so it is important to prevent that from happening or it’s a real pain in the ass.

3 Likes

How would I achieve this without home-manager, that is, using just the standard NixOS options?

These are per-user settings. Probably the simplest is to save the settings you want in the dconf dump format, and have something in your login setup, or a systemd user service, that loads that file.

That’s essentially what the hm module does anyway, after generating the dconf dump file from the nix settings.

By the way, thanks for bumping the thread: I had tried to do this too and it hadn’t worked; looking at this example and the code to generate it, I noticed I was missing the trailing / from the entry in the custom-keybindings list

programs.dconf = {
  enable = true;
  profiles.user.databases = [
    {
      settings = {
        "org/gnome/settings-daemon/plugins/media-keys" = {
          area-screenshot = [ "<Primary><Shift>Print" ];
        };
      };
      lockAll = true;
    }
  ];
}
2 Likes

It looks like this is new; nice!

Available in 23.11. Nice! In the meantime this seems to work.

FYI, here’s an example of moving from gsettings to dconf and adding a custom keyboard shortcut with vanilla configuration.nix on NixOS 23.11.

1 Like