A keyboard input remapper for Linux/Wayland systems, written by @wez
A keyboard input remapper for Linux/Wayland systems, written by @wez
A keyboard input remapper for Linux/Wayland systems, written by @wez
I couldn't find a good solution for the following:
CAPSLOCK key so that it produces CTRL when held, but ESC if tappedF3 -> CTRL+c, and ALT+LEFT to HOMEevremap works by grabbing exclusive access to an input device and maintaining
a model of the keys that are pressed. It then applies your remapping configuration
to produce the effective set of pressed keys and emits appropriate changes to a virtual
output device.
Because evremap targets the evdev layer of libinput, its remapping
is effective system-wide: in Wayland, X11 and the linux console.
Here's an example configuration that makes capslock useful:
…You can also express simple remapping entries:
# This config snippet is useful if your keyboard has an arrow
# cluster, but doesn't have page up, page down, home or end
# keys. Here we're configuring ALT+arrow to map to those functions.
[[remap]]
input = ["KEY_LEFTALT", "KEY_UP"]
output = ["KEY_PAGEUP"]
[[remap]]
input = ["KEY_LEFTALT", "KEY_DOWN"]
output = ["KEY_PAGEDOWN"]
[[remap]]
input = ["KEY_LEFTALT", "KEY_LEFT"]
output = ["KEY_HOME"]
[[remap]]
input = ["KEY_LEFTALT", "KEY_RIGHT"]
output = ["KEY_END"]When applying remapping configuration, ordering is important:
Here's an example where ordering is important: on the PixelBook Go keyboard, the function key row has alternate functions on the keycaps. It is natural to want the mute button to mute by default, but to emit the F8 key when holding alt. We can express that with the following configuration:
[[remap]]
input = ["KEY_LEFTALT", "KEY_F8"]
# When our `input` is matched, our list of `output` is prevented from
# matching as the `input` of subsequent rules.
output = ["KEY_F8"]
[[remap]]
input = ["KEY_F8"]
output = ["KEY_MUTE"]How do I list available input devices?
sudo evremap list-devices
How do I list available key codes?
evremap list-keys
Is there a GUI for editing the config file? Yes, take a look at Evremap-GUI
$ sudo dnf install libevdev-devel # redhat/centos
## or
$ sudo apt install libevdev-dev pkg-config # debian/ubuntu
$ cargo build --releaseTo run the remapper, invoke it as root (so that it can grab exclusive access to the input device):
$ sudo target/release/evremap remap my-config-file.tomlOr, grant an unprivileged user access to evdev and uinput.
On Ubuntu, this can be configured by running the following commands and rebooting:
sudo gpasswd -a YOUR_USER input
echo 'KERNEL=="uinput", GROUP="input"' | sudo tee /etc/udev/rules.d/input.rulesFor some platforms, you might need to create an input group first and run:
echo 'KERNEL=="event*", NAME="input/%k", MODE="660", GROUP="input"' | sudo tee /etc/udev/rules.d/input.rulesas well.
A sample system service unit is included in the repo. You'll want to adjust the paths to match your system and then install and enable it:
$ sudo cp evremap.service /usr/lib/systemd/system/
$ sudo systemctl daemon-reload
$ sudo systemctl enable evremap.service
$ sudo systemctl start evremap.serviceIf you're using Runit instead of Systemd, follow these steps to create a service.
evremap and create a file called run under itsudo mkdir /etc/sv/evremap
sudo touch /etc/sv/evremap/run#!/bin/sh
set -e
exec remap Replace with the path to your evremap executable and with the path to your configuration file.
/var/servicesudo ln -s /etc/sv/evremap /var/serviceTo make an OpenRC service, create the file /etc/init.d/evremap with the following contents...
#!/usr/bin/openrc-run
supervisor=supervise-daemon
command=""
command_args="remap "Replace with the path to your evremap executable and with the path to your configuration file.
Make the file executable...
chmod +x /etc/init.d/evremapEnable the service with...
rc-update add evremapStart the service with...
rc-service evremap startThat feature is not implemented.
No open issues yet, or sync has not completed.