docs/setup-linux.md
In Linux, kanata needs to be able to access the input and uinput subsystem to inject events. To do this, your user needs to have permissions. Follow the steps in this page to obtain user permissions.
sudo groupdel uinput 2>/dev/null
sudo groupadd --system uinput
input and uinput groupsudo usermod -aG input $USER
sudo usermod -aG uinput $USER
Verify:
groups
You may need to log out and back in for it to take effect.
sudo modprobe uinput
This ensures /dev/uinput exists.
Create the udev rule:
sudo tee /etc/udev/rules.d/99-input.rules > /dev/null <<EOF
KERNEL=="uinput", MODE="0660", GROUP="uinput", OPTIONS+="static_node=uinput"
EOF
Reload udev rules:
sudo udevadm control --reload-rules && sudo udevadm trigger
Verify:
ls -l /dev/uinput
Expected output:
crw-rw---- 1 root uinput 10, <minor> <MMM DD HH:MM> /dev/uinput
If uinput is not listed in groups even after adding your user:
newgrp uinput -c kanata
This temporarily gives the current shell the uinput group so kanata can access /dev/uinput until the next login.
First, create the directory for user services:
mkdir -p ~/.config/systemd/user
Then add this to: ~/.config/systemd/user/kanata.service:
[Unit]
Description=Kanata keyboard remapper
Documentation=https://github.com/jtroo/kanata
[Service]
Environment=PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/bin
# Uncomment the 4 lines beneath this to increase process priority
# of Kanata in case you encounter lagginess when resource constrained.
# WARNING: doing so will require the service to run as an elevated user such as root.
# Implementing least privilege access is an exercise left to the reader.
#
# CPUSchedulingPolicy=rr
# CPUSchedulingPriority=99
# IOSchedulingClass=realtime
# Nice=-20
Type=simple
ExecStart=/usr/bin/sh -c 'exec $$(which kanata) --cfg $${HOME}/.config/kanata/config.kbd --no-wait'
Restart=on-failure
RestartSec=3
[Install]
WantedBy=default.target
Note: The --no-wait flag is required for Restart=on-failure to work.
Without it, kanata waits for user input on exit, which blocks automatic restart.
Make sure to update the executable location for sh in the snippet above.
This would be the line starting with ExecStart=/usr/bin/sh -c.
You can check the executable path with:
which sh
Also, verify if the path to kanata is included in the line Environment=PATH=[...].
For example, if executing which kanata returns /home/[user]/.cargo/bin/kanata, the PATH line should be appended with /home/[user]/.cargo/bin or :%h/.cargo/bin.
%h is one of the specifiers allowed in systemd, more can be found in https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#Specifiers
Then run:
systemctl --user daemon-reload
systemctl --user enable kanata.service
systemctl --user start kanata.service
systemctl --user status kanata.service # check whether the service is running
Edit new file /etc/init.d/kanata as root, replacing <username> as appropriate:
#!/sbin/openrc-run
command="/home/<username>/.cargo/bin/kanata"
#command_args="--config=/home/<username>/.config/kanata/kanata.kbd"
command_background=true
pidfile="/run/${RC_SVCNAME}.pid"
command_user="<username>"
Then run:
sudo chmod +x /etc/init.d/kanata # script must be executable
sudo rc-service kanata start
rc-status # check that kanata isn't listed as [ crashed ]
sudo rc-update add kanata default # start the service automatically at boot
The original text was taken and adapted from: https://github.com/kmonad/kmonad/blob/master/doc/faq.md#linux