Small Thoughts for a Quiet World.

Keybow in Three Rows

Keybow Three Row
I've been playing around with the Pimoroni Keybow again. It's a nice little device that is delightfully simple to tinker with for far too long at any given time. Each key can be programmed to have specific lights and do hideously complex things, should you so desire. Macros are fun!

The code to make it do stuff is just Lua, which is a good fit for a project toy like this. For a while I wanted to do weird fun things on the Keybow itself, but then I got lazier. The problem isn't that the Keybow isn't capable of being weird, it's quite capable of it. It's just that I don't want it sparkling or doing odd stuff when I'm trying to work. I want it to be dependable and just cool enough that people ask me what it is when they walk past my desk...in times where people have desks by which other people could walk.

Anyway, I settled on a simple layout. The Keybow addresses its keys in a 3x4 grid, with the USB cable coming out the right side. Which is great! except I want my mouse on the right side of my keyboard, meaning the keybow needs to be on the left of my keyboard, meaning the USB cable bonks into my keyboard. Unacceptable.

So why not turn it sideways? Now I have three rows of four keys each. By trial and error I've discovered having my media keys on the Keybow is great, because I like media. Who doesn't? Sure, we all do. That leaves me eight keys to do other things with.

Also by trial and error I discovered that I like being able to change what each key does frequently, and per app in some cases. So instead of giving each key a specific job, they all do the same thing. The magic is this:

function allmods(key, pressed) 
	
	keybow.set_modifier(keybow.LEFT_META,  keybow.KEY_DOWN)
	keybow.set_modifier(keybow.LEFT_CTRL,  keybow.KEY_DOWN)
	keybow.set_modifier(keybow.LEFT_ALT,   keybow.KEY_DOWN)
	keybow.set_modifier(keybow.LEFT_SHIFT, keybow.KEY_DOWN)
	
	keybow.tap_key(key, pressed)
	
	keybow.set_modifier(keybow.LEFT_META,  keybow.KEY_UP)
	keybow.set_modifier(keybow.LEFT_CTRL,  keybow.KEY_UP)
	keybow.set_modifier(keybow.LEFT_ALT,   keybow.KEY_UP)
	keybow.set_modifier(keybow.LEFT_SHIFT, keybow.KEY_UP)
end

then each key's definition looks like this:

function handle_key_00(pressed)
 if pressed then
	allmods(keybow.F4,pressed)
 end
end

In other words, each key on the keybow is mapped to “Press all the modifier keys, press an F key, then release all the modifiers.” To date I haven't found any conflicts to the chord ⌘ ⌥ ⇧ ^ F4

So now I have a device that sends heavily modified function keys to the system. From there I use BetterTouchTool to make those into useful commands. In the image above you can see that I've split it into three rows of four. The bottom four are (by my personal convention) for app-specific commands; defined in BTT. Thus the first key can be “search for a person” in Slack, and “create a new note” in Obsidian.

The green keys are all mapped to media keys, which the Keybow handles directly:

function handle_key_01(pressed)
  keybow.set_media_key(keybow.MEDIA_NEXT,pressed)
end

And the top row is reserved (again, by me, there's no code difference) for “global” shortcuts. Since I'm in a lot of Zoom meetings, the top row key closest to my keyboard tells BTT to send ⌥⇧A, the Zoom global keystroke for “toggle mute”.

Now, of course none of this is essential. My computing life has not become so burdensome that I need twelve new keys to handle it. But I've really enjoyed setting up the Keybow, and I like being able to redefine what each key does on a whim using BTT.

I've put my layout in a GitHub gist if you want to see the whole thing, including my awesome graph showing how to map the keys when you turn the thing sideways, which I have not been able to get to render correctly on here, no matter how many times I've tried. Just go see the gist. You'll get the gist.

I’m publishing this as part of 100 Days To Offload. You can join in yourself by visiting 100 Days To Offload.

#100DaysToOffload 31/100

Thoughts? Tell me about them!
on Mastodon | on Twitter| on Remark.as Discuss...