Qukeys rewrite (may fix rollover issues)

(Michael Richters) #1

For people who are still having difficulty using Qukeys to add modifiers to home row keys (or other keys that are primarily used for printable characters), I have rewritten Qukeys completely, with a new rollover grace period algorithm. Right now, it can be found as a draft pull request against Kaleidoscope (#640).

In order to use it, you may want to make two changes to your sketch. First, if you define any Qukey objects (rather than just using the DualUse-style definitions in the keymap), you may want to change the constructor from this one:

Qukey(layer, row, col, alternate_key);

…to this new one:

Qukey(layer, KeyAddr(row, col), alternate_key);

…in order to suppress some deprecation warnings.

In addition, the setTimeout() function has also been deprecated, in favor of setHoldTimeout(), which is functionally equivalent.

Most important is that the rollover grace period works in a completely new way, and has a different method of controlling its settings. The old way was to set a fixed amount of time in milliseconds as a “release delay”. After a qukey was released, if there was a subsequent key press, Qukeys would wait that period of time for the subsequent key to be released before determining the state that the qukey would end up in. So you could do the following:

  1. Press qukey Q (a / shift) – (@ time = t1 )
  2. Press X(@ time = t2 )
  3. Release Q(@ time = t3 )
  4. Release X(@ time = t4 )

If the release delay was set to 20ms (Qukeys.setReleaseDelay(20)), and less than 20ms elapsed between events #3 and #4 ( t4 - t3 > 20ms ), the qukey would become shift instead of a. This helped, but was clearly not good enough.

The new system records both the press and release times of the keys, and uses a percentage as a threshold, by calling Qukeys.setOverlapThreshold(pct), where pct is a number between 1 (1%) and 100 (100%). Using the above example, it compares the duration of the subsequent key’s press ( Tx = t4 - t2 ) to the duration of the overlap ( Tr = t4 - t3 ). Suppose we set the threshold to 80%. If Tr is more than 80% of Tx (because X was released soon after Q), the qukey will become a. If Tr is less than 80% of Tx (because X was held longer), the qukey will become shift.

This new algorithm automatically adjusts to different typing speeds, so it should do much better than the old one. When testing it out, I was surprised at how low I could set the percentage and still reliably get the output I intended without triggering unwanted modifiers. Whereas I used to caution against setting the old release delay too high (above ~20ms), the new overlap threshold parameter might work well at values as low as 50%.