There are some amazing keyboards like dygma or uhk available. Beside of ergonomics they also support to have multiple function layers and custom layouts. They ship with easy to use software to customize the layouts and function layers. I am fine with my keyboard, but I always envy my friends for having keyboards that allow switching custom layers easily. So I asked a little bit around and someone recommended me the free open-source software kanata. It is a cross-platform software keyboard mapper for Linux, macOS and Windows and allows me to switch my keyboard layout dynamically. As an addition, I will also try to integrate kanata in my i3wm environment smoothly and create a custom menu with rofi.
Installing kanata
Kanata is written in rust, so it is possible to compile it manually or simply use the binary from the kanata github site. I saved the binary:
mv kanata /usr/local/bin
chmod +x /usr/local/bin/kanata
Configure keyboard layers
One thing I really don’t like about kanata is it’s syntax. But luckily I don’t need much. I want to keep my keyboard layout and just add some few more additions to it. So I edit the file /etc/kanata.kbd as root and tell kanata to keep the layout and define the layouts base-layer(default), nav, num and sym. If I tap on left windows key, it will switch to the nav layer. If I hold that key down it will switch to the symbols layer. If I am in the nav-layer and tap on the windows key, it will switch back to the base layer.
The nav layer allows me to use the primary keys on the right hand to use the arrow-keys, page-up, page-down or home and end:
The sym layer maps all kinds of brackets and symbols I need for coding to the primary keys on the right hand:
Since it is also useful to have the numpad on the right handside I also map the number keys to the right hand:
This is my /etc/kanata.kbd
:
(defcfg
process-unmapped-keys yes
)
(defsrc)
(defalias
cpy C-S-c
pst C-S-v
at RA-q
b1 RA-7
b2 RA-0
b3 RA-8
b4 RA-9
c @cpy
v @pst
)
(deflayermap (base-layer)
lmet (tap-hold 200 200 (layer-switch nav) (layer-while-held sym))
)
(deflayermap (nav)
u home
i up
o end
h pgup
j left
k down
l right
n pgdn
lmet (tap-hold 200 200 (layer-switch base-layer) (layer-while-held sym))
)
(deflayermap (num)
y 4
u 5
i 6
h 1
j 2
k 3
)
(deflayermap (sym)
j @b1
k @b2
l @b3
Semicolon @b4
h @at
)
Autostart kanata
In order to start kanata automatically, I created a systemd-service for my desktop-user:
systemctl --user --force --full edit kanata.service
I placed the following service-config that also starts kanata with a listening port on 12321/tcp:
[Unit]
Description=This unit will start kanata keyboard-layout-switcher
[Service]
Restart=always
Type=simple
ExecStart=sudo /usr/local/bin/kanata -p 12321 -c /etc/kantana.kbd
Environment=
[Install]
WantedBy=default.target
Since I start kanata with sudo, I also need a nifty sudo-config in /etc/sudoers.d/myuser
:
myuser ALL=(ALL) NOPASSWD:/usr/local/bin/kanata
Finally I could enable and start that service:
systemctl --user enable kanata.service
systemctl --user start kanata.service
Displaying the current layer
Now I faced the problem, that I never know what keyboard layer I am using. It would be nice to have an indicator in my
status bar for i3wm. Since I am using i3blocks, I can edit ~/.config/i3blocks/config
and add something like:
[kanata]
color=#00FF00
command=~/bin/kanata-layer.py
interval=3
This will execute that python-script every 3 seconds. I wrote a script that connects to the kanata-api-port(12321/tcp) and queries the current layer or even allows to switch the layer. Let’s install this script:
git clone https://codeberg.org/pty/kanata-i3-scripts.git
test -d ~/bin || mkdir ~/bin
cp kanata-i3-scripts/kanata-* ~/bin/
chmod +x ~/bin/kanata*
So now my i3blocks status bar indicates the keyboard-layer:
Switching the layer using rofi
Finally I also want to have a nice rofi-menu for switching the layouts. I bind the key $mod+m in my i3-config to my
custom script. For that I add the following line to my ~/config/i3/config
:
bindsym $mod+m exec rofi -modi kanata:"~/bin/kanata-rofi.sh" -show kanata
The script that allows me switching my keyboard layers was already installed together with the script to display the layer in the previous section. It is very short and simple:
#!/bin/bash
kanatalayer="$HOME/bin/kanata-layer.py"
if [ -z $1 ]
then
$kanatalayer list
else
$kanatalayer change -l $1 > /dev/null
fi
Now I press $mod+shift+r to restart i3 and I can open the menu using $mod+m and select my keyboard-layer:
Be aware that if you are using a screen-lock with password authentication, you might get locked out if you are currently on the navigation layer!