Plugin name: Kaleidoscope-Qukeys
Author: Michael Richters
Source URL: https://github.com/gedankenlab/Kaleidoscope-Qukeys
Schrödinger’s Keys!
The name “qukey” (quantum key) is a reference to the “qubit” (quantum bit) from quantum computing, because it can be in two “states” simultaneously.
Description
Kaleidoscope-Qukeys
allows you to define a key in (layer, row, column)
coordinates, with an alternate keycode that should be sent if the key is held – the keycode in the keymap will be sent if the key is “tapped”. Note, the idea is to use a modifier as the alternate keycode, but any Key
definition is allowed, so if you wanted to have your A
key send B
if it’s held, you could do that. Also, since it’s not simply a keycode, but a two-byte Key
object, you can have the alternate be LSHIFT(LCTRL(Key_LeftAlt)
(for example) to have modifier combinations as the “hold” behaviour on a single key.
Obviously, this means that you won’t be able to press and hold a qukey
for its primary purpose if this plugin is active.
Background
I was dissatisfied with the existing implementations of the “dual-use” functionality that I could find. Both SpaceCadet and DualUse work very well if you want to add extra functionality to keys that you’d normally use as modifiers (and if that’s all you want, you’re probably better off sticking with one of those plugins), but they don’t work so well if you want to add a secondary (modifier) behaviour to an existing key. I have heard that people have tried configuring dual-use keys on the home row letter keys, but that it often results in accidental modifiers when they have overlap between keys during normal typing. Qukeys
is (hopefully) a solution to this problem.
Details
To solve the typing-overlap problem, Kaleidoscope-Qukeys
doesn’t add anything to the HID report when a qukey
is pressed. At this point the qukey
is in an indeterminate state (or, if you like the quantum physics metaphor, a superposition of states), which won’t be resolved until one of three things happens:
- A timer expires. This should be something short, but just long enough that anything that’s a reasonable “tap” will not exceed the timeout. In this case the
qukey
assumes it’s alternate (i.e. modifier) state. - The
qukey
is released. In this case, it assumes its primary state (from the regular keymap), sending an extra report to the host. - A key pressed after the
qukey
was pressed is released. In this case, thequkey
takes on its alternate state, and a report is sent.
To make this work, once a qukey
is pressed, all new keypresses are suppressed and stored in a queue, until either the timer expires or one of those keys is released. When a key in the queue is released, HID reports will be sent to the host – one for each key flushed from the queue, in order, thus preserving the order of keypresses. So, there is still a danger for fast typists, if the order of key releases is not the same as the order of key presses, you could still end up getting unintended modifiers instead of printable characters.
The other caveat is that if you want to use a qukey
to modify mouse clicks (for example), you’ll have to wait for the timer to expire. This is probably not a big deal, because the timeout can probably be set quite low (200ms might be long enough).
One last note here: the qukeys
key queue is limited to 8 keys – I figure if you’re pressing that many keys in the length of time it takes for a normal tap, you’re probably not really typing anymore, so I give up and the first qukey
just gets its primary state.
Status
This plugin isn’t quite finished yet, and depends on at least one change to Kaleidoscope that hasn’t been merged into the master branch, so building it right now will be tricky. I’d be very surprised if it also wasn’t quite buggy.