Unexpected characters using Qukeys

(Michael Richters) #4

You definitely shouldn’t be seeing that behaviour. I’ll look into it today. If you can share your sketch, that would help. I also recommend reporting the issue on GitHub, if you’ve got an account there.

(Michael Richters) #5

Did you update to Kaleidoscope-Bundle-Keyboardio’s master branch, or to Kaleidoscope’s master branch? There are some big changes in the latter than have not been updated in the former yet.

That said, I have so far been unsuccessful at reproducing this bug in either case. I’m probably going to need more information in order to sort this one out.

(Michael Richters) #6

I’m speculating that this is being caused by interaction with another plugin, possibly due to suboptimal plugin hook ordering.

(Ian Potter) #7
(Michael Richters) #8

Thanks. I can reproduce the problem now, and I know what’s going on (but not yet all the details). It’s not that Qukeys is sending both the modifier and the parenthesis character – the problem is rollover from a mod-flagged key (LSHIFT(Key_0)) to a normal key (Key_Q). So, Qukeys is doing what it ought to, but Kaleidoscope isn’t suppressing the shift modifier flag when the Q is pressed. This also happens when rolling over from one of the curly-brace keys on the FUNCTION layer to any other key.

I thought we had fixed this problem several months ago, but perhaps recent changes have brought it back. :confused:

(Michael Richters) #9

