summaryrefslogtreecommitdiff
path: root/quantum/process_keycode/process_combo.c
diff options
context:
space:
mode:
authorFilios92 <filios92@gmail.com>2024-09-06 08:27:20 +0200
committerGitHub <noreply@github.com>2024-09-05 23:27:20 -0700
commit0fd99096577a57453f070f2dd94baefa09e369a4 (patch)
tree23c3a69568b02530f18475c608c5d2297a9d680f /quantum/process_keycode/process_combo.c
parentb5c807fb4a365e59052f99c8d7c9e0ef7dc2ce86 (diff)
Add combo key repress feature (#22858)
Co-authored-by: jack <jack@pngu.org>
Diffstat (limited to 'quantum/process_keycode/process_combo.c')
-rw-r--r--quantum/process_keycode/process_combo.c46
1 files changed, 34 insertions, 12 deletions
diff --git a/quantum/process_keycode/process_combo.c b/quantum/process_keycode/process_combo.c
index b0034d136a..38171c2f54 100644
--- a/quantum/process_keycode/process_combo.c
+++ b/quantum/process_keycode/process_combo.c
@@ -65,12 +65,20 @@ __attribute__((weak)) bool process_combo_key_release(uint16_t combo_index, combo
65} 65}
66#endif 66#endif
67 67
68#ifdef COMBO_PROCESS_KEY_REPRESS
69__attribute__((weak)) bool process_combo_key_repress(uint16_t combo_index, combo_t *combo, uint8_t key_index, uint16_t keycode) {
70 return false;
71}
72#endif
73
68#ifdef COMBO_SHOULD_TRIGGER 74#ifdef COMBO_SHOULD_TRIGGER
69__attribute__((weak)) bool combo_should_trigger(uint16_t combo_index, combo_t *combo, uint16_t keycode, keyrecord_t *record) { 75__attribute__((weak)) bool combo_should_trigger(uint16_t combo_index, combo_t *combo, uint16_t keycode, keyrecord_t *record) {
70 return true; 76 return true;
71} 77}
72#endif 78#endif
73 79
80typedef enum { COMBO_KEY_NOT_PRESSED, COMBO_KEY_PRESSED, COMBO_KEY_REPRESSED } combo_key_action_t;
81
74#ifndef COMBO_NO_TIMER 82#ifndef COMBO_NO_TIMER
75static uint16_t timer = 0; 83static uint16_t timer = 0;
76#endif 84#endif
@@ -414,14 +422,14 @@ static bool keys_pressed_in_order(uint16_t combo_index, combo_t *combo, uint16_t
414} 422}
415#endif 423#endif
416 424
417static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *record, uint16_t combo_index) { 425static combo_key_action_t process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *record, uint16_t combo_index) {
418 uint8_t key_count = 0; 426 uint8_t key_count = 0;
419 uint16_t key_index = -1; 427 uint16_t key_index = -1;
420 _find_key_index_and_count(combo->keys, keycode, &key_index, &key_count); 428 _find_key_index_and_count(combo->keys, keycode, &key_index, &key_count);
421 429
422 /* Continue processing if key isn't part of current combo. */ 430 /* Continue processing if key isn't part of current combo. */
423 if (-1 == (int16_t)key_index) { 431 if (-1 == (int16_t)key_index) {
424 return false; 432 return COMBO_KEY_NOT_PRESSED;
425 } 433 }
426 434
427 bool key_is_part_of_combo = (!COMBO_DISABLED(combo) && is_combo_enabled() 435 bool key_is_part_of_combo = (!COMBO_DISABLED(combo) && is_combo_enabled()
@@ -449,7 +457,7 @@ static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *
449 /* Don't buffer this combo if its combo term has passed. */ 457 /* Don't buffer this combo if its combo term has passed. */
450 if (timer && timer_elapsed(timer) > time) { 458 if (timer && timer_elapsed(timer) > time) {
451 DISABLE_COMBO(combo); 459 DISABLE_COMBO(combo);
452 return true; 460 return COMBO_KEY_PRESSED;
453 } else 461 } else
454#endif 462#endif
455 { 463 {
@@ -485,6 +493,15 @@ static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *
485 } 493 }
486 } // if timer elapsed end 494 } // if timer elapsed end
487 } 495 }
496#ifdef COMBO_PROCESS_KEY_REPRESS
497 } else if (record->event.pressed) {
498 if (COMBO_ACTIVE(combo)) {
499 if (process_combo_key_repress(combo_index, combo, key_index, keycode)) {
500 KEY_STATE_DOWN(combo->state, key_index);
501 return COMBO_KEY_REPRESSED;
502 }
503 }
504#endif
488 } else { 505 } else {
489 // chord releases 506 // chord releases
490 if (!COMBO_ACTIVE(combo) && ALL_COMBO_KEYS_ARE_DOWN(COMBO_STATE(combo), key_count)) { 507 if (!COMBO_ACTIVE(combo) && ALL_COMBO_KEYS_ARE_DOWN(COMBO_STATE(combo), key_count)) {
@@ -531,12 +548,12 @@ static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *
531 KEY_STATE_UP(combo->state, key_index); 548 KEY_STATE_UP(combo->state, key_index);
532 } 549 }
533 550
534 return key_is_part_of_combo; 551 return key_is_part_of_combo ? COMBO_KEY_PRESSED : COMBO_KEY_NOT_PRESSED;
535} 552}
536 553
537bool process_combo(uint16_t keycode, keyrecord_t *record) { 554bool process_combo(uint16_t keycode, keyrecord_t *record) {
538 bool is_combo_key = false; 555 uint8_t is_combo_key = COMBO_KEY_NOT_PRESSED;
539 bool no_combo_keys_pressed = true; 556 bool no_combo_keys_pressed = true;
540 557
541 if (keycode == QK_COMBO_ON && record->event.pressed) { 558 if (keycode == QK_COMBO_ON && record->event.pressed) {
542 combo_enable(); 559 combo_enable();
@@ -582,12 +599,17 @@ bool process_combo(uint16_t keycode, keyrecord_t *record) {
582# endif 599# endif
583#endif 600#endif
584 601
585 if (key_buffer_size < COMBO_KEY_BUFFER_LENGTH) { 602#ifdef COMBO_PROCESS_KEY_REPRESS
586 key_buffer[key_buffer_size++] = (queued_record_t){ 603 if (is_combo_key == COMBO_KEY_PRESSED)
587 .record = *record, 604#endif
588 .keycode = keycode, 605 {
589 .combo_index = -1, // this will be set when applying combos 606 if (key_buffer_size < COMBO_KEY_BUFFER_LENGTH) {
590 }; 607 key_buffer[key_buffer_size++] = (queued_record_t){
608 .record = *record,
609 .keycode = keycode,
610 .combo_index = -1, // this will be set when applying combos
611 };
612 }
591 } 613 }
592 } else { 614 } else {
593 if (combo_buffer_read != combo_buffer_write) { 615 if (combo_buffer_read != combo_buffer_write) {