diff --git a/docs/plugins/Qukeys.md b/docs/plugins/Qukeys.md index 7ff1347d..8b32358b 100644 --- a/docs/plugins/Qukeys.md +++ b/docs/plugins/Qukeys.md @@ -97,6 +97,17 @@ likely to generate errors and out-of-order events. > > Defaults to `80`. +### `.setMinimumHoldTime(min_hold_time)` + +> Sets the minimum amount of time (in milliseconds) a qukey must be held before +> it is allowed to resolve to its alternate `Key` value. Use this if you find +> that you're getting unintended alternate values (i.e. modifiers) while typing +> on home-row qukeys, despite setting the overlap threshold (see above) to +> 100%. It may mean that you'll need to slow down when using Qukeys to get +> modifiers, however. +> +> Defaults to `50` (milliseconds). + ### `.activate()` ### `.deactivate()` ### `.toggle()` diff --git a/examples/Keystrokes/Qukeys/Qukeys.ino b/examples/Keystrokes/Qukeys/Qukeys.ino index c3cdb777..030aff66 100644 --- a/examples/Keystrokes/Qukeys/Qukeys.ino +++ b/examples/Keystrokes/Qukeys/Qukeys.ino @@ -72,6 +72,7 @@ void setup() { ) Qukeys.setHoldTimeout(1000); Qukeys.setOverlapThreshold(50); + Qukeys.setMinimumHoldTime(100); Kaleidoscope.setup(); } diff --git a/src/kaleidoscope/plugin/Qukeys.cpp b/src/kaleidoscope/plugin/Qukeys.cpp index d823a517..ffa9df41 100644 --- a/src/kaleidoscope/plugin/Qukeys.cpp +++ b/src/kaleidoscope/plugin/Qukeys.cpp @@ -239,8 +239,14 @@ bool Qukeys::processQueue() { // not a key press, there must be one in the queue, so it shouldn't be // necessary to confirm that `j` is a actually a key press. if (event_queue_.addr(j) == event_queue_.addr(i)) { - flushEvent(queue_head_.alternate_key); - return true; + // Next, verify that enough time has passed after the qukey was pressed + // to make it eligible for its alternate value. This helps faster + // typists avoid unintended modifiers in the output. + if (Runtime.hasTimeExpired(event_queue_.timestamp(0), + minimum_hold_time_)) { + flushEvent(queue_head_.alternate_key); + return true; + } } } } diff --git a/src/kaleidoscope/plugin/Qukeys.h b/src/kaleidoscope/plugin/Qukeys.h index 55761c1e..4ed92fb6 100644 --- a/src/kaleidoscope/plugin/Qukeys.h +++ b/src/kaleidoscope/plugin/Qukeys.h @@ -120,6 +120,13 @@ class Qukeys : public kaleidoscope::Plugin { } } + // Set the minimum length of time a qukey must be held before it can resolve + // to its alternate key value. If a qukey is pressed and released in less than + // this number of milliseconds, it will always produce its primary key value. + void setMinimumHoldTime(uint8_t min_hold_time) { + minimum_hold_time_ = min_hold_time; + } + // Function for defining the array of qukeys data (in PROGMEM). It's a // template function that takes as its sole argument an array reference of // size `_qukeys_count`, so there's no need to use `sizeof` to calculate the @@ -175,6 +182,11 @@ class Qukeys : public kaleidoscope::Plugin { // alternate state (or primary state, in the case of a SpaceCadet-type qukey). uint16_t hold_timeout_{250}; + // The minimum number of milliseconds a qukey must be held before it is + // allowed to take on its alternate key value (to limit unintended modifiers + // for very fast typists). + uint8_t minimum_hold_time_{50}; + // This is a guard against re-processing events when qukeys flushes them from // its event queue. We can't just use an "injected" key state flag, because // that would cause other plugins to also ignore the event.