From 21958a93434e40db904eb731bc75b65661bcb9ae Mon Sep 17 00:00:00 2001 From: Pete Sevander Date: Sun, 9 Jan 2022 22:02:25 +0200 Subject: New combo configuration options (#15083) Co-authored-by: precondition <57645186+precondition@users.noreply.github.com> --- quantum/process_keycode/process_combo.c | 39 ++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'quantum/process_keycode/process_combo.c') diff --git a/quantum/process_keycode/process_combo.c b/quantum/process_keycode/process_combo.c index a050161edf..8040ede528 100644 --- a/quantum/process_keycode/process_combo.c +++ b/quantum/process_keycode/process_combo.c @@ -40,10 +40,18 @@ __attribute__((weak)) bool get_combo_must_tap(uint16_t index, combo_t *combo) { __attribute__((weak)) uint16_t get_combo_term(uint16_t index, combo_t *combo) { return COMBO_TERM; } #endif +#ifdef COMBO_MUST_PRESS_IN_ORDER_PER_COMBO +__attribute__((weak)) bool get_combo_must_press_in_order(uint16_t combo_index, combo_t *combo) { return true; } +#endif + #ifdef COMBO_PROCESS_KEY_RELEASE __attribute__((weak)) bool process_combo_key_release(uint16_t combo_index, combo_t *combo, uint8_t key_index, uint16_t keycode) { return false; } #endif +#ifdef COMBO_SHOULD_TRIGGER +__attribute__((weak)) bool combo_should_trigger(uint16_t combo_index, combo_t *combo, uint16_t keycode, keyrecord_t *record) { return true; } +#endif + #ifndef COMBO_NO_TIMER static uint16_t timer = 0; #endif @@ -350,6 +358,28 @@ combo_t *overlaps(combo_t *combo1, combo_t *combo2) { return combo1; } +#if defined(COMBO_MUST_PRESS_IN_ORDER) || defined(COMBO_MUST_PRESS_IN_ORDER_PER_COMBO) +static bool keys_pressed_in_order(uint16_t combo_index, combo_t *combo, uint16_t key_index, uint16_t keycode, keyrecord_t *record) { +# ifdef COMBO_MUST_PRESS_IN_ORDER_PER_COMBO + if (!get_combo_must_press_in_order(combo_index, combo)) { + return true; + } +# endif + if ( + // The `state` bit for the key being pressed. + (1 << key_index) == + // The *next* combo key's bit. + (COMBO_STATE(combo) + 1) + // E.g. two keys already pressed: `state == 11`. + // Next possible `state` is `111`. + // So the needed bit is `100` which we get with `11 + 1`. + ) { + return true; + } + return false; +} +#endif + static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *record, uint16_t combo_index) { uint8_t key_count = 0; uint16_t key_index = -1; @@ -360,7 +390,14 @@ static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t * return false; } - bool key_is_part_of_combo = !COMBO_DISABLED(combo) && is_combo_enabled(); + bool key_is_part_of_combo = (!COMBO_DISABLED(combo) && is_combo_enabled() +#if defined(COMBO_MUST_PRESS_IN_ORDER) || defined(COMBO_MUST_PRESS_IN_ORDER_PER_COMBO) + && keys_pressed_in_order(combo_index, combo, key_index, keycode, record) +#endif +#ifdef COMBO_SHOULD_TRIGGER + && combo_should_trigger(combo_index, combo, keycode, record) +#endif + ); if (record->event.pressed && key_is_part_of_combo) { uint16_t time = _get_combo_term(combo_index, combo); -- cgit v1.2.3 From d700447ddac307ab6b1e39b0485ddef76ed1fe7f Mon Sep 17 00:00:00 2001 From: Pete Sevander Date: Sat, 29 Jan 2022 09:19:36 +0200 Subject: Combo `TAP_CODE_DELAY` and `clear_weak_mods` (#15866) --- quantum/process_keycode/process_combo.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'quantum/process_keycode/process_combo.c') diff --git a/quantum/process_keycode/process_combo.c b/quantum/process_keycode/process_combo.c index 8040ede528..21fd737ab7 100644 --- a/quantum/process_keycode/process_combo.c +++ b/quantum/process_keycode/process_combo.c @@ -17,6 +17,7 @@ #include "print.h" #include "process_combo.h" #include "action_tapping.h" +#include "action.h" #ifdef COMBO_COUNT __attribute__((weak)) combo_t key_combos[COMBO_COUNT]; @@ -193,6 +194,9 @@ void clear_combos(void) { static inline void dump_key_buffer(void) { /* First call start from 0 index; recursive calls need to start from i+1 index */ static uint8_t key_buffer_next = 0; +#if TAP_CODE_DELAY > 0 + bool delay_done = false; +#endif if (key_buffer_size == 0) { return; @@ -218,6 +222,15 @@ static inline void dump_key_buffer(void) { #endif } record->event.time = 0; + clear_weak_mods(); + +#if TAP_CODE_DELAY > 0 + // only delay once and for a non-tapping key + if (!delay_done && !is_tap_record(record)) { + delay_done = true; + wait_ms(TAP_CODE_DELAY); + } +#endif } key_buffer_next = key_buffer_size = 0; -- cgit v1.2.3 From 63646e8906e062d1c1de3925cba70c4e3426a855 Mon Sep 17 00:00:00 2001 From: QMK Bot Date: Sat, 12 Feb 2022 10:29:31 -0800 Subject: Format code according to conventions (#16322) --- quantum/process_keycode/process_combo.c | 40 +++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 12 deletions(-) (limited to 'quantum/process_keycode/process_combo.c') diff --git a/quantum/process_keycode/process_combo.c b/quantum/process_keycode/process_combo.c index 21fd737ab7..efaf8fe0e9 100644 --- a/quantum/process_keycode/process_combo.c +++ b/quantum/process_keycode/process_combo.c @@ -30,33 +30,45 @@ extern uint16_t COMBO_LEN; __attribute__((weak)) void process_combo_event(uint16_t combo_index, bool pressed) {} #ifdef COMBO_MUST_HOLD_PER_COMBO -__attribute__((weak)) bool get_combo_must_hold(uint16_t index, combo_t *combo) { return false; } +__attribute__((weak)) bool get_combo_must_hold(uint16_t index, combo_t *combo) { + return false; +} #endif #ifdef COMBO_MUST_TAP_PER_COMBO -__attribute__((weak)) bool get_combo_must_tap(uint16_t index, combo_t *combo) { return false; } +__attribute__((weak)) bool get_combo_must_tap(uint16_t index, combo_t *combo) { + return false; +} #endif #ifdef COMBO_TERM_PER_COMBO -__attribute__((weak)) uint16_t get_combo_term(uint16_t index, combo_t *combo) { return COMBO_TERM; } +__attribute__((weak)) uint16_t get_combo_term(uint16_t index, combo_t *combo) { + return COMBO_TERM; +} #endif #ifdef COMBO_MUST_PRESS_IN_ORDER_PER_COMBO -__attribute__((weak)) bool get_combo_must_press_in_order(uint16_t combo_index, combo_t *combo) { return true; } +__attribute__((weak)) bool get_combo_must_press_in_order(uint16_t combo_index, combo_t *combo) { + return true; +} #endif #ifdef COMBO_PROCESS_KEY_RELEASE -__attribute__((weak)) bool process_combo_key_release(uint16_t combo_index, combo_t *combo, uint8_t key_index, uint16_t keycode) { return false; } +__attribute__((weak)) bool process_combo_key_release(uint16_t combo_index, combo_t *combo, uint8_t key_index, uint16_t keycode) { + return false; +} #endif #ifdef COMBO_SHOULD_TRIGGER -__attribute__((weak)) bool combo_should_trigger(uint16_t combo_index, combo_t *combo, uint16_t keycode, keyrecord_t *record) { return true; } +__attribute__((weak)) bool combo_should_trigger(uint16_t combo_index, combo_t *combo, uint16_t keycode, keyrecord_t *record) { + return true; +} #endif #ifndef COMBO_NO_TIMER static uint16_t timer = 0; #endif -static bool b_combo_enable = true; // defaults to enabled +static bool b_combo_enable = true; // defaults to enabled static uint16_t longest_term = 0; typedef struct { @@ -462,7 +474,7 @@ static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t * // get possible longer waiting time for tap-/hold-only combos. longest_term = _get_wait_time(combo_index, combo); } - } // if timer elapsed end + } // if timer elapsed end } } else { // chord releases @@ -477,7 +489,7 @@ static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t * else if (get_combo_must_tap(combo_index, combo)) { // immediately apply tap-only combo apply_combo(combo_index, combo); - apply_combos(); // also apply other prepared combos and dump key buffer + apply_combos(); // also apply other prepared combos and dump key buffer # ifdef COMBO_PROCESS_KEY_RELEASE if (process_combo_key_release(combo_index, combo, key_index, keycode)) { release_combo(combo_index, combo); @@ -559,7 +571,7 @@ bool process_combo(uint16_t keycode, keyrecord_t *record) { key_buffer[key_buffer_size++] = (queued_record_t){ .record = *record, .keycode = keycode, - .combo_index = -1, // this will be set when applying combos + .combo_index = -1, // this will be set when applying combos }; } } else { @@ -598,7 +610,9 @@ void combo_task(void) { #endif } -void combo_enable(void) { b_combo_enable = true; } +void combo_enable(void) { + b_combo_enable = true; +} void combo_disable(void) { #ifndef COMBO_NO_TIMER @@ -618,4 +632,6 @@ void combo_toggle(void) { } } -bool is_combo_enabled(void) { return b_combo_enable; } +bool is_combo_enabled(void) { + return b_combo_enable; +} -- cgit v1.2.3