From 7722673a8c813dce977928823c73aa58545abd5c Mon Sep 17 00:00:00 2001 From: Marco Herrn Date: Tue, 4 Apr 2023 23:36:14 +0200 Subject: [PATCH] Make autoshift longpress configurable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit allows specifying the keys to produce on long press if not a shifted, but a totally different character is wanted. Such an explicit mapping takes precedence over shifting the key. That means if all alpanumeric characters are configured for AutoShift, but the ‘e’ key has an explicit mapping to produce ‘ë’, a long press on ‘e’ will result in ’ë’, not ‘E’. Signed-off-by: Marco Herrn --- .../src/kaleidoscope/plugin/AutoShift.cpp | 40 +++++++++++++++++-- .../src/kaleidoscope/plugin/AutoShift.h | 35 ++++++++++++++++ 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/plugins/Kaleidoscope-AutoShift/src/kaleidoscope/plugin/AutoShift.cpp b/plugins/Kaleidoscope-AutoShift/src/kaleidoscope/plugin/AutoShift.cpp index 2427828545..67c6b2c044 100644 --- a/plugins/Kaleidoscope-AutoShift/src/kaleidoscope/plugin/AutoShift.cpp +++ b/plugins/Kaleidoscope-AutoShift/src/kaleidoscope/plugin/AutoShift.cpp @@ -23,6 +23,7 @@ #include "kaleidoscope/Runtime.h" // for Runtime, Runtime_ #include "kaleidoscope/key_defs.h" // for Key, Key_0, Key_1, Key_A, Key_F1, Key_F12, Key... #include "kaleidoscope/keyswitch_state.h" // for keyToggledOn, keyIsInjected +#include "kaleidoscope/progmem_helpers.h" // for cloneFromProgmem // IWYU pragma: no_include "HIDAliases.h" @@ -57,6 +58,11 @@ bool AutoShift::enabledForKey(Key key) { if (!key.isKeyboardKey()) return false; + // Check whether we have an explicit mapping for that key + if (isExplicitlyMapped(key)) { + return true; + } + // We compare only the keycode, and disregard any modifier flags applied to // the key. This simplifies the comparison, and also allows AutoShift to // apply to keys like `RALT(Key_E)`. @@ -93,6 +99,19 @@ bool AutoShift::enabledForKey(Key key) { return false; } +bool AutoShift::isExplicitlyMapped(Key key) { + // Check whether the given key has an explicit mapping to a different one + for (uint8_t i{0}; i < explicitmappings_count_; ++i) { + LongPress mappedKey = cloneFromProgmem(explicitmappings_[i]); + if (mappedKey.key == key) { + return true; + } + } + + // If no matches were found, return false + return false; +} + // ============================================================================= // Event handler hook functions @@ -188,9 +207,24 @@ void AutoShift::flushEvent(bool is_long_press) { KeyEvent event = queue_.event(0); if (is_long_press) { event.key = Runtime.lookupKey(event.addr); - uint8_t flags = event.key.getFlags(); - flags ^= SHIFT_HELD; - event.key.setFlags(flags); + + // If we have an explicit mapping for that key, apply that. + bool mapped= false; + for (uint8_t i{0}; i < explicitmappings_count_; ++i) { + LongPress mappedKey = cloneFromProgmem(explicitmappings_[i]); + if (mappedKey.key == event.key) { + event.key = mappedKey.alternate_key; + mapped= true; + } + } + + // If there was no explicit mapping, just add the shift modifier + if (!mapped) { + // event.key = longpresses[event.key] + uint8_t flags = event.key.getFlags(); + flags ^= SHIFT_HELD; + event.key.setFlags(flags); + } } queue_.shift(); Runtime.handleKeyswitchEvent(event); diff --git a/plugins/Kaleidoscope-AutoShift/src/kaleidoscope/plugin/AutoShift.h b/plugins/Kaleidoscope-AutoShift/src/kaleidoscope/plugin/AutoShift.h index 38d7c87911..1b4e53fde1 100644 --- a/plugins/Kaleidoscope-AutoShift/src/kaleidoscope/plugin/AutoShift.h +++ b/plugins/Kaleidoscope-AutoShift/src/kaleidoscope/plugin/AutoShift.h @@ -29,6 +29,22 @@ namespace kaleidoscope { namespace plugin { +struct LongPress { + // The key that should result in a different value on long press. + Key key; + // The alternate Key value that should be produced on long press. + Key alternate_key; + + // This is the constructor that should be used when creating a LongPress object in + // the PROGMEM array that will be used by explicit mappings (i.e. in the `AUTOSHIFT()` + // macro). + constexpr LongPress(Key key, Key alternate_key) + : key(key), alternate_key(alternate_key) {} + // This constructor is here so that we can create an empty LongPress object in RAM + // into which we can copy the values from a PROGMEM LongPress object. + LongPress() = default; +}; + // ============================================================================= /// Kaleidoscope plugin for long-press auto-shift keys /// @@ -232,6 +248,12 @@ class AutoShift : public Plugin { EventHandlerResult onKeyswitchEvent(KeyEvent &event); EventHandlerResult afterEachCycle(); + template + void configureLongPresses(LongPress const (&explicitmappings)[_explicitmappings_count]) { + explicitmappings_ = explicitmappings; + explicitmappings_count_ = _explicitmappings_count; + } + private: // --------------------------------------------------------------------------- /// A container for AutoShift configuration settings @@ -268,6 +290,12 @@ class AutoShift : public Plugin { /// The default function for `isAutoShiftable()` bool enabledForKey(Key key); + + bool isExplicitlyMapped(Key key); + + // An array of LongPress objects in PROGMEM. + LongPress const *explicitmappings_{nullptr}; + uint8_t explicitmappings_count_{0}; }; // ============================================================================= @@ -288,3 +316,10 @@ class AutoShiftConfig : public Plugin { extern kaleidoscope::plugin::AutoShift AutoShift; extern kaleidoscope::plugin::AutoShiftConfig AutoShiftConfig; + +#define AUTOSHIFT(longpress_defs...) \ + { \ + static kaleidoscope::plugin::LongPress const qk_table[] PROGMEM = { \ + longpress_defs}; \ + AutoShift.configureLongPresses(qk_table); \ + }