From 8d4967db8d93854b4c21f3203d2853980734e039 Mon Sep 17 00:00:00 2001 From: Michael Richters Date: Sat, 10 Apr 2021 14:32:04 -0500 Subject: [PATCH] Adapt Leader plugin to KeyEvent handlers Signed-off-by: Michael Richters --- plugins/Kaleidoscope-Leader/README.md | 3 - .../src/kaleidoscope/plugin/Leader.cpp | 61 ++++++++----------- .../src/kaleidoscope/plugin/Leader.h | 6 +- 3 files changed, 30 insertions(+), 40 deletions(-) diff --git a/plugins/Kaleidoscope-Leader/README.md b/plugins/Kaleidoscope-Leader/README.md index 0643ae3e..c79cefa5 100644 --- a/plugins/Kaleidoscope-Leader/README.md +++ b/plugins/Kaleidoscope-Leader/README.md @@ -58,9 +58,6 @@ The dictionary is made up of a list of keys, and an action callback. Using the `LEADER_DICT` and `LEADER_SEQ` helpers is recommended. The dictionary *must* be marked `PROGMEM`! -**Note** that we need to use the `Leader` object before any other that adds or -changes key behaviour! Failing to do so may result in unpredictable behaviour. - ## Plugin methods The plugin provides the `Leader` object, with the following methods and properties: diff --git a/plugins/Kaleidoscope-Leader/src/kaleidoscope/plugin/Leader.cpp b/plugins/Kaleidoscope-Leader/src/kaleidoscope/plugin/Leader.cpp index 4c832f15..edad67b5 100644 --- a/plugins/Kaleidoscope-Leader/src/kaleidoscope/plugin/Leader.cpp +++ b/plugins/Kaleidoscope-Leader/src/kaleidoscope/plugin/Leader.cpp @@ -20,12 +20,14 @@ #include "kaleidoscope/keyswitch_state.h" #include "kaleidoscope/keyswitch_state.h" #include "kaleidoscope/key_events.h" +#include "kaleidoscope/KeyEventTracker.h" namespace kaleidoscope { namespace plugin { // --- state --- Key Leader::sequence_[LEADER_MAX_SEQUENCE_LENGTH + 1]; +KeyEventTracker Leader::event_tracker_; uint8_t Leader::sequence_pos_; uint16_t Leader::start_time_ = 0; uint16_t Leader::time_out = 1000; @@ -81,8 +83,9 @@ void Leader::reset(void) { sequence_[0] = Key_NoKey; } +// DEPRECATED void Leader::inject(Key key, uint8_t key_state) { - onKeyswitchEvent(key, UnknownKeyswitchLocation, key_state); + Runtime.handleKeyEvent(KeyEvent(KeyAddr::none(), key_state | INJECTED, key)); } // --- hooks --- @@ -90,61 +93,49 @@ EventHandlerResult Leader::onNameQuery() { return ::Focus.sendName(F("Leader")); } -EventHandlerResult Leader::onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t keyState) { - if (keyState & INJECTED) +EventHandlerResult Leader::onKeyswitchEvent(KeyEvent &event) { + // If the plugin has already processed and released this event, ignore it. + // There's no need to update the event tracker explicitly. + if (event_tracker_.shouldIgnore(event)) return EventHandlerResult::OK; - if (!isActive() && !isLeader(mapped_key)) + if (keyToggledOff(event.state) || event.state & INJECTED) return EventHandlerResult::OK; if (!isActive()) { - // Must be a leader key! - - if (keyToggledOff(keyState)) { - // not active, but a leader key = start the sequence on key release! - start_time_ = Runtime.millisAtCycleStart(); - sequence_pos_ = 0; - sequence_[sequence_pos_] = mapped_key; - } - - // If the sequence was not active yet, ignore the key. - return EventHandlerResult::EVENT_CONSUMED; - } - - // active - int8_t action_index = lookup(); - - if (keyToggledOn(keyState)) { - sequence_pos_++; - if (sequence_pos_ > LEADER_MAX_SEQUENCE_LENGTH) { - reset(); + if (!isLeader(event.key)) return EventHandlerResult::OK; - } start_time_ = Runtime.millisAtCycleStart(); - sequence_[sequence_pos_] = mapped_key; - action_index = lookup(); + sequence_pos_ = 0; + sequence_[sequence_pos_] = event.key; - if (action_index >= 0) { - return EventHandlerResult::EVENT_CONSUMED; - } - } else if (keyIsPressed(keyState)) { - // held, no need for anything here. - return EventHandlerResult::EVENT_CONSUMED; + return EventHandlerResult::ABORT; } + ++sequence_pos_; + if (sequence_pos_ > LEADER_MAX_SEQUENCE_LENGTH) { + reset(); + return EventHandlerResult::OK; + } + + start_time_ = Runtime.millisAtCycleStart(); + sequence_[sequence_pos_] = event.key; + int8_t action_index = lookup(); + if (action_index == NO_MATCH) { reset(); return EventHandlerResult::OK; } if (action_index == PARTIAL_MATCH) { - return EventHandlerResult::EVENT_CONSUMED; + return EventHandlerResult::ABORT; } action_t leaderAction = (action_t) pgm_read_ptr((void const **) & (dictionary[action_index].action)); (*leaderAction)(action_index); + reset(); - return EventHandlerResult::EVENT_CONSUMED; + return EventHandlerResult::ABORT; } EventHandlerResult Leader::afterEachCycle() { diff --git a/plugins/Kaleidoscope-Leader/src/kaleidoscope/plugin/Leader.h b/plugins/Kaleidoscope-Leader/src/kaleidoscope/plugin/Leader.h index fd0dd928..f84b4752 100644 --- a/plugins/Kaleidoscope-Leader/src/kaleidoscope/plugin/Leader.h +++ b/plugins/Kaleidoscope-Leader/src/kaleidoscope/plugin/Leader.h @@ -17,8 +17,9 @@ #pragma once -#include "kaleidoscope/Runtime.h" #include +#include "kaleidoscope/KeyEventTracker.h" +#include "kaleidoscope/plugin.h" #define LEADER_MAX_SEQUENCE_LENGTH 4 @@ -47,11 +48,12 @@ class Leader : public kaleidoscope::Plugin { void inject(Key key, uint8_t key_state); EventHandlerResult onNameQuery(); - EventHandlerResult onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t keyState); + EventHandlerResult onKeyswitchEvent(KeyEvent &event); EventHandlerResult afterEachCycle(); private: static Key sequence_[LEADER_MAX_SEQUENCE_LENGTH + 1]; + static KeyEventTracker event_tracker_; static uint8_t sequence_pos_; static uint16_t start_time_;