diff options
| author | Pete Sevander <pete.sevander@gmail.com> | 2022-01-09 22:02:25 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-01-09 12:02:25 -0800 |
| commit | 21958a93434e40db904eb731bc75b65661bcb9ae (patch) | |
| tree | a3480525b7460ecbddaad523ac87aded78b32d86 /quantum/process_keycode/process_combo.c | |
| parent | 69b211abb60d46b8c694c8e17d0c9a9a318dbc06 (diff) | |
New combo configuration options (#15083)
Co-authored-by: precondition <57645186+precondition@users.noreply.github.com>
Diffstat (limited to 'quantum/process_keycode/process_combo.c')
| -rw-r--r-- | quantum/process_keycode/process_combo.c | 39 |
1 files changed, 38 insertions, 1 deletions
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) { | |||
| 40 | __attribute__((weak)) uint16_t get_combo_term(uint16_t index, combo_t *combo) { return COMBO_TERM; } | 40 | __attribute__((weak)) uint16_t get_combo_term(uint16_t index, combo_t *combo) { return COMBO_TERM; } |
| 41 | #endif | 41 | #endif |
| 42 | 42 | ||
| 43 | #ifdef COMBO_MUST_PRESS_IN_ORDER_PER_COMBO | ||
| 44 | __attribute__((weak)) bool get_combo_must_press_in_order(uint16_t combo_index, combo_t *combo) { return true; } | ||
| 45 | #endif | ||
| 46 | |||
| 43 | #ifdef COMBO_PROCESS_KEY_RELEASE | 47 | #ifdef COMBO_PROCESS_KEY_RELEASE |
| 44 | __attribute__((weak)) bool process_combo_key_release(uint16_t combo_index, combo_t *combo, uint8_t key_index, uint16_t keycode) { return false; } | 48 | __attribute__((weak)) bool process_combo_key_release(uint16_t combo_index, combo_t *combo, uint8_t key_index, uint16_t keycode) { return false; } |
| 45 | #endif | 49 | #endif |
| 46 | 50 | ||
| 51 | #ifdef COMBO_SHOULD_TRIGGER | ||
| 52 | __attribute__((weak)) bool combo_should_trigger(uint16_t combo_index, combo_t *combo, uint16_t keycode, keyrecord_t *record) { return true; } | ||
| 53 | #endif | ||
| 54 | |||
| 47 | #ifndef COMBO_NO_TIMER | 55 | #ifndef COMBO_NO_TIMER |
| 48 | static uint16_t timer = 0; | 56 | static uint16_t timer = 0; |
| 49 | #endif | 57 | #endif |
| @@ -350,6 +358,28 @@ combo_t *overlaps(combo_t *combo1, combo_t *combo2) { | |||
| 350 | return combo1; | 358 | return combo1; |
| 351 | } | 359 | } |
| 352 | 360 | ||
| 361 | #if defined(COMBO_MUST_PRESS_IN_ORDER) || defined(COMBO_MUST_PRESS_IN_ORDER_PER_COMBO) | ||
| 362 | static bool keys_pressed_in_order(uint16_t combo_index, combo_t *combo, uint16_t key_index, uint16_t keycode, keyrecord_t *record) { | ||
| 363 | # ifdef COMBO_MUST_PRESS_IN_ORDER_PER_COMBO | ||
| 364 | if (!get_combo_must_press_in_order(combo_index, combo)) { | ||
| 365 | return true; | ||
| 366 | } | ||
| 367 | # endif | ||
| 368 | if ( | ||
| 369 | // The `state` bit for the key being pressed. | ||
| 370 | (1 << key_index) == | ||
| 371 | // The *next* combo key's bit. | ||
| 372 | (COMBO_STATE(combo) + 1) | ||
| 373 | // E.g. two keys already pressed: `state == 11`. | ||
| 374 | // Next possible `state` is `111`. | ||
| 375 | // So the needed bit is `100` which we get with `11 + 1`. | ||
| 376 | ) { | ||
| 377 | return true; | ||
| 378 | } | ||
| 379 | return false; | ||
| 380 | } | ||
| 381 | #endif | ||
| 382 | |||
| 353 | static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *record, uint16_t combo_index) { | 383 | static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *record, uint16_t combo_index) { |
| 354 | uint8_t key_count = 0; | 384 | uint8_t key_count = 0; |
| 355 | uint16_t key_index = -1; | 385 | uint16_t key_index = -1; |
| @@ -360,7 +390,14 @@ static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t * | |||
| 360 | return false; | 390 | return false; |
| 361 | } | 391 | } |
| 362 | 392 | ||
| 363 | bool key_is_part_of_combo = !COMBO_DISABLED(combo) && is_combo_enabled(); | 393 | bool key_is_part_of_combo = (!COMBO_DISABLED(combo) && is_combo_enabled() |
| 394 | #if defined(COMBO_MUST_PRESS_IN_ORDER) || defined(COMBO_MUST_PRESS_IN_ORDER_PER_COMBO) | ||
| 395 | && keys_pressed_in_order(combo_index, combo, key_index, keycode, record) | ||
| 396 | #endif | ||
| 397 | #ifdef COMBO_SHOULD_TRIGGER | ||
| 398 | && combo_should_trigger(combo_index, combo, keycode, record) | ||
| 399 | #endif | ||
| 400 | ); | ||
| 364 | 401 | ||
| 365 | if (record->event.pressed && key_is_part_of_combo) { | 402 | if (record->event.pressed && key_is_part_of_combo) { |
| 366 | uint16_t time = _get_combo_term(combo_index, combo); | 403 | uint16_t time = _get_combo_term(combo_index, combo); |