One recommendation, regarding Qukeys – it’s best to put it first in KALEIDOSCOPE_INIT_PLUGINS() (though that is not the source of the problem you were seeing.

(Michael Richters) #10

This won’t fix the bug, but if you’re in the habit of (nearly) simultaneously releasing the modifier key and the modified key, you should probably set the Qukeys release delay to some non-zero value, like so:


That specifies a 20ms “grace period” window after a Qukey is released. If a subsequently-pressed key is released within that window, Qukeys will interpret that as the user intending to get the alternate (i.e. modifier) keycode. The danger is that you might get the alternate keycode when you intended to get the primary one when typing fast, so I wouldn’t recommend setting it to anything higher than ~25ms (and even that is probably pushing it).

1 Like
(Ian Potter) #11

I made the recommended changes just for good hygiene’s sake, and as you said the issue persists. One thing I’m noticing that I can’t explain is when I’m in the MACOS layer and hit Cmd+A (where Cmd is a Qukey mapped to {), I’ll sometimes get “{A” when it doesn’t select all. I don’t quite understand why the A is capitalized, since I’m not involving a shift key.

(Michael Richters) #12

When you release the qukey first, it becomes {, which is generated by shift + [. While that key is still in effect, including the shift, the A keycode is sent, so the host produces a capital letter A. The fact that you were getting capital letters with the (/shift qukey was coincidental — the shift came from the (, not the qukey’s alternate value.

I’m having a hard time figuring out a way to fix the bug that you’ve uncovered (short of a wholesale rewrite of Kaleidoscope…), but assuming I can, what Qukeys would be producing in these cases is still not what you intend. Rather than {A, you would get {a; you would not be getting cmd + A, because Qukeys determines the value of the key based on the order in which the keys are released.

You can try bigger values for Qukeys.setReleaseDelay() — the maximum is 255ms — but you might find that you then get unintended alternate keycodes (i.e. modifiers), which is generally more dangerous than unintended primary keycodes. This is a fundamental limit of this type of dual-purpose key; in order to produce reliable output, it needs clear inputs. Sadly, for people who regularly roll over from modifiers, rather than holding them until after the modified key is released, Qukeys may not be able to give them the functionality they want.

(Michael Richters) #13

@pian0 – I’ve submitted a PR that should fix the bug (with the caveat that it will most likely not fix the problem that you’re having):

[Edit: That PR has now been merged into the master branch of Kaleidoscope.]

(Ian Potter) #14

I’m trying to get my environment set up to build with the fix, but I’m a little confused with which repos do what. After not seeing any changes in the remote repository I already had, I cloned the Kaleidoscope-Bundle-Keyboardio and Kaleidoscope bundles and symlinked them into my Arduino/hardware/keyboardio directory. If I do make flash from inside my Model01-Firmware folder, will those get picked up?

(Michael Richters) #15

You should just clone the Kaleidoscope-Bundle-Keyboardio repository (recursively), and set it up so that Arduino can find it. One of that repository’s submodules is Kaleidoscope (in avr/libraries/Kaleidoscope). Within that directory, a git checkout master will bring it up to date.

1 Like
(Ian Potter) #16

I got the latest and the bug where the shift modifier would carry over is fixed, but as you said, rolling over modifiers still produces undesirable results. I think I only switched to Qukeys in the past because I thought SpaceCadet was dead, but I think I got confused by its repo being archived and I hadn’t figured out how to navigate the merged repo. I found the new SpaceCadet home though and I’m back in business! Based on the Qukeys description, it sounds like it’s designed to prioritize the tap where SpaceCadet prioritizes holding the key.

Thank you very much for your help!

(Michael Richters) #17

You are exactly correct about the difference between SpaceCadet and Qukeys. SpaceCadet is for adding a secondary function to modifier keys, and Qukeys is for adding a secondary function to other keys (e.g. home row keys). Qukeys can be used where you would use SpaceCadet, but depending on one’s typing habits, it might be unsuitable. (SpaceCadet, on the other hand, would be a total disaster on the home row for touch-typists.)

I think someone asked a long time ago if the release delay could be configured with different values based on the key. I didn’t think that would really be worthwhile, but now I can see a clear use for it — keys that are meant to serve primarily as modifiers should have a very long release delay, or even better, I could treat the maximum value as special, and have qukeys immediately enter their alternate state when rolling over to another key. Maybe even better, the release delay could get longer the longer a qukey is held…

This conversation has given me some interesting ideas — thanks!

1 Like

I run into the rollover problem with Qukeys pretty constantly. I use the thumb clusters for SpaceCadet-like behavior. I can’t use SpaceCadet itself, because it doesn’t allow me to use the modifiers and the tap behavior in a single chord (e.g., I have “Ctrl-]” set to my tmux prefix key, which requires holding left-control and tapping right-control at the same time).

The behavior is consistent: I always get the tapped version of the key, followed by the modified version of the subsequent character.



    (Key_Escape,      Key_1,         Key_2,       Key_3,      Key_4, Key_5, Key_LEDEffectNext,
     Key_Backtick,    Key_Quote,     Key_Comma,   Key_Period, Key_P, Key_Y, Key_Tab,
     Key_PageUp,      Key_A,         Key_O,       Key_E,      Key_U, Key_I,
     Key_PageDown,    Key_Semicolon, Key_Q,       Key_J,      Key_K, Key_X, Key_LeftGui,
     Key_LeftBracket, Key_Backspace, LSHIFT(Key_LeftBracket), LSHIFT(Key_9),

     LockLayer(EMOTES), Key_6, Key_7, Key_8, Key_9, Key_0, LockLayer(NUMPAD),
     Key_Enter,         Key_F, Key_G, Key_C, Key_R, Key_L, Key_Slash,
                        Key_D, Key_H, Key_T, Key_N, Key_S, Key_Minus,
     SYSTER,            Key_B, Key_M, Key_W, Key_V, Key_Z, Key_Equals,
     LSHIFT(Key_0), LSHIFT(Key_RightBracket), Key_Spacebar, Key_RightBracket,

Qukeys setup:

  QUKEYS(kaleidoscope::plugin::Qukey(0, 3, 7, Key_LeftShift),
         kaleidoscope::plugin::Qukey(0, 3, 8, Key_RightShift),
         kaleidoscope::plugin::Qukey(0, 0, 7, Key_LeftControl),
         kaleidoscope::plugin::Qukey(0, 0, 8, Key_RightControl),
         kaleidoscope::plugin::Qukey(0, 2, 7, Key_LeftAlt),
         kaleidoscope::plugin::Qukey(0, 2, 8, Key_RightAlt),
         kaleidoscope::plugin::Qukey(0, 2, 9, Key_RightGui));

Given the above, it is frequently the case that when I type a capital letter I, I’ll get the key sequence “)I”. IOW, the tapped right shift, plus the shifted letter I.

It seems like the easiest course of events would be that, for certain keys, if a modifier is being held and any key is pressed down while that key is held, Qukeys will always act like the key is held rather than tapped. I can see this being a problem for people who use Qukeys on the home row, and primarily roll over when typing quickly, but I’d rather not have to deal with heuristic timings which you seem to be working towards in your other recent post; I know how I want these keys to act, so I’d rather just set a flag on the Qukey definition that says “rollover is/isn’t wanted here”.

(Michael Richters) #19

I’ve got an idea for that in the works, too. If you’re interested, read the section titled “A related problem” in my latest post in that topic.


Sigh. Even though I read that post at least three times, apparently my brain didn’t register that section properly. That does sound exactly like what I want.

(Michael Richters) #21

The fault is entirely mine.

Je n’ai fait celle-ci plus longue que parce que je n’ai pas eu le loisir de la faire plus courte.” –Blaise Pascal

(Michael Richters) #22

Just in case this isn’t clear, the reason you’ve been getting a shifted I is due to a bug that just got fixed. The shift was coming from the ), not from the alternate keycode of the qukey. If you update to the current master, you should see the difference — but, alas, it won’t solve your real problem. My long-term plan should be the best way to deal with that, but in the short term, you could try setting the Qukeys release delay much higher. 100ms would probably do the trick. I would only recommend that for someone who’s using Qukeys exclusively like SpaceCadet (adding a secondary “tap” behaviour to a modifier).


It did do the trick. Thanks.

1 Like