diff options
| author | zvecr <git@zvecr.com> | 2022-02-25 23:45:40 +0000 | 
|---|---|---|
| committer | zvecr <git@zvecr.com> | 2022-02-25 23:45:40 +0000 | 
| commit | e7931289918221081cbe2a7ea5df27a5d86324db (patch) | |
| tree | 0b06145520f8aaf5ff5cb928aa5176fc2dd23619 /quantum/process_keycode/process_combo.c | |
| parent | c0ee3d2c79388187883b1b1b1d1a0b6842acf741 (diff) | |
| parent | cf31355f08dca311a013168eb3eb995e2fc6a3d1 (diff) | |
Merge remote-tracking branch 'origin/develop'
Diffstat (limited to 'quantum/process_keycode/process_combo.c')
| -rw-r--r-- | quantum/process_keycode/process_combo.c | 88 | 
1 files changed, 77 insertions, 11 deletions
| diff --git a/quantum/process_keycode/process_combo.c b/quantum/process_keycode/process_combo.c index a050161edf..efaf8fe0e9 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]; @@ -29,25 +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; +}  #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; +}  #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 { @@ -185,6 +206,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; @@ -210,6 +234,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; @@ -350,6 +383,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 +415,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); @@ -412,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 @@ -427,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); @@ -509,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 { @@ -548,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 @@ -568,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; +} | 
