From 1dc57e7ea6b308bee81a5a78aea40bad6ec697b1 Mon Sep 17 00:00:00 2001 From: Garretonzo Date: Sun, 8 Jun 2025 11:13:16 -0700 Subject: [PATCH] feature to update keycode on press and read keycode on release using map cache --- docs/config_options.md | 2 ++ quantum/action_layer.c | 41 ++++++++++++++++++++++++++++++++++++++++- quantum/action_layer.h | 5 +++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/docs/config_options.md b/docs/config_options.md index b2a2117693d..7c456702e1d 100644 --- a/docs/config_options.md +++ b/docs/config_options.md @@ -142,6 +142,8 @@ If you define these options you will enable the associated feature, which may in * Enables the `QK_MAKE` keycode * `#define STRICT_LAYER_RELEASE` * force a key release to be evaluated using the current layer stack instead of remembering which layer it came from (used for advanced cases) +* `#define KEYCODE_CACHE_ENABLE` + * Cache keycode for pressed keys, to be used on key release, across entire physical keyboard layout. ## Behaviors That Can Be Configured diff --git a/quantum/action_layer.c b/quantum/action_layer.c index 5828dcb8240..e692150bfd6 100644 --- a/quantum/action_layer.c +++ b/quantum/action_layer.c @@ -306,6 +306,32 @@ uint8_t read_source_layers_cache(keypos_t key) { # endif // ENCODER_MAP_ENABLE return 0; } + +# ifdef KEYCODE_CACHE_ENABLE +static uint16_t keycode_map[MATRIX_ROWS][MATRIX_COLS] = {{KC_NO}}; + +/** \brief update keycode map + * + * Updates map of keycodes when a key is pressed down + */ +void update_keycode_map(keypos_t key, uint16_t keycode) { + if (key.row < MATRIX_ROWS && key.col < MATRIX_COLS) { + keycode_map[key.row][key.col] = keycode; + } +} + +/** \brief read keycode map + * + * reads from map of keycodes when a key is released + */ +uint16_t read_keycode_map(keypos_t key) { + if (key.row < MATRIX_ROWS && key.col < MATRIX_COLS) { + return keycode_map[key.row][key.col]; + } + return KC_NO; +} +# endif + #endif /** \brief Store or get action (FIXME: Needs better summary) @@ -322,14 +348,27 @@ action_t store_or_get_action(bool pressed, keypos_t key) { } uint8_t layer; - +# ifdef KEYCODE_CACHE_ENABLE + uint16_t keycode; +# endif if (pressed) { layer = layer_switch_get_layer(key); update_source_layers_cache(key, layer); +# ifdef KEYCODE_CACHE_ENABLE + keycode = keymap_key_to_keycode(layer, key); + update_keycode_map(key, keycode); +# endif } else { layer = read_source_layers_cache(key); +# ifdef KEYCODE_CACHE_ENABLE + keycode = read_keycode_map(key); +# endif } +# ifndef KEYCODE_CACHE_ENABLE return action_for_key(layer, key); +# else + return action_for_keycode(keycode); +# endif #else return layer_switch_get_action(key); #endif diff --git a/quantum/action_layer.h b/quantum/action_layer.h index 067e33cdb5c..f2ac7cca5b3 100644 --- a/quantum/action_layer.h +++ b/quantum/action_layer.h @@ -163,6 +163,11 @@ layer_state_t update_tri_layer_state(layer_state_t state, uint8_t layer1, uint8_ void update_source_layers_cache(keypos_t key, uint8_t layer); uint8_t read_source_layers_cache(keypos_t key); +# ifdef KEYCODE_CACHE_ENABLE +void update_keycode_map(keypos_t key, uint16_t keycode); +uint16_t read_keycode_map(keypos_t key); +uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key); +# endif #endif action_t store_or_get_action(bool pressed, keypos_t key);