mirror of
https://github.com/qmk/qmk_firmware.git
synced 2025-07-27 11:31:13 +00:00
implemented array of historical_keycode_t to cache keycodes, with configurable limit
This commit is contained in:
parent
1dc57e7ea6
commit
c6bbe8031a
@ -144,6 +144,8 @@ If you define these options you will enable the associated feature, which may in
|
|||||||
* force a key release to be evaluated using the current layer stack instead of remembering which layer it came from (used for advanced cases)
|
* 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`
|
* `#define KEYCODE_CACHE_ENABLE`
|
||||||
* Cache keycode for pressed keys, to be used on key release, across entire physical keyboard layout.
|
* Cache keycode for pressed keys, to be used on key release, across entire physical keyboard layout.
|
||||||
|
* `#define KEYCODE_CACHE_LIMIT 10`
|
||||||
|
* Optionally limit the number of keycodes able to be cached. Keys pressed beyond the limit will behave as without using the keycode cache.
|
||||||
|
|
||||||
## Behaviors That Can Be Configured
|
## Behaviors That Can Be Configured
|
||||||
|
|
||||||
|
@ -308,25 +308,69 @@ uint8_t read_source_layers_cache(keypos_t key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# ifdef KEYCODE_CACHE_ENABLE
|
# ifdef KEYCODE_CACHE_ENABLE
|
||||||
static uint16_t keycode_map[MATRIX_ROWS][MATRIX_COLS] = {{KC_NO}};
|
# ifndef KEYCODE_CACHE_LIMIT
|
||||||
|
#define KEYCODE_CACHE_LIMIT (MATRIX_ROWS * MATRIX_COLS)
|
||||||
|
# endif
|
||||||
|
|
||||||
/** \brief update keycode map
|
typedef struct historical_keycode_t {
|
||||||
|
uint8_t row;
|
||||||
|
uint8_t col;
|
||||||
|
uint16_t keycode;
|
||||||
|
} historical_keycode_t;
|
||||||
|
static historical_keycode_t keycode_cache[KEYCODE_CACHE_LIMIT];
|
||||||
|
static uint16_t keycode_cache_count = 0;
|
||||||
|
|
||||||
|
/** \brief find keycode cache index
|
||||||
*
|
*
|
||||||
* Updates map of keycodes when a key is pressed down
|
* returns index of keycode_cache for given key
|
||||||
*/
|
*/
|
||||||
void update_keycode_map(keypos_t key, uint16_t keycode) {
|
static int16_t find_keycode_cache_index(keypos_t key) {
|
||||||
if (key.row < MATRIX_ROWS && key.col < MATRIX_COLS) {
|
for (uint16_t i = 0; i < keycode_cache_count; ++i) {
|
||||||
keycode_map[key.row][key.col] = keycode;
|
if (keycode_cache[i].row == key.row && keycode_cache[i].col == key.col) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief add keycode cache
|
||||||
|
*
|
||||||
|
* add to cache of keycodes after a key is pressed down
|
||||||
|
*/
|
||||||
|
static void add_keycode_cache(keypos_t key, uint16_t keycode) {
|
||||||
|
int16_t idx = find_keycode_cache_index(key);
|
||||||
|
if (idx >= 0) {
|
||||||
|
keycode_cache[idx].keycode = keycode;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (keycode_cache_count < KEYCODE_CACHE_LIMIT) {
|
||||||
|
keycode_cache[keycode_cache_count].row = key.row;
|
||||||
|
keycode_cache[keycode_cache_count].col = key.col;
|
||||||
|
keycode_cache[keycode_cache_count].keycode = keycode;
|
||||||
|
keycode_cache_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief read keycode map
|
/** \brief remove keycode cache
|
||||||
*
|
*
|
||||||
* reads from map of keycodes when a key is released
|
* remove from cache of keycodes after a key is released
|
||||||
*/
|
*/
|
||||||
uint16_t read_keycode_map(keypos_t key) {
|
static void remove_keycode_cache(keypos_t key) {
|
||||||
if (key.row < MATRIX_ROWS && key.col < MATRIX_COLS) {
|
int16_t idx = find_keycode_cache_index(key);
|
||||||
return keycode_map[key.row][key.col];
|
if (idx >= 0) {
|
||||||
|
keycode_cache[idx] = keycode_cache[keycode_cache_count - 1];
|
||||||
|
keycode_cache_count--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief read keycode cache
|
||||||
|
*
|
||||||
|
* reads from cache of keycodes for when a key is releasing
|
||||||
|
*/
|
||||||
|
static uint16_t read_keycode_cache(keypos_t key) {
|
||||||
|
int16_t idx = find_keycode_cache_index(key);
|
||||||
|
if (idx >= 0) {
|
||||||
|
return keycode_cache[idx].keycode;
|
||||||
}
|
}
|
||||||
return KC_NO;
|
return KC_NO;
|
||||||
}
|
}
|
||||||
@ -350,24 +394,34 @@ action_t store_or_get_action(bool pressed, keypos_t key) {
|
|||||||
uint8_t layer;
|
uint8_t layer;
|
||||||
# ifdef KEYCODE_CACHE_ENABLE
|
# ifdef KEYCODE_CACHE_ENABLE
|
||||||
uint16_t keycode;
|
uint16_t keycode;
|
||||||
|
bool cache_used = false;
|
||||||
# endif
|
# endif
|
||||||
if (pressed) {
|
if (pressed) {
|
||||||
layer = layer_switch_get_layer(key);
|
layer = layer_switch_get_layer(key);
|
||||||
update_source_layers_cache(key, layer);
|
update_source_layers_cache(key, layer);
|
||||||
# ifdef KEYCODE_CACHE_ENABLE
|
# ifdef KEYCODE_CACHE_ENABLE
|
||||||
keycode = keymap_key_to_keycode(layer, key);
|
keycode = keymap_key_to_keycode(layer, key);
|
||||||
update_keycode_map(key, keycode);
|
if (keycode_cache_count < KEYCODE_CACHE_LIMIT) {
|
||||||
|
add_keycode_cache(key, keycode);
|
||||||
|
cache_used = true;
|
||||||
|
}
|
||||||
# endif
|
# endif
|
||||||
} else {
|
} else {
|
||||||
layer = read_source_layers_cache(key);
|
layer = read_source_layers_cache(key);
|
||||||
# ifdef KEYCODE_CACHE_ENABLE
|
# ifdef KEYCODE_CACHE_ENABLE
|
||||||
keycode = read_keycode_map(key);
|
keycode = read_keycode_cache(key);
|
||||||
|
remove_keycode_cache(key);
|
||||||
|
cache_used = (keycode != KC_NO);
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
# ifndef KEYCODE_CACHE_ENABLE
|
# ifndef KEYCODE_CACHE_ENABLE
|
||||||
return action_for_key(layer, key);
|
return action_for_key(layer, key);
|
||||||
# else
|
# else
|
||||||
|
if (cache_used) {
|
||||||
return action_for_keycode(keycode);
|
return action_for_keycode(keycode);
|
||||||
|
} else {
|
||||||
|
return action_for_key(layer, key);
|
||||||
|
}
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
return layer_switch_get_action(key);
|
return layer_switch_get_action(key);
|
||||||
|
Loading…
Reference in New Issue
Block a user