KMonad vs QMK
As I’ve discussed before, qmk is an amazing piece of software designed to program your mechanical keyboard. The problem, of course, is that you have to have a mechanical keyboard to use it.
But, what if, instead, you could run software on your computer itself that would re-interpret keypresses on your regular keyboard to give it some of the ‘magic’ that QMK has?
Enter KMonad
This nifty software lets you do simple things like key remappings, along with fancier things like layer-taps and tap-dances with any keyboard (provided it’s connected to a computer running KMonad).
When to prefer it
Of course, it doesn’t make sense to use if you have a programmable mechanical keyboard already, but consider the built-in keyboard in your laptop.
For me personally, a huge advantage of my keyboard layout is that I have backspace and return close to my thumbs, as opposed to having them somewhere in the corner where my right pinkie would need to stretch to hit them.
Just moving these keys somewhere close to the spacebar would make my laptop keyboard much more usable. Similarly, if you’ve gotten accustomed to home-row mods (modifier keys activated in your home row), you can use this to get the same behavior natively out of your laptop keyboard.
Setting it up on OSX with a non-US keyboard
It should be as simple as following along on the github page, right? Well, I hit a few snags, so I wrote this to help anyone else stuck as well
Download the code
Go to the github site and clone the code into a directory
Install ‘dext’ component
The key input-grabbing mechanism is actually taken from Karabiner Elements. As of this writing, KMonad is dependent on a specific version of the ‘dext’ library component from Karabiner Elements, meaning it will not work together with Karabiner. This is important if (like me) you used Karabiner for simple key remappings.
Here is how you make sure you install the correct dext
library (from install docs):
1
2
3
4
$ git clone --recursive https://github.com/kmonad/kmonad.git
$ cd kmonad/
$ open c_src/mac/Karabiner-DriverKit-VirtualHIDDevice/dist/Karabiner-DriverKit-VirtualHIDDevice-1.15.0.pkg
$ /Applications/.Karabiner-VirtualHIDDevice-Manager.app/Contents/MacOS/Karabiner-VirtualHIDDevice-Manager activate
Dealing with the § key if you have it
From the github issue page on this
If you have a non-US keyboard, you may have an extra key that is sometimes called a ‘Non-US backslash’. On OSX, if you switch your key layout to US, this key will type out a § symbol.
If you have this key and press it while KMonad is running, it will crash irrecoverably 😢.
You can fix this by going into the directory you have cloned into above (we’ll call it kmonad
for consistency), and editing the following file:
kmonad/src/KMonad/Keyboard/IO/Mac/Types.hs
Find the line that says:
1
-- , ((0x7,0x64), KeyNonUSBackslash)
and un-comment it to say something like the following
1
, ((0x7,0x64), KeyF13)
You’ve now backed the § key to F13 (which most computers don’t have). This won’t really do anything except:
-
When KMonad is running, your computer will interpret a key press here as pressing
F13
-
If referencing this key inside the
defsrc
section of your KMonad keyboard mappings, you have to call itf13
Compile with Stack
Because this is written in Haskell, you’ll need to use Stack build to build it. If it’s not installed, install it first.
1
$ brew install stack
Important: be sure to run the following from inside the kmonad/ directory:
1
$ stack build --flag kmonad:dext --extra-include-dirs=c_src/mac/Karabiner-DriverKit-VirtualHIDDevice/include/pqrs/karabiner/driverkit:c_src/mac/Karabiner-DriverKit-VirtualHIDDevice/src/Client/vendor/include
Move the binary
At the end of the compilation, stack will give the location that it build the binary (just called kmonad
)– move the binary somewhere easier to find and remember (like ~/bin/
)
Set privacy preferences
You have to specifically allow the kmonad
binary to listen to all key presses and intercept them.
Navigate to System Preferences > Security & Privacy > Privacy > Input Monitoring
and add the kmonad
binary from the location you created AND Terminal.app
(for now) to allow them to accept keypresses
NOTE: if you get some sort of permission or connect error at this stage, it could be an incompatible version of Karibeaner
Create a keyboard config and test from the command line
Create a keyboard config file (or just use the default mac config).
Assuming you copied it to the same directory as the kmonad
binary, run it as sudo inside the built-in Terminal app:
1
#sudo ./kmonad apple.kbd
Type around a bit, if you don’t get any errors, it should all be working fine.
Exit with Ctrl-C
Launch Kmonad on startup
Slightly modified from the issue page
Create the following file named local.kmonad.plist
, changing values of /path/to/kmonad/
and /path/to/kbd/file.kbd/
to the correct locations.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>local.kmonad</string>
<key>Program</key>
<string>/path/to/kmonad</string>
<key>ProgramArguments</key>
<array>
<string>/path/to/kmonad</string>
<string>/path/to/kbd/file.kbd</string>
</array>
<key>RunAtLoad</key>
<true />
<key>StandardOutPath</key>
<string>/tmp/kmonad.stdout</string>
<key>StandardErrorPath</key>
<string>/tmp/kmonad.stderr</string>
</dict>
</plist>
Move this plist file to /Library/LaunchDaemons/
NOTE: the binary and the .kbd file will need to be readable by launchctl’s default user. To play it safe, I gave both of these files universal read and execute permissions
Final permissions
Grant input changing permissions to the launchtl binary
(/bin/launchctl
) using the same System Preferences
menu as described before.
Unfortunately, you can’t just type the path in directly since the input-changing permissions library has a graphical user interface.
To get it in there, go to your Desktop, press Cmd+shift+G
, and then /
into the prompt window that comes up. You’ll now have the root directory (/
) loaded into a Finder window. Now you can drag the launchctl
binary in to the input-changing permissions menu.
That’s it, kinda
Now you can run KMonad, hopefully. There are some pretty big quirks around its syntax, how it works, etc. Conceptually, it lets you do the same kinds of things that QMK does, but the way its syntax is formed and the concepts behind it are a little different and take a while to wrap your head around.
But it’s worth it — your fingers will thank you!