Plugin name: Kaleidoscope-Qukeys
Author: Michael Richters
Source URL: https://github.com/gedankenlab/Kaleidoscope-Qukeys
The name “qukey” (quantum key) is a reference to the “qubit” (quantum bit) from quantum computing, because it can be in two “states” simultaneously.
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.
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.
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
qukeyassumes it’s alternate (i.e. modifier) state.
qukeyis 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
qukeywas pressed is released. In this case, the
qukeytakes 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.
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.