gxhk, which stands for Go X hotkey (daemon), is an application that I made. It is a hotkey daemon for X, something in the vein of sxhkd, if you know what it is (if not, then this app is not for you, probably). When hotkeys (such as Alt+F1) get pressed (or released), the user can run various commands with the help of the hotkey daemon. My hotkey daemon has some unique features: it can be configured on the fly using a socket (similarly to bspwm for those who know it 😉) to listen to certain hotkeys and execute their commands, or to stop listening to some hotkeys, or show infos about the currently grabbed hotkeys and their associated commands. This app works only on Linux & friends, on X desktops (not on Wayland).

I initially planned to write this app in Rust, the hot language right now. That being said, there weren’t satisfactory bindings of the X libraries to Rust that could convert keysyms (numbers representing precisely the symbols on the keys of the keyboard) to keycodes (8-bit numbers that represent to the X server the keys of a desktop user’s keyboard), so I contemplated other languages for this project of an X hotkey daemon configurable like bspwm, and found Go to be a good option as a low-level language for my project, as it had a good X binding (xgb) with a helper library called xgbutil which even provided a readily done hotkey parser, how lovely! Go won me as opposed to Rust, again. I went on to make the rest of the app with all the features I planned to implement for this project. That being said, there was still a small issue.

I was a little bit frustrated that xgbutil doesn’t have a method of converting keysyms to the string which names them (e.g. “bar”), but rather to the string they output (e.g. “|”), and that made me store the necessary information about the bound keys for displaying it on demand in a manner which could cause bugs, and I didn’t like that.

One of the options that I considered was to fork the xgbutil to expose the functionality that I needed, as the project is basically dead done and sees no contributions anymore, and also address the fact that it used the WTFPL which wasn’t liked by pkg.go.dev, the site which automatically displays the documentation of Go libraries. After a good night’s sleep, I went ahead, forked xgbutil, made the necessary changes to it, then to my application, and now my app is finnaly the way I wanted it.

There are more features that could be added to my hotkey daemon, like multi-hotkey chords or mouse bindings, that I will probably implement some day, who knows…