From 7e983796e18e7401c062c158f23966aeb7b1405b Mon Sep 17 00:00:00 2001 From: Pete Sevander Date: Fri, 6 Aug 2021 02:44:57 +0300 Subject: Process combos earlier & overlapping combos (#8591) * Combo processing improvements. Now it is possible to use ModTap and LayerTap keys as part of combos. Overlapping combos also don't trigger all the combos, just exactly the one that you press. New settings: - COMBO_MUST_HOLD_MODS - COMBO_MOD_TERM - COMBO_TERM_PER_COMBO - COMBO_MUST_HOLD_PER_COMBO - COMBO_STRICT_TIMER - COMBO_NO_TIMER * Remove the size flags from combo_t struct boolean members. This in the end actually saves space as the members are accessed so many times. The amount of operations needed to access the bits uses more memory than setting the size saves. * Fix `process_combo_key_release` not called correctly with tap-only combos * Fix not passing a pointer when NO_ACTION_TAPPING is defined. * Docs for `COMBO_ONLY_FROM_LAYER` * Update docs/feature_combo.md Co-authored-by: precondition <57645186+precondition@users.noreply.github.com> * Update quantum/process_keycode/process_combo.c Co-authored-by: precondition <57645186+precondition@users.noreply.github.com> * Add `EXTRA_SHORT_COMBOS` option. Stuff combo's `disabled` and `active` flags into `state`. Possibly can save some space. * Add more examples and clarify things with dict management system. - Simple examples now has a combo that has modifiers included. - The slightly more advanced examples now are actually more advanced instead of just `tap_code16()`. - Added a note that `COMBO_ACTION`s are not needed anymore as you can just use custom keycodes. - Added a note that the `g/keymap_combo.h` macros use the `process_combo_event` function and that it is not usable in one's keymap afterwards. * Update docs/feature_combo.md Co-authored-by: precondition <57645186+precondition@users.noreply.github.com> * Update docs/feature_combo.md Co-authored-by: precondition <57645186+precondition@users.noreply.github.com> * Update docs/feature_combo.md Co-authored-by: precondition <57645186+precondition@users.noreply.github.com> * Update docs/feature_combo.md Co-authored-by: precondition <57645186+precondition@users.noreply.github.com> * Update docs/feature_combo.md Co-authored-by: precondition <57645186+precondition@users.noreply.github.com> * Change "the" combo action example to "email" example. * Update docs/feature_combo.md Co-authored-by: precondition <57645186+precondition@users.noreply.github.com> * Fix sneaky infinite loop with `combo_disable()` No need to call `dump_key_buffer` when disabling combos because the buffer is either being dumped if a combo-key was pressed, or the buffer is empty if a non-combo-key is pressed. * Update docs/feature_combo.md Co-authored-by: precondition <57645186+precondition@users.noreply.github.com> * Update docs/feature_combo.md Co-authored-by: precondition <57645186+precondition@users.noreply.github.com> Co-authored-by: precondition <57645186+precondition@users.noreply.github.com> Co-authored-by: Drashna Jaelre --- quantum/keymap_common.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'quantum/keymap_common.c') diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index e0fd6d4793..780c71ab9b 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -40,7 +40,10 @@ extern keymap_config_t keymap_config; action_t action_for_key(uint8_t layer, keypos_t key) { // 16bit keycodes - important uint16_t keycode = keymap_key_to_keycode(layer, key); + return action_for_keycode(keycode); +}; +action_t action_for_keycode(uint16_t keycode) { // keycode remapping keycode = keycode_config(keycode); -- cgit v1.2.3 From c4dbf4bf0118dd785802861beb247433b5b7411d Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Tue, 24 Aug 2021 14:28:37 +0100 Subject: Tidy up quantum.c now some of tmk_core has been merged (#14083) --- quantum/action.c | 28 +++++++++++++++ quantum/action.h | 5 +++ quantum/action_tapping.c | 35 +++++++++++++++++++ quantum/keymap_common.c | 25 ++++++++++++++ quantum/quantum.c | 90 ------------------------------------------------ quantum/quantum.h | 16 +++------ 6 files changed, 98 insertions(+), 101 deletions(-) (limited to 'quantum/keymap_common.c') diff --git a/quantum/action.c b/quantum/action.c index d19fd2a045..ec9fcd9c9c 100644 --- a/quantum/action.c +++ b/quantum/action.c @@ -960,6 +960,34 @@ void unregister_weak_mods(uint8_t mods) { } } +static void do_code16(uint16_t code, void (*f)(uint8_t)) { f(extract_mod_bits(code)); } + +void register_code16(uint16_t code) { + if (IS_MOD(code) || code == KC_NO) { + do_code16(code, register_mods); + } else { + do_code16(code, register_weak_mods); + } + register_code(code); +} + +void unregister_code16(uint16_t code) { + unregister_code(code); + if (IS_MOD(code) || code == KC_NO) { + do_code16(code, unregister_mods); + } else { + do_code16(code, unregister_weak_mods); + } +} + +void tap_code16(uint16_t code) { + register_code16(code); +#if TAP_CODE_DELAY > 0 + wait_ms(TAP_CODE_DELAY); +#endif + unregister_code16(code); +} + /** \brief Utilities for actions. (FIXME: Needs better description) * * FIXME: Needs documentation. diff --git a/quantum/action.h b/quantum/action.h index 3d357b33b8..4382c7ba4a 100644 --- a/quantum/action.h +++ b/quantum/action.h @@ -109,6 +109,9 @@ void register_mods(uint8_t mods); void unregister_mods(uint8_t mods); void register_weak_mods(uint8_t mods); void unregister_weak_mods(uint8_t mods); +void register_code16(uint16_t code); +void unregister_code16(uint16_t code); +void tap_code16(uint16_t code); // void set_mods(uint8_t mods); void clear_keyboard(void); void clear_keyboard_but_mods(void); @@ -118,6 +121,8 @@ bool is_tap_key(keypos_t key); bool is_tap_record(keyrecord_t *record); bool is_tap_action(action_t action); +uint8_t extract_mod_bits(uint16_t code); + #ifndef NO_ACTION_TAPPING void process_record_tap_hint(keyrecord_t *record); #endif diff --git a/quantum/action_tapping.c b/quantum/action_tapping.c index 36839f9faf..eef6ed1b7d 100644 --- a/quantum/action_tapping.c +++ b/quantum/action_tapping.c @@ -5,6 +5,7 @@ #include "action_tapping.h" #include "keycode.h" #include "timer.h" +#include "keymap.h" #ifdef DEBUG_ACTION # include "debug.h" @@ -58,6 +59,40 @@ static void waiting_buffer_scan_tap(void); static void debug_tapping_key(void); static void debug_waiting_buffer(void); +/* Convert record into usable keycode via the contained event. */ +uint16_t get_record_keycode(keyrecord_t *record, bool update_layer_cache) { +#ifdef COMBO_ENABLE + if (record->keycode) { return record->keycode; } +#endif + return get_event_keycode(record->event, update_layer_cache); +} + +/* Convert event into usable keycode. Checks the layer cache to ensure that it + * retains the correct keycode after a layer change, if the key is still pressed. + * "update_layer_cache" is to ensure that it only updates the layer cache when + * appropriate, otherwise, it will update it and cause layer tap (and other keys) + * from triggering properly. + */ +uint16_t get_event_keycode(keyevent_t event, bool update_layer_cache) { + const keypos_t key = event.key; + +#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE) + /* TODO: Use store_or_get_action() or a similar function. */ + if (!disable_action_cache) { + uint8_t layer; + + if (event.pressed && update_layer_cache) { + layer = layer_switch_get_layer(key); + update_source_layers_cache(key, layer); + } else { + layer = read_source_layers_cache(key); + } + return keymap_key_to_keycode(layer, key); + } +#endif + return keymap_key_to_keycode(layer_switch_get_layer(key), key); +} + /** \brief Action Tapping Process * * FIXME: Needs doc diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 780c71ab9b..008177bbee 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -36,6 +36,31 @@ extern keymap_config_t keymap_config; #include +uint8_t extract_mod_bits(uint16_t code) { + switch (code) { + case QK_MODS ... QK_MODS_MAX: + break; + default: + return 0; + } + + uint8_t mods_to_send = 0; + + if (code & QK_RMODS_MIN) { // Right mod flag is set + if (code & QK_LCTL) mods_to_send |= MOD_BIT(KC_RCTL); + if (code & QK_LSFT) mods_to_send |= MOD_BIT(KC_RSFT); + if (code & QK_LALT) mods_to_send |= MOD_BIT(KC_RALT); + if (code & QK_LGUI) mods_to_send |= MOD_BIT(KC_RGUI); + } else { + if (code & QK_LCTL) mods_to_send |= MOD_BIT(KC_LCTL); + if (code & QK_LSFT) mods_to_send |= MOD_BIT(KC_LSFT); + if (code & QK_LALT) mods_to_send |= MOD_BIT(KC_LALT); + if (code & QK_LGUI) mods_to_send |= MOD_BIT(KC_LGUI); + } + + return mods_to_send; +} + /* converts key to action */ action_t action_for_key(uint8_t layer, keypos_t key) { // 16bit keycodes - important diff --git a/quantum/quantum.c b/quantum/quantum.c index e60378afe4..00426c3973 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -51,63 +51,6 @@ float default_layer_songs[][16][2] = DEFAULT_LAYER_SONGS; # endif #endif -#ifdef AUTO_SHIFT_ENABLE -# include "process_auto_shift.h" -#endif - -uint8_t extract_mod_bits(uint16_t code) { - switch (code) { - case QK_MODS ... QK_MODS_MAX: - break; - default: - return 0; - } - - uint8_t mods_to_send = 0; - - if (code & QK_RMODS_MIN) { // Right mod flag is set - if (code & QK_LCTL) mods_to_send |= MOD_BIT(KC_RCTL); - if (code & QK_LSFT) mods_to_send |= MOD_BIT(KC_RSFT); - if (code & QK_LALT) mods_to_send |= MOD_BIT(KC_RALT); - if (code & QK_LGUI) mods_to_send |= MOD_BIT(KC_RGUI); - } else { - if (code & QK_LCTL) mods_to_send |= MOD_BIT(KC_LCTL); - if (code & QK_LSFT) mods_to_send |= MOD_BIT(KC_LSFT); - if (code & QK_LALT) mods_to_send |= MOD_BIT(KC_LALT); - if (code & QK_LGUI) mods_to_send |= MOD_BIT(KC_LGUI); - } - - return mods_to_send; -} - -static void do_code16(uint16_t code, void (*f)(uint8_t)) { f(extract_mod_bits(code)); } - -void register_code16(uint16_t code) { - if (IS_MOD(code) || code == KC_NO) { - do_code16(code, register_mods); - } else { - do_code16(code, register_weak_mods); - } - register_code(code); -} - -void unregister_code16(uint16_t code) { - unregister_code(code); - if (IS_MOD(code) || code == KC_NO) { - do_code16(code, unregister_mods); - } else { - do_code16(code, unregister_weak_mods); - } -} - -void tap_code16(uint16_t code) { - register_code16(code); -#if TAP_CODE_DELAY > 0 - wait_ms(TAP_CODE_DELAY); -#endif - unregister_code16(code); -} - __attribute__((weak)) bool process_action_kb(keyrecord_t *record) { return true; } __attribute__((weak)) bool process_record_kb(uint16_t keycode, keyrecord_t *record) { return process_record_user(keycode, record); } @@ -142,39 +85,6 @@ void reset_keyboard(void) { bootloader_jump(); } -/* Convert record into usable keycode via the contained event. */ -uint16_t get_record_keycode(keyrecord_t *record, bool update_layer_cache) { -#ifdef COMBO_ENABLE - if (record->keycode) { return record->keycode; } -#endif - return get_event_keycode(record->event, update_layer_cache); -} - - -/* Convert event into usable keycode. Checks the layer cache to ensure that it - * retains the correct keycode after a layer change, if the key is still pressed. - * "update_layer_cache" is to ensure that it only updates the layer cache when - * appropriate, otherwise, it will update it and cause layer tap (and other keys) - * from triggering properly. - */ -uint16_t get_event_keycode(keyevent_t event, bool update_layer_cache) { -#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE) - /* TODO: Use store_or_get_action() or a similar function. */ - if (!disable_action_cache) { - uint8_t layer; - - if (event.pressed && update_layer_cache) { - layer = layer_switch_get_layer(event.key); - update_source_layers_cache(event.key, layer); - } else { - layer = read_source_layers_cache(event.key); - } - return keymap_key_to_keycode(layer, event.key); - } else -#endif - return keymap_key_to_keycode(layer_switch_get_layer(event.key), event.key); -} - /* Get keycode, and then process pre tapping functionality */ bool pre_process_record_quantum(keyrecord_t *record) { if (!( diff --git a/quantum/quantum.h b/quantum/quantum.h index 86b717e445..b409edef31 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -212,23 +212,17 @@ void set_single_persistent_default_layer(uint8_t default_layer); #define IS_LAYER_ON_STATE(state, layer) layer_state_cmp(state, layer) #define IS_LAYER_OFF_STATE(state, layer) !layer_state_cmp(state, layer) -uint16_t get_record_keycode(keyrecord_t *record, bool update_layer_cache); -uint16_t get_event_keycode(keyevent_t event, bool update_layer_cache); -bool process_action_kb(keyrecord_t *record); -bool process_record_kb(uint16_t keycode, keyrecord_t *record); -bool process_record_user(uint16_t keycode, keyrecord_t *record); -void post_process_record_kb(uint16_t keycode, keyrecord_t *record); -void post_process_record_user(uint16_t keycode, keyrecord_t *record); +bool process_action_kb(keyrecord_t *record); +bool process_record_kb(uint16_t keycode, keyrecord_t *record); +bool process_record_user(uint16_t keycode, keyrecord_t *record); +void post_process_record_kb(uint16_t keycode, keyrecord_t *record); +void post_process_record_user(uint16_t keycode, keyrecord_t *record); void reset_keyboard(void); void startup_user(void); void shutdown_user(void); -void register_code16(uint16_t code); -void unregister_code16(uint16_t code); -void tap_code16(uint16_t code); - void led_set_user(uint8_t usb_led); void led_set_kb(uint8_t usb_led); bool led_update_user(led_t led_state); -- cgit v1.2.3 From a84de5e22be25e2059dfee732f5cca3ec0953a35 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Wed, 25 Aug 2021 01:16:59 +0100 Subject: Revert 14083 && 14144 (#14150) * Revert "Short term bodge for firmware size bloat (#14144)" This reverts commit a8d65473461c337fb1e168d907bfb8c3ac8fdbd0. * Revert "Tidy up quantum.c now some of tmk_core has been merged (#14083)" This reverts commit c4dbf4bf0118dd785802861beb247433b5b7411d.--- quantum/action.c | 28 --------------- quantum/action.h | 5 --- quantum/action_tapping.c | 35 ------------------- quantum/keymap.h | 4 ++- quantum/keymap_common.c | 25 -------------- quantum/keymap_common.h | 19 ---------- quantum/quantum.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++ quantum/quantum.h | 16 ++++++--- 8 files changed, 104 insertions(+), 118 deletions(-) delete mode 100644 quantum/keymap_common.h (limited to 'quantum/keymap_common.c') diff --git a/quantum/action.c b/quantum/action.c index ec9fcd9c9c..d19fd2a045 100644 --- a/quantum/action.c +++ b/quantum/action.c @@ -960,34 +960,6 @@ void unregister_weak_mods(uint8_t mods) { } } -static void do_code16(uint16_t code, void (*f)(uint8_t)) { f(extract_mod_bits(code)); } - -void register_code16(uint16_t code) { - if (IS_MOD(code) || code == KC_NO) { - do_code16(code, register_mods); - } else { - do_code16(code, register_weak_mods); - } - register_code(code); -} - -void unregister_code16(uint16_t code) { - unregister_code(code); - if (IS_MOD(code) || code == KC_NO) { - do_code16(code, unregister_mods); - } else { - do_code16(code, unregister_weak_mods); - } -} - -void tap_code16(uint16_t code) { - register_code16(code); -#if TAP_CODE_DELAY > 0 - wait_ms(TAP_CODE_DELAY); -#endif - unregister_code16(code); -} - /** \brief Utilities for actions. (FIXME: Needs better description) * * FIXME: Needs documentation. diff --git a/quantum/action.h b/quantum/action.h index 4382c7ba4a..3d357b33b8 100644 --- a/quantum/action.h +++ b/quantum/action.h @@ -109,9 +109,6 @@ void register_mods(uint8_t mods); void unregister_mods(uint8_t mods); void register_weak_mods(uint8_t mods); void unregister_weak_mods(uint8_t mods); -void register_code16(uint16_t code); -void unregister_code16(uint16_t code); -void tap_code16(uint16_t code); // void set_mods(uint8_t mods); void clear_keyboard(void); void clear_keyboard_but_mods(void); @@ -121,8 +118,6 @@ bool is_tap_key(keypos_t key); bool is_tap_record(keyrecord_t *record); bool is_tap_action(action_t action); -uint8_t extract_mod_bits(uint16_t code); - #ifndef NO_ACTION_TAPPING void process_record_tap_hint(keyrecord_t *record); #endif diff --git a/quantum/action_tapping.c b/quantum/action_tapping.c index 09514aa7fd..36839f9faf 100644 --- a/quantum/action_tapping.c +++ b/quantum/action_tapping.c @@ -5,7 +5,6 @@ #include "action_tapping.h" #include "keycode.h" #include "timer.h" -#include "keymap_common.h" #ifdef DEBUG_ACTION # include "debug.h" @@ -59,40 +58,6 @@ static void waiting_buffer_scan_tap(void); static void debug_tapping_key(void); static void debug_waiting_buffer(void); -/* Convert record into usable keycode via the contained event. */ -uint16_t get_record_keycode(keyrecord_t *record, bool update_layer_cache) { -#ifdef COMBO_ENABLE - if (record->keycode) { return record->keycode; } -#endif - return get_event_keycode(record->event, update_layer_cache); -} - -/* Convert event into usable keycode. Checks the layer cache to ensure that it - * retains the correct keycode after a layer change, if the key is still pressed. - * "update_layer_cache" is to ensure that it only updates the layer cache when - * appropriate, otherwise, it will update it and cause layer tap (and other keys) - * from triggering properly. - */ -uint16_t get_event_keycode(keyevent_t event, bool update_layer_cache) { - const keypos_t key = event.key; - -#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE) - /* TODO: Use store_or_get_action() or a similar function. */ - if (!disable_action_cache) { - uint8_t layer; - - if (event.pressed && update_layer_cache) { - layer = layer_switch_get_layer(key); - update_source_layers_cache(key, layer); - } else { - layer = read_source_layers_cache(key); - } - return keymap_key_to_keycode(layer, key); - } -#endif - return keymap_key_to_keycode(layer_switch_get_layer(key), key); -} - /** \brief Action Tapping Process * * FIXME: Needs doc diff --git a/quantum/keymap.h b/quantum/keymap.h index 6520485f76..191e813977 100644 --- a/quantum/keymap.h +++ b/quantum/keymap.h @@ -33,7 +33,6 @@ along with this program. If not, see . // #include "print.h" #include "debug.h" #include "keycode_config.h" -#include "keymap_common.h" // ChibiOS uses RESET in its FlagStatus enumeration // Therefore define it as QK_RESET here, to avoid name collision @@ -47,6 +46,9 @@ along with this program. If not, see . #include "quantum_keycodes.h" +// translates key to keycode +uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key); + // translates function id to action uint16_t keymap_function_id_to_action(uint16_t function_id); diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 008177bbee..780c71ab9b 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -36,31 +36,6 @@ extern keymap_config_t keymap_config; #include -uint8_t extract_mod_bits(uint16_t code) { - switch (code) { - case QK_MODS ... QK_MODS_MAX: - break; - default: - return 0; - } - - uint8_t mods_to_send = 0; - - if (code & QK_RMODS_MIN) { // Right mod flag is set - if (code & QK_LCTL) mods_to_send |= MOD_BIT(KC_RCTL); - if (code & QK_LSFT) mods_to_send |= MOD_BIT(KC_RSFT); - if (code & QK_LALT) mods_to_send |= MOD_BIT(KC_RALT); - if (code & QK_LGUI) mods_to_send |= MOD_BIT(KC_RGUI); - } else { - if (code & QK_LCTL) mods_to_send |= MOD_BIT(KC_LCTL); - if (code & QK_LSFT) mods_to_send |= MOD_BIT(KC_LSFT); - if (code & QK_LALT) mods_to_send |= MOD_BIT(KC_LALT); - if (code & QK_LGUI) mods_to_send |= MOD_BIT(KC_LGUI); - } - - return mods_to_send; -} - /* converts key to action */ action_t action_for_key(uint8_t layer, keypos_t key) { // 16bit keycodes - important diff --git a/quantum/keymap_common.h b/quantum/keymap_common.h deleted file mode 100644 index 9ff8441e86..0000000000 --- a/quantum/keymap_common.h +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright 2021 QMK - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#pragma once - -// translates key to keycode -uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key); diff --git a/quantum/quantum.c b/quantum/quantum.c index 00426c3973..e60378afe4 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -51,6 +51,63 @@ float default_layer_songs[][16][2] = DEFAULT_LAYER_SONGS; # endif #endif +#ifdef AUTO_SHIFT_ENABLE +# include "process_auto_shift.h" +#endif + +uint8_t extract_mod_bits(uint16_t code) { + switch (code) { + case QK_MODS ... QK_MODS_MAX: + break; + default: + return 0; + } + + uint8_t mods_to_send = 0; + + if (code & QK_RMODS_MIN) { // Right mod flag is set + if (code & QK_LCTL) mods_to_send |= MOD_BIT(KC_RCTL); + if (code & QK_LSFT) mods_to_send |= MOD_BIT(KC_RSFT); + if (code & QK_LALT) mods_to_send |= MOD_BIT(KC_RALT); + if (code & QK_LGUI) mods_to_send |= MOD_BIT(KC_RGUI); + } else { + if (code & QK_LCTL) mods_to_send |= MOD_BIT(KC_LCTL); + if (code & QK_LSFT) mods_to_send |= MOD_BIT(KC_LSFT); + if (code & QK_LALT) mods_to_send |= MOD_BIT(KC_LALT); + if (code & QK_LGUI) mods_to_send |= MOD_BIT(KC_LGUI); + } + + return mods_to_send; +} + +static void do_code16(uint16_t code, void (*f)(uint8_t)) { f(extract_mod_bits(code)); } + +void register_code16(uint16_t code) { + if (IS_MOD(code) || code == KC_NO) { + do_code16(code, register_mods); + } else { + do_code16(code, register_weak_mods); + } + register_code(code); +} + +void unregister_code16(uint16_t code) { + unregister_code(code); + if (IS_MOD(code) || code == KC_NO) { + do_code16(code, unregister_mods); + } else { + do_code16(code, unregister_weak_mods); + } +} + +void tap_code16(uint16_t code) { + register_code16(code); +#if TAP_CODE_DELAY > 0 + wait_ms(TAP_CODE_DELAY); +#endif + unregister_code16(code); +} + __attribute__((weak)) bool process_action_kb(keyrecord_t *record) { return true; } __attribute__((weak)) bool process_record_kb(uint16_t keycode, keyrecord_t *record) { return process_record_user(keycode, record); } @@ -85,6 +142,39 @@ void reset_keyboard(void) { bootloader_jump(); } +/* Convert record into usable keycode via the contained event. */ +uint16_t get_record_keycode(keyrecord_t *record, bool update_layer_cache) { +#ifdef COMBO_ENABLE + if (record->keycode) { return record->keycode; } +#endif + return get_event_keycode(record->event, update_layer_cache); +} + + +/* Convert event into usable keycode. Checks the layer cache to ensure that it + * retains the correct keycode after a layer change, if the key is still pressed. + * "update_layer_cache" is to ensure that it only updates the layer cache when + * appropriate, otherwise, it will update it and cause layer tap (and other keys) + * from triggering properly. + */ +uint16_t get_event_keycode(keyevent_t event, bool update_layer_cache) { +#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE) + /* TODO: Use store_or_get_action() or a similar function. */ + if (!disable_action_cache) { + uint8_t layer; + + if (event.pressed && update_layer_cache) { + layer = layer_switch_get_layer(event.key); + update_source_layers_cache(event.key, layer); + } else { + layer = read_source_layers_cache(event.key); + } + return keymap_key_to_keycode(layer, event.key); + } else +#endif + return keymap_key_to_keycode(layer_switch_get_layer(event.key), event.key); +} + /* Get keycode, and then process pre tapping functionality */ bool pre_process_record_quantum(keyrecord_t *record) { if (!( diff --git a/quantum/quantum.h b/quantum/quantum.h index b409edef31..86b717e445 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -212,17 +212,23 @@ void set_single_persistent_default_layer(uint8_t default_layer); #define IS_LAYER_ON_STATE(state, layer) layer_state_cmp(state, layer) #define IS_LAYER_OFF_STATE(state, layer) !layer_state_cmp(state, layer) -bool process_action_kb(keyrecord_t *record); -bool process_record_kb(uint16_t keycode, keyrecord_t *record); -bool process_record_user(uint16_t keycode, keyrecord_t *record); -void post_process_record_kb(uint16_t keycode, keyrecord_t *record); -void post_process_record_user(uint16_t keycode, keyrecord_t *record); +uint16_t get_record_keycode(keyrecord_t *record, bool update_layer_cache); +uint16_t get_event_keycode(keyevent_t event, bool update_layer_cache); +bool process_action_kb(keyrecord_t *record); +bool process_record_kb(uint16_t keycode, keyrecord_t *record); +bool process_record_user(uint16_t keycode, keyrecord_t *record); +void post_process_record_kb(uint16_t keycode, keyrecord_t *record); +void post_process_record_user(uint16_t keycode, keyrecord_t *record); void reset_keyboard(void); void startup_user(void); void shutdown_user(void); +void register_code16(uint16_t code); +void unregister_code16(uint16_t code); +void tap_code16(uint16_t code); + void led_set_user(uint8_t usb_led); void led_set_kb(uint8_t usb_led); bool led_update_user(led_t led_state); -- cgit v1.2.3