Hello! I am using NixOS 23.11 with Gnome, and according to Gnome Settings I’m using Wayland. I also use the Colemak keyboard layout.
By default, the Capslock key with my layout backspaces. I would prefer that it act as an ESC key. I don’t see a way to do this with Gnome keyboard settings. I have also tried the following command:
setxkbmap -option caps:escape
But I get an error saying that I’m running setxkbmap against an Xwayland server. Also it simply doesn’t work.
I tried using keyd (couldn’t get it to start due to group errors) and kanata also, but these seem like overkill and have a very large learning curve. All I want to do is remap a single key.
Does anyone know how to do this on a system that isn’t using Xwindows?
Kanata is cross platform, and can do this and much more stuff (in particular, most similar linux tools don’t support chording (mapping simultaneous keypresses — for instance, I have mapped qw to esc))
I used tools like setxkbmap in the past. They’re clunky and not always work, as they alter X11 events. I recommend Kmonad which alters kernel input events. It is much more configurable, supporting afaict arbitrary configurations, and is cross platform.
I was able to get Kanata to work! Here’s how I did it.
First, I added the following to my configuration.nix file:
environment.systemPackages = with pkgs; [
...
kanata
...
];
services.kanata = {
enable = true;
keyboards = {
"logi".config = ''
(defsrc
grv 1 2 3 4 5 6 7 8 9 0 - = bspc
tab q w e r t y u i o p [ ] \
caps a s d f g h j k l ; ' ret
lsft z x c v b n m , . / rsft
lctl lmet lalt spc ralt rmet rctl
)
(deflayer colemak
grv 1 2 3 4 5 6 7 8 9 0 - = bspc
tab q w f p g j l u y ; [ ] \
esc a r s t d h n e i o ' ret
lsft z x c v b k m , . / rsft
lctl lmet lalt spc ralt rmet rctl
)
'';
};
};
Logi is just an arbitrary name that I’m using since I have a Logitech keyboard.
I then ran sudo nixos-rebuild switch and now I’m able to remap my caps lock key as esc!
Here’s a few notes:
The colemak deflayer isn’t a true colemak keyboard. The only difference is that I replaced the caps key with esc.
Of course this didn’t work the first time . I had a typo and nothing seemed to change on my keyboard after running nixos-rebuild. The good news is that the log file (that I could see with sudo journalctl -fu kanata-logi.service) did a good job telling me where the typo was.
I had to use the gnome keyboard switcher to switch to a US QWERTY layout first to make this work.
FYI, if anyone’s having permissions issues with uinput like the one below, there’s an open Github issue
Jun 04 21:36:31 midgar kanata[2788826]: 2024-06-04T21:36:31.672701327+02:00 [INFO] process unmapped keys: false
Jun 04 21:36:31 midgar kanata[2788826]: 2024-06-04T21:36:31.672745135+02:00 [INFO] NOTE: kanata was compiled to never allow cmd
Jun 04 21:36:31 midgar kanata[2788826]: 2024-06-04T21:36:31.672861387+02:00 [INFO] config file is valid
Jun 04 21:36:31 midgar kanata[2788826]: 2024-06-04T21:36:31.672889007+02:00 [ERROR] Failed to open the output uinput device. Make sure you've added the user executing kanata to the `uinput` group
Jun 04 21:36:31 midgar kanata[2788826]: 2024-06-04T21:36:31.672901284+02:00 [ERROR] Permission denied (os error 13)
Jun 04 21:36:31 midgar kanata[2788826]: Press enter to exit
Jun 04 21:36:31 midgar kanata[2788826]: Error: Permission denied (os error 13)
Jun 04 21:36:31 midgar systemd[1]: kanata-default.service: Main process exited, code=exited, status=1/FAILURE
Jun 04 21:36:31 midgar systemd[1]: kanata-default.service: Failed with result 'exit-code'.
Jun 04 21:36:31 midgar systemd[1]: Failed to start kanata-default.service.
This worked for me, let me know if its not nix way of doing this.
# /etc/nixos/configuration.nix
{ config, pkgs, ... }:
{
# ... other configurations ...
# Enable the X11 windowing system.
services.xserver = {
enable = true;
xkb.options = "caps:swapescape";
};
# ... rest of your configuration ...
}
xkb.options is traditionally an Xorg concept, modern Wayland compositors (like GNOME’s Mutter) often interpret and apply these xkbOptions settings correctly by parsing the XKB configuration. So, caps:swapescape should work as expected in your GNOME Wayland session.
I’m quite new to nix and NixOS, but your answer seems alright to me. At first I did it this way. But Minecraft takes keyboard input from a lower level API, and it doesn’t work correctly. So I used @zogstrip ‘s answer:
So, if you have a similar problem, this is a good answer too.
I mapped capslock to esc, and I was consulting ChatGPT while configuring my new machine, and suggested to cover generic keyboards, leaving it in my config as:
I guess there’s a tradeoff here. using services.xserver.xkb is easier to configure, and you don’t need to worry about targeting the hardware specifically, but with services.udev you can rest assured that any program will be compatible, no matter if it’s X11 or Wayland. In my case, since I don’t expect to switch keyboards that often or have any weird ones, udev works perfectly.
This is an old thread it seems, but did the keyd service already exist as a config option at the time? cause it does look like the service should have created the group, but if there wasn’t a service for it at the time then you probably could have tried creating a group manually. I use Guix and they don’t have a service module for keyd, but i just configured it manually by adding the group and declaratively adding the config to /etc, and creating a service to start the daemon. I personally really like it and was pretty simple to set up from my experience. I also use it for just a single key. I remap capslock to control because of Emacs
{
# this is a home-manager option
dconf.settings = {
# map caps to escape
"org/gnome/desktop/input-sources" = {
xkb-options = [ "caps:escape" ];
};
};
}
Only works on GNOME though, and I’m sure there is a better way to do it in a more portable way, but this is essentially what the setting does in gnome-tweaks.