summaryrefslogtreecommitdiff
path: root/quantum
diff options
context:
space:
mode:
authorPascal Getreuer <50221757+getreuer@users.noreply.github.com>2025-04-28 00:52:20 -0700
committerGitHub <noreply@github.com>2025-04-28 09:52:20 +0200
commitc26449e64f18940c0a57e459eeae465b26502b64 (patch)
tree3111fece85c3a533fab4a059305389b44e021936 /quantum
parent7fa65aa877db691ccba8fe38f407da91d250cc44 (diff)
[Core] Enhance Flow Tap to work better for rolls over multiple tap-hold keys. (#25200)
* Flow Tap revision for rolling press. * Remove debugging cruft. * Formatting fix.
Diffstat (limited to 'quantum')
-rw-r--r--quantum/action_tapping.c57
1 files changed, 45 insertions, 12 deletions
diff --git a/quantum/action_tapping.c b/quantum/action_tapping.c
index 3e391d1526..b105cd60a9 100644
--- a/quantum/action_tapping.c
+++ b/quantum/action_tapping.c
@@ -103,10 +103,11 @@ __attribute__((weak)) bool get_hold_on_other_key_press(uint16_t keycode, keyreco
103# endif 103# endif
104 104
105# if defined(FLOW_TAP_TERM) 105# if defined(FLOW_TAP_TERM)
106static uint32_t flow_tap_prev_time = 0;
107static uint16_t flow_tap_prev_keycode = KC_NO; 106static uint16_t flow_tap_prev_keycode = KC_NO;
107static uint16_t flow_tap_prev_time = 0;
108static bool flow_tap_expired = true;
108 109
109static bool flow_tap_key_if_within_term(keyrecord_t *record); 110static bool flow_tap_key_if_within_term(keyrecord_t *record, uint16_t prev_time);
110# endif // defined(FLOW_TAP_TERM) 111# endif // defined(FLOW_TAP_TERM)
111 112
112static keyrecord_t tapping_key = {}; 113static keyrecord_t tapping_key = {};
@@ -159,6 +160,12 @@ void action_tapping_process(keyrecord_t record) {
159 } 160 }
160 if (IS_EVENT(record.event)) { 161 if (IS_EVENT(record.event)) {
161 ac_dprintf("\n"); 162 ac_dprintf("\n");
163 } else {
164# ifdef FLOW_TAP_TERM
165 if (!flow_tap_expired && TIMER_DIFF_16(record.event.time, flow_tap_prev_time) >= INT16_MAX / 2) {
166 flow_tap_expired = true;
167 }
168# endif // FLOW_TAP_TERM
162 } 169 }
163} 170}
164 171
@@ -240,7 +247,7 @@ bool process_tapping(keyrecord_t *keyp) {
240 // into the "pressed" tapping key state 247 // into the "pressed" tapping key state
241 248
242# if defined(FLOW_TAP_TERM) 249# if defined(FLOW_TAP_TERM)
243 if (flow_tap_key_if_within_term(keyp)) { 250 if (flow_tap_key_if_within_term(keyp, flow_tap_prev_time)) {
244 return true; 251 return true;
245 } 252 }
246# endif // defined(FLOW_TAP_TERM) 253# endif // defined(FLOW_TAP_TERM)
@@ -281,6 +288,27 @@ bool process_tapping(keyrecord_t *keyp) {
281 288
282 // copy tapping state 289 // copy tapping state
283 keyp->tap = tapping_key.tap; 290 keyp->tap = tapping_key.tap;
291
292# if defined(FLOW_TAP_TERM)
293 // Now that tapping_key has settled as tapped, check whether
294 // Flow Tap applies to following yet-unsettled keys.
295 uint16_t prev_time = tapping_key.event.time;
296 for (; waiting_buffer_tail != waiting_buffer_head; waiting_buffer_tail = (waiting_buffer_tail + 1) % WAITING_BUFFER_SIZE) {
297 keyrecord_t *record = &waiting_buffer[waiting_buffer_tail];
298 if (!record->event.pressed) {
299 break;
300 }
301 const int16_t next_time = record->event.time;
302 if (!is_tap_record(record)) {
303 process_record(record);
304 } else if (!flow_tap_key_if_within_term(record, prev_time)) {
305 break;
306 }
307 prev_time = next_time;
308 }
309 debug_waiting_buffer();
310# endif // defined(FLOW_TAP_TERM)
311
284 // enqueue 312 // enqueue
285 return false; 313 return false;
286 } 314 }
@@ -557,7 +585,7 @@ bool process_tapping(keyrecord_t *keyp) {
557 } else if (is_tap_record(keyp)) { 585 } else if (is_tap_record(keyp)) {
558 // Sequential tap can be interfered with other tap key. 586 // Sequential tap can be interfered with other tap key.
559# if defined(FLOW_TAP_TERM) 587# if defined(FLOW_TAP_TERM)
560 if (flow_tap_key_if_within_term(keyp)) { 588 if (flow_tap_key_if_within_term(keyp, flow_tap_prev_time)) {
561 tapping_key = (keyrecord_t){0}; 589 tapping_key = (keyrecord_t){0};
562 debug_tapping_key(); 590 debug_tapping_key();
563 return true; 591 return true;
@@ -791,11 +819,11 @@ static void waiting_buffer_process_regular(void) {
791 819
792# ifdef FLOW_TAP_TERM 820# ifdef FLOW_TAP_TERM
793void flow_tap_update_last_event(keyrecord_t *record) { 821void flow_tap_update_last_event(keyrecord_t *record) {
822 const uint16_t keycode = get_record_keycode(record, false);
794 // Don't update while a tap-hold key is unsettled. 823 // Don't update while a tap-hold key is unsettled.
795 if (waiting_buffer_tail != waiting_buffer_head || (tapping_key.event.pressed && tapping_key.tap.count == 0)) { 824 if (record->tap.count == 0 && (waiting_buffer_tail != waiting_buffer_head || (tapping_key.event.pressed && tapping_key.tap.count == 0))) {
796 return; 825 return;
797 } 826 }
798 const uint16_t keycode = get_record_keycode(record, false);
799 // Ignore releases of modifiers and held layer switches. 827 // Ignore releases of modifiers and held layer switches.
800 if (!record->event.pressed) { 828 if (!record->event.pressed) {
801 switch (keycode) { 829 switch (keycode) {
@@ -826,20 +854,25 @@ void flow_tap_update_last_event(keyrecord_t *record) {
826 } 854 }
827 855
828 flow_tap_prev_keycode = keycode; 856 flow_tap_prev_keycode = keycode;
829 flow_tap_prev_time = timer_read32(); 857 flow_tap_prev_time = record->event.time;
858 flow_tap_expired = false;
830} 859}
831 860
832static bool flow_tap_key_if_within_term(keyrecord_t *record) { 861static bool flow_tap_key_if_within_term(keyrecord_t *record, uint16_t prev_time) {
862 const uint16_t idle_time = TIMER_DIFF_16(record->event.time, prev_time);
863 if (flow_tap_expired || idle_time >= 500) {
864 return false;
865 }
866
833 const uint16_t keycode = get_record_keycode(record, false); 867 const uint16_t keycode = get_record_keycode(record, false);
834 if (is_mt_or_lt(keycode)) { 868 if (is_mt_or_lt(keycode)) {
835 const uint32_t idle_time = timer_elapsed32(flow_tap_prev_time); 869 uint16_t term = get_flow_tap_term(keycode, record, flow_tap_prev_keycode);
836 uint16_t term = get_flow_tap_term(keycode, record, flow_tap_prev_keycode);
837 if (term > 500) { 870 if (term > 500) {
838 term = 500; 871 term = 500;
839 } 872 }
840 if (idle_time < 500 && idle_time < term) { 873 if (idle_time < term) {
841 debug_event(record->event); 874 debug_event(record->event);
842 ac_dprintf(" within flow tap term (%u < %u) considered a tap\n", (int16_t)idle_time, term); 875 ac_dprintf(" within flow tap term (%u < %u) considered a tap\n", idle_time, term);
843 record->tap.count = 1; 876 record->tap.count = 1;
844 registered_taps_add(record->event.key); 877 registered_taps_add(record->event.key);
845 debug_registered_taps(); 878 debug_registered_taps();