I made a keylogger
It’s true. But it’s for a good reason, promise.
One of the best things about tiling window managers like i3m is the ability to launch a terminal from anywhere by pressing a simple key combination like
alt+enter and have it open in the correct place.
image courtesy of ashwin @ medium
Looks pretty, right?
While I haven’t exactly replicated the putting it in the right place part yet, MS PowerToys makes it easy to snap it to a particular zone once the terminal has been launched. Good enough for now.
k is a simple program that spies on the keyboard, waiting for the magic character combination.
Once detected, it launches the editor of my choice.
The main magic resolves around polling of the 2 keys we are interested in, the
Enter key and the
Win key (specifically LWIN in this case.)
Windows is kind of cool. I’ve been giving it a real shot to make it my main development environment over the past few months. You may remember I started my journey programming on Windows. Nostalgia!
One of the things that makes it cool is that interacting with it is pretty straightforward through the WIN32 API. For an extra layer of fun, let’s do it in Golang.
First we get the specific function we want from the win32 API. The docs do a great job describing how the keyboard and Windows interact, but to cut to the chase GetAsyncKeyState is the API to know the specific state of a key - nada, pressed down or released.
So, let’s import it.
Next, define the keys we want to look at, in this case the
LWIN and the
Enter keys. Keycodes for all keys can be found in the docs
enterKey := 0x0D
OK. Boilerplate is out of the way.
The main loop
Now an infinite loop is needed so that the state of these keys are constantly available. Make sure to give the CPU some rest. I can’t press the combo faster than
enterDown ? Good question. Glad you’re paying attention. The thing is, there’s a delay between when you start to press a button and when it is released. It even takes time, however short, for a key to travel from pressed, to fully up. Windows also has something called
repeat which repeats the character press if you hold the character downnnnnnnnnnnnnnnnnnnnnnnnn.
k doesn’t care about any of that. In fact, without the
enterDown logic all of the other stuff just makes
k think the button combination continues to be pressed. Resulting in hilarious outcomes like spawning 600 terminal windows.
The finished product
Main logic explained. How is it all put together? Take a look at the repo.
I am not sure if I will keep developing this tool. It kind of does exactly what I want it to do. It will be annoying to recompile if I decide to start using a different terminal. Or if I want to change the key combination. Or if I happen to want another macro to do something else.
I have no interest in spending energy on all of the what if’s. If I change any of those things a lot I may make it configurable to some extent. But I probably won’t.
How does it look?
Why not use?
Of course, there’s a lot of tools I could be using instead of this, like AutoHotKey. I could get a better keyboard with programmable macros. Or I could do some QMK programming on my macropad?
Maybe next time :)