# New plugin: Qukeys (yet another SpaceCadet/DualUse-type plugin)

**URL:** <https://community.keyboard.io/t/new-plugin-qukeys-yet-another-spacecadet-dualuse-type-plugin/812>\
**Category:** Plugins\
**Tags:** plugin\
**Created:** [November 30, 2017, 6:36pm UTC](https://community.keyboard.io/t/new-plugin-qukeys-yet-another-spacecadet-dualuse-type-plugin/812 "2017-11-30T18:36:42Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [November 30, 2017, 6:36pm UTC](https://community.keyboard.io/t/new-plugin-qukeys-yet-another-spacecadet-dualuse-type-plugin/812/1 "2017-11-30T18:36:42Z")

</div>

Plugin name: **Kaleidoscope-Qukeys**  
Author: _Michael Richters_  
Source URL: [https://github.com/gedankenlab/Kaleidoscope-Qukeys](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](https://github.com/keyboardio/Kaleidoscope-SpaceCadet) and [DualUse](https://github.com/keyboardio/Kaleidoscope-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:

1. 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.
2. The `qukey` is released. In this case, it assumes its primary state (from the regular keymap), sending an extra report to the host.
3. A key pressed _after the `qukey` was pressed_ is released. In this case, the `qukey` 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](https://github.com/keyboardio/Kaleidoscope/pull/255) 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.

---

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [November 30, 2017, 6:40pm UTC](https://community.keyboard.io/t/new-plugin-qukeys-yet-another-spacecadet-dualuse-type-plugin/812/2 "2017-11-30T18:40:27Z")

</div>

If anyone really wants to try it out before Kaleidoscope gets updated to enable the necessary core feature(s), I can try to put together a version of Arduino-Boards that has everything you’ll need.

I mostly wanted to get this out of my head to focus on other things, like writing lots of Kaleidoscope documentation. And maybe sleep.

---

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [November 30, 2017, 6:44pm UTC](https://community.keyboard.io/t/new-plugin-qukeys-yet-another-spacecadet-dualuse-type-plugin/812/3 "2017-11-30T18:44:47Z")

</div>

Oh, and thanks to @algernon and @jesse for helping me understand how everything works well enough to be able to put this together.

---

<div class="post-metadata">

**Author:** ![fishheadsoup](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/fishheadsoup/32/161_2.png) [@fishheadsoup](https://community.keyboard.io/u/fishheadsoup)\
**Post date:** [November 30, 2017, 8:39pm UTC](https://community.keyboard.io/t/new-plugin-qukeys-yet-another-spacecadet-dualuse-type-plugin/812/4 "2017-11-30T20:39:10Z")

</div>

> [@merlin](#):
>
> 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.

Love it, is there a cat involved?

---

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [December 1, 2017, 6:09am UTC](https://community.keyboard.io/t/new-plugin-qukeys-yet-another-spacecadet-dualuse-type-plugin/812/5 "2017-12-01T06:09:37Z")

</div>

> [@Fast typing overlap](https://community.keyboard.io/t/fast-typing-overlap/788/16):
>
> Gave it a quick test and I wasn’t able to see any aberrant behaviour (I usually type around 90WPM, my best on the Model 01 is 104). Seems pretty cool!

@james.nvc (and anyone else interested in giving this a try):

The current head of the master branch of Arduino-Boards (if all the submodules are updated) has everything necessary to build Kaleidoscope-Qukeys now.

Also, I just made a couple of commits that should make it a bit easier to add what’s needed to the sketch: see the [Qukeys.ino](https://github.com/gedankenlab/Kaleidoscope-Qukeys/blob/master/examples/Qukeys/Qukeys.ino) file for examples.

---

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [December 3, 2017, 1:15am UTC](https://community.keyboard.io/t/new-plugin-qukeys-yet-another-spacecadet-dualuse-type-plugin/812/6 "2017-12-03T01:15:46Z")

</div>

If you want to try out Qukeys, but setting it up is difficult, I’d be happy to help. The configuration isn’t as straightforward as DualUse or SpaceCadet, but it’s really designed to do what you want (overloading a symbol key with a modifier) as opposed to SpaceCadet (overloading a modifier key with a symbol).

---

<div class="post-metadata">

**Author:** ![plantarum](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/plantarum/32/695_2.png) [@plantarum](https://community.keyboard.io/u/plantarum)\
**Post date:** [December 3, 2017, 5:00pm UTC](https://community.keyboard.io/t/new-plugin-qukeys-yet-another-spacecadet-dualuse-type-plugin/812/7 "2017-12-03T17:00:39Z")

</div>

Sounds great! I cloned the repo into Arduino/hardware/keyboardio/avr/libraries/, and just added the include line to see if it installed properly. I get the following errors with Make:

```
make
BOARD_HARDWARE_PATH="/home/tws/Arduino/hardware" /home/tws/Arduino/hardware/keyboardio/avr/libraries/Kaleidoscope/bin//kaleidoscope-builder build-all
Building output/Model01-Firmware/Model01-Firmware (0.0.0-gv1.13-60-g8f58-dirty) ...
/home/tws/Arduino/hardware/keyboardio/avr/libraries/Kaleidoscope-Qukeys/src/Kaleidoscope/Qukeys.cpp: In static member function 'static int8_t kaleidoscope::Qukeys::lookupQukey(uint8_t)':
/home/tws/Arduino/hardware/keyboardio/avr/libraries/Kaleidoscope-Qukeys/src/Kaleidoscope/Qukeys.cpp:64:38: error: 'class Layer_' has no member named 'lookupActiveLayer'
           (qukeys_[i].layer == Layer.lookupActiveLayer(row, col))) {
                                      ^
/home/tws/Arduino/hardware/keyboardio/avr/libraries/Kaleidoscope-Qukeys/src/Kaleidoscope/Qukeys.cpp: In static member function 'static void kaleidoscope::Qukeys::flushKey(int8_t, uint8_t)':
/home/tws/Arduino/hardware/keyboardio/avr/libraries/Kaleidoscope-Qukeys/src/Kaleidoscope/Qukeys.cpp:110:39: error: 'class Keyboard_' has no member named 'keyReport'
   memcpy(hid_report.allkeys, Keyboard.keyReport.allkeys, sizeof(hid_report));
                                       ^
/home/tws/Arduino/hardware/keyboardio/avr/libraries/Kaleidoscope-Qukeys/src/Kaleidoscope/Qukeys.cpp:112:19: error: 'class Keyboard_' has no member named 'keyReport'
   memcpy(Keyboard.keyReport.allkeys, Keyboard.lastKeyReport.allkeys, sizeof(Keyboard.keyRepor

```

etc.

What else do I need to do to install it?

---

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [December 3, 2017, 5:02pm UTC](https://community.keyboard.io/t/new-plugin-qukeys-yet-another-spacecadet-dualuse-type-plugin/812/8 "2017-12-03T17:02:50Z")

</div>

You’ll need to update your Arduino-Boards clone. There have been recent changes to Kaleidoscope and KeyboardioHID that are required to build Qukeys.

---

<div class="post-metadata">

**Author:** ![plantarum](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/plantarum/32/695_2.png) [@plantarum](https://community.keyboard.io/u/plantarum)\
**Post date:** [December 3, 2017, 5:29pm UTC](https://community.keyboard.io/t/new-plugin-qukeys-yet-another-spacecadet-dualuse-type-plugin/812/9 "2017-12-03T17:29:14Z")

</div>

I’m not sure what that means. I did this:

```
~/.../keyboardio/avr > git pull

```

This appeared to do what I needed, but the error persisted. Looking at the documentation here:

> **[keyboardio/Arduino-Boards](https://github.com/keyboardio/Arduino-Boards)**
>
> This repository has been retired in favor of https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio - keyboardio/Arduino-Boards

I then tried:

```
~/.../keyboardio/avr > make checkout-submodules
git pull
Already up-to-date.
git submodule update --init --recursive
Submodule 'libraries/Kaleidoscope-NumPad' (https://github.com/Keyboardio/Kaleidoscope-NumPad) registered for path 'libraries/Kaleidoscope-NumPad'
Cloning into '/home/tws/Arduino/hardware/keyboardio/avr/libraries/Kaleidoscope-NumPad'...
Submodule path 'libraries/Kaleidoscope-NumPad': checked out '952198a98af9a19174d9ba1ea73d8515a0f28ebb'

```

I’m still getting the same errors when I try to make with QUkeys included.

---

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [December 3, 2017, 5:36pm UTC](https://community.keyboard.io/t/new-plugin-qukeys-yet-another-spacecadet-dualuse-type-plugin/812/10 "2017-12-03T17:36:39Z")

</div>

Try the command:

```auto
git submodule status

```

You should see the following line in the output:

```auto
 c060c5ef7e76f5bce5524d66921a1179724b260d libraries/Kaleidoscope (shipped-model00-xmas-924-gc060c5e)

```

If it’s showing something different, your Kaleidoscope repo is not up to date.

---

<div class="post-metadata">

**Author:** ![plantarum](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/plantarum/32/695_2.png) [@plantarum](https://community.keyboard.io/u/plantarum)\
**Post date:** [December 3, 2017, 5:41pm UTC](https://community.keyboard.io/t/new-plugin-qukeys-yet-another-spacecadet-dualuse-type-plugin/812/11 "2017-12-03T17:41:58Z")

</div>

This is what I get:

```
67aa56022d5f429000448ca2b4fbaf8cf5d1aef7 libraries/Kaleidoscope (shipped-model00-xmas-881-g67aa560)

```

I have already pulled from the repos, do I need to switch branches or something?

---

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [December 3, 2017, 5:48pm UTC](https://community.keyboard.io/t/new-plugin-qukeys-yet-another-spacecadet-dualuse-type-plugin/812/12 "2017-12-03T17:48:19Z")

</div>

Yeah, that’s quite out of date now.

Try this: in your Arduino-Boards repo:

```auto
git submodule update --remote --init

```

---

<div class="post-metadata">

**Author:** ![plantarum](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/plantarum/32/695_2.png) [@plantarum](https://community.keyboard.io/u/plantarum)\
**Post date:** [December 3, 2017, 5:50pm UTC](https://community.keyboard.io/t/new-plugin-qukeys-yet-another-spacecadet-dualuse-type-plugin/812/13 "2017-12-03T17:50:34Z")

</div>

That did it, thanks!

---

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [December 3, 2017, 5:50pm UTC](https://community.keyboard.io/t/new-plugin-qukeys-yet-another-spacecadet-dualuse-type-plugin/812/14 "2017-12-03T17:50:46Z")

</div>

Oh, maybe you have a particular version of Arduino-Boards checked out. Do this first:

```bash
git checkout master
git pull

```

---

<div class="post-metadata">

**Author:** ![plantarum](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/plantarum/32/695_2.png) [@plantarum](https://community.keyboard.io/u/plantarum)\
**Post date:** [December 3, 2017, 6:10pm UTC](https://community.keyboard.io/t/new-plugin-qukeys-yet-another-spacecadet-dualuse-type-plugin/812/15 "2017-12-03T18:10:22Z")

</div>

Got it working now, thanks!

---

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [December 3, 2017, 6:13pm UTC](https://community.keyboard.io/t/new-plugin-qukeys-yet-another-spacecadet-dualuse-type-plugin/812/16 "2017-12-03T18:13:17Z")

</div>

Excellent! Just in case you cloned Qukeys more than ~an hour ago, I just fixed a bug this morning, so you might want to update.

---

<div class="post-metadata">

**Author:** ![plantarum](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/plantarum/32/695_2.png) [@plantarum](https://community.keyboard.io/u/plantarum)\
**Post date:** [December 4, 2017, 2:00am UTC](https://community.keyboard.io/t/new-plugin-qukeys-yet-another-spacecadet-dualuse-type-plugin/812/17 "2017-12-04T02:00:50Z")

</div>

Ok, moving on from compiling and flashing, I have now set it up to put Shift, Control, Alt, under the middle, ring and pinky finger of home row on each side. This is really cool! It even works for combined modifiers, so I can do hold down l and ;, to get C-A. It’s sort of intuitive too, so I can imagine getting up to speed reasonably quickly.

I’m curious, how are you using your thumb keys? I’ll probably keep dedicated modifer keys on my layout somewhere, but I’m not sure they need to go on the thumbs anymore…

---

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [December 4, 2017, 4:12am UTC](https://community.keyboard.io/t/new-plugin-qukeys-yet-another-spacecadet-dualuse-type-plugin/812/18 "2017-12-04T04:12:19Z")

</div>

Awesome! I’m so happy someone is using my work! Let me know if you have any problems.

As for my keymap… Well, I have _plans_, but I’m hopeless at typing on it so far, and I’ve been enjoying playing with Kaleidoscope so much, that I haven’t done much. I had planned to use the thumb arcs almost the same as in the default keymap, but my own plugin seems to work better than I’d hoped, so I might use them for layer selection. Or stick with modifiers, because I want to try OneShot modifiers, and those can’t really be combined with Qukeys… Well, they _could_, but I can’t think of a scenario where that would actually be _useful_…

I’m holding off trying to really type on a Model01 until I can really get my intended keymap done, because I want it to be totally different than a “normal” keyboard so my brain doesn’t confuse the two and overwrite my QWERTY ability. And I need to write one more plugin (working title: “Unshifter”) in order to get the keymap I want.

---

<div class="post-metadata">

**Author:** ![florentnicoulaud](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/florentnicoulaud/32/724_2.png) [@florentnicoulaud](https://community.keyboard.io/u/florentnicoulaud)\
**Post date:** [December 12, 2017, 5:27pm UTC](https://community.keyboard.io/t/new-plugin-qukeys-yet-another-spacecadet-dualuse-type-plugin/812/19 "2017-12-12T17:27:42Z")

</div>

Hi there,

I’m trying to use your plugin but I can’t get it to compile.  
I’m getting something like that:

```
C:\Users\Z017316\Documents\Arduino\libraries\Kaleidoscope-Qukeys\src\Kaleidoscope\Qukeys.cpp:60:37: error: 'class Layer_' has no member named 'lookupActiveLayer'

           (qukeys[i].layer == Layer.lookupActiveLayer(row, col))) {

                                     ^

```

Any idea ?

Thanks.

---

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [December 12, 2017, 7:08pm UTC](https://community.keyboard.io/t/new-plugin-qukeys-yet-another-spacecadet-dualuse-type-plugin/812/20 "2017-12-12T19:08:57Z")

</div>

Your version of Kaleidoscope is older than the one that Qukeys requires. Did you clone the git repository [Arduino-Boards](https://github.com/keyboardio/Arduino-Boards), or did you use the Arduio GUI boards-manager to install Kaleidoscope?

[Next page](https://community.keyboard.io/t/new-plugin-qukeys-yet-another-spacecadet-dualuse-type-plugin/812.md?page=2)
