From 94db15ad0862fcaade3e94a114c030d9d9abd798 Mon Sep 17 00:00:00 2001 From: Michael Richters Date: Tue, 5 Dec 2017 11:19:35 -0600 Subject: [PATCH] Use a static variable instead of INJECTED keyswitch state We need to prevent infinite loops, and also stop handling keyswitch events when flushing the queue, but if we do this by setting the `INJECTED` bit in `keyswitch_state` when calling `handleKeyswitchEvent()`, then other plugins will ignore those events, which is not what we want; we need them to process those events as if they were real keypresses. The solution is to use a static boolean to let us know if the queue is being flushed. --- src/Kaleidoscope/Qukeys.cpp | 13 ++++++++++--- src/Kaleidoscope/Qukeys.h | 1 + 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Kaleidoscope/Qukeys.cpp b/src/Kaleidoscope/Qukeys.cpp index 311feb93..a48fa752 100644 --- a/src/Kaleidoscope/Qukeys.cpp +++ b/src/Kaleidoscope/Qukeys.cpp @@ -100,6 +100,10 @@ void Qukeys::flushKey(bool qukey_state, uint8_t keyswitch_state) { keycode = Layer.lookup(row, col); } + // Before calling handleKeyswitchEvent() below, make sure Qukeys knows not to handle + // these events: + flushing_queue_ = true; + // Since we're in the middle of the key scan, we don't necessarily // have a full HID report, and we don't want to accidentally turn // off keys that the scan hasn't reached yet, so we force the @@ -114,7 +118,7 @@ void Qukeys::flushKey(bool qukey_state, uint8_t keyswitch_state) { // we can ignore it and don't start an infinite loop. It would be // nice if we could use key_state to also indicate which plugin // injected the key. - handleKeyswitchEvent(keycode, row, col, IS_PRESSED | INJECTED); + handleKeyswitchEvent(keycode, row, col, IS_PRESSED); // Now we send the report (if there were any changes) hid::sendKeyboardReport(); @@ -123,7 +127,10 @@ void Qukeys::flushKey(bool qukey_state, uint8_t keyswitch_state) { // Last, if the key is still down, add its code back in if (! keyToggledOn(keyswitch_state)) - handleKeyswitchEvent(keycode, row, col, IS_PRESSED | WAS_PRESSED | INJECTED); + handleKeyswitchEvent(keycode, row, col, IS_PRESSED | WAS_PRESSED); + + // Now that we're done sending the report(s), Qukeys can process events again: + flushing_queue_ = true; // Shift the queue, so key_queue[0] is always the first key that gets processed for (byte i = 0; i < key_queue_length_; i++) { @@ -163,7 +170,7 @@ Key Qukeys::keyScanHook(Key mapped_key, byte row, byte col, uint8_t key_state) { return mapped_key; // If the key was injected (from the queue being flushed), continue to next plugin - if (key_state & INJECTED) + if (flushing_queue_) return mapped_key; // If the key isn't active, and didn't just toggle off, continue to next plugin diff --git a/src/Kaleidoscope/Qukeys.h b/src/Kaleidoscope/Qukeys.h index 5a8d9989..2e920e69 100644 --- a/src/Kaleidoscope/Qukeys.h +++ b/src/Kaleidoscope/Qukeys.h @@ -92,6 +92,7 @@ class Qukeys : public KaleidoscopePlugin { static uint16_t time_limit_; static QueueItem key_queue_[QUKEYS_QUEUE_MAX]; static uint8_t key_queue_length_; + static bool flushing_queue_; // Qukey state bitfield static uint8_t qukey_state_[(TOTAL_KEYS) / 8 + ((TOTAL_KEYS) % 8 ? 1 : 0)];