From e3f1172244928efc12ebce1ceeb6b378ed8221d5 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 7 Aug 2017 11:52:44 +0200 Subject: [PATCH] Changed how key caching & lookup works This changes how key caching & lookup works: instead of updating the whole key cache whenever we change the layer state, we update each key before they are pressed or released. This allows us to have two different ways in which layers can work: - Keys still held when releasing the layer key will be masked out until they are released. (This is the current behaviour) - Keys held will repeat the keycode they had when they toggled on, even if the layer key gets released prior to this other key, while other keys will not be affected. One can toggle between the two modes by setting `Kaleidoscope.repeat_first_press` to `true` (second behaviour) or `false` (first behaviour). For now, the default behaviour is left unchanged. Signed-off-by: Gergely Nagy --- src/key_events.cpp | 9 ++++++--- src/layers.cpp | 33 +++++++++++---------------------- src/layers.h | 6 ++++-- 3 files changed, 21 insertions(+), 27 deletions(-) diff --git a/src/key_events.cpp b/src/key_events.cpp index f17ef1a4..cfa04099 100644 --- a/src/key_events.cpp +++ b/src/key_events.cpp @@ -44,9 +44,8 @@ static bool handleKeyswitchEventDefault(Key mappedKey, byte row, byte col, uint8 } void handleKeyswitchEvent(Key mappedKey, byte row, byte col, uint8_t keyState) { - if (!(keyState & INJECTED)) { - mappedKey = Layer.lookup(row, col); - } + if (keyToggledOn(keyState) || keyToggledOff(keyState)) + Layer.updateKeyCache(row, col); /* If the key we are dealing with is masked, ignore it until it is released. * When releasing it, clear the mask, so future key events can be handled @@ -63,6 +62,10 @@ void handleKeyswitchEvent(Key mappedKey, byte row, byte col, uint8_t keyState) { } } + if (!(keyState & INJECTED)) { + mappedKey = Layer.lookup(row, col); + } + for (byte i = 0; Kaleidoscope.eventHandlers[i] != NULL && i < HOOK_MAX; i++) { Kaleidoscope_::eventHandlerHook handler = Kaleidoscope.eventHandlers[i]; mappedKey = (*handler)(mappedKey, row, col, keyState); diff --git a/src/layers.cpp b/src/layers.cpp index 340936c4..d0622118 100644 --- a/src/layers.cpp +++ b/src/layers.cpp @@ -6,6 +6,7 @@ static uint32_t LayerState; uint8_t Layer_::highestLayer; uint8_t Layer_::keyMap[ROWS][COLS]; Key(*Layer_::getKey)(uint8_t layer, byte row, byte col) = Layer.getKeyFromPROGMEM; +bool Layer_::repeat_first_press = false; static void handleKeymapKeyswitchEvent(Key keymapEntry, uint8_t keyState) { if (keymapEntry.keyCode >= MOMENTARY_OFFSET) { @@ -44,7 +45,8 @@ static void handleKeymapKeyswitchEvent(Key keymapEntry, uint8_t keyState) { * ignore held keys after releasing a layer key, until they are pressed * again, to avoid the aforementioned issue. */ - KeyboardHardware.maskHeldKeys(); + if (!Layer.repeat_first_press) + KeyboardHardware.maskHeldKeys(); } // switch keymap and stay there @@ -79,27 +81,16 @@ Layer_::getKeyFromPROGMEM(uint8_t layer, byte row, byte col) { } void -Layer_::mergeLayers(void) { +Layer_::updateKeyCache(byte row, byte col) { + int8_t layer = highestLayer; - memset(keyMap, DefaultLayer, ROWS * COLS); + for (layer = highestLayer; layer >= DefaultLayer; layer--) { + if (Layer.isOn(layer)) { + Key mappedKey = (*getKey)(layer, row, col); - if (LayerState == (uint32_t)(1 << DefaultLayer)) - return; - - for (uint8_t r = 0; r < ROWS; r++) { - for (uint8_t c = 0; c < COLS; c++) { - int8_t layer = highestLayer; - - while (layer > DefaultLayer) { - if (Layer.isOn(layer)) { - Key mappedKey = (*getKey)(layer, r, c); - - if (mappedKey != Key_Transparent) { - keyMap[r][c] = layer; - break; - } - } - layer--; + if (mappedKey != Key_Transparent) { + keyMap[row][col] = layer; + break; } } } @@ -128,14 +119,12 @@ void Layer_::on(uint8_t layer) { bitSet(LayerState, layer); if (layer > highestLayer) highestLayer = layer; - mergeLayers(); } void Layer_::off(uint8_t layer) { bitClear(LayerState, layer); if (layer == highestLayer) highestLayer = top(); - mergeLayers(); } boolean Layer_::isOn(uint8_t layer) { diff --git a/src/layers.h b/src/layers.h index 91225dd7..06eb7e75 100644 --- a/src/layers.h +++ b/src/layers.h @@ -30,11 +30,13 @@ class Layer_ { static Key getKeyFromPROGMEM(uint8_t layer, byte row, byte col); + static void updateKeyCache(byte row, byte col); + + static bool repeat_first_press; + private: static uint8_t highestLayer; static uint8_t keyMap[ROWS][COLS]; - - static void mergeLayers(void); }; Key layer_getKey(uint8_t layer, uint8_t r, uint8_t c);