logo

qmk_firmware

custom branch of QMK firmware git clone https://anongit.hacktivis.me/git/qmk_firmware.git

action_tapping.c (37557B)


  1. #include <stdint.h>
  2. #include <stdbool.h>
  3. #include "action.h"
  4. #include "action_layer.h"
  5. #include "action_tapping.h"
  6. #include "action_util.h"
  7. #include "keycode.h"
  8. #include "quantum_keycodes.h"
  9. #include "timer.h"
  10. #ifndef NO_ACTION_TAPPING
  11. # if defined(IGNORE_MOD_TAP_INTERRUPT_PER_KEY)
  12. # error "IGNORE_MOD_TAP_INTERRUPT_PER_KEY has been removed; the code needs to be ported to use HOLD_ON_OTHER_KEY_PRESS_PER_KEY instead."
  13. # elif defined(IGNORE_MOD_TAP_INTERRUPT)
  14. # error "IGNORE_MOD_TAP_INTERRUPT is no longer necessary as it is now the default behavior of mod-tap keys. Please remove it from your config."
  15. # endif
  16. # ifndef COMBO_ENABLE
  17. # define IS_TAPPING_RECORD(r) (KEYEQ(tapping_key.event.key, (r->event.key)))
  18. # else
  19. # define IS_TAPPING_RECORD(r) (KEYEQ(tapping_key.event.key, (r->event.key)) && tapping_key.keycode == r->keycode)
  20. # endif
  21. # define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < GET_TAPPING_TERM(get_record_keycode(&tapping_key, false), &tapping_key))
  22. # define WITHIN_QUICK_TAP_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < GET_QUICK_TAP_TERM(get_record_keycode(&tapping_key, false), &tapping_key))
  23. # ifdef DYNAMIC_TAPPING_TERM_ENABLE
  24. uint16_t g_tapping_term = TAPPING_TERM;
  25. # endif
  26. # ifdef TAPPING_TERM_PER_KEY
  27. __attribute__((weak)) uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) {
  28. # ifdef DYNAMIC_TAPPING_TERM_ENABLE
  29. return g_tapping_term;
  30. # else
  31. return TAPPING_TERM;
  32. # endif
  33. }
  34. # endif
  35. # ifdef QUICK_TAP_TERM_PER_KEY
  36. __attribute__((weak)) uint16_t get_quick_tap_term(uint16_t keycode, keyrecord_t *record) {
  37. return QUICK_TAP_TERM;
  38. }
  39. # endif
  40. # ifdef PERMISSIVE_HOLD_PER_KEY
  41. __attribute__((weak)) bool get_permissive_hold(uint16_t keycode, keyrecord_t *record) {
  42. return false;
  43. }
  44. # endif
  45. # if defined(CHORDAL_HOLD) || defined(FLOW_TAP_TERM)
  46. # define REGISTERED_TAPS_SIZE 8
  47. // Array of tap-hold keys that have been settled as tapped but not yet released.
  48. static keypos_t registered_taps[REGISTERED_TAPS_SIZE] = {};
  49. static uint8_t num_registered_taps = 0;
  50. /** Adds `key` to the registered_taps array. */
  51. static void registered_taps_add(keypos_t key);
  52. /** Returns the index of `key` in registered_taps, or -1 if not found. */
  53. static int8_t registered_tap_find(keypos_t key);
  54. /** Removes index `i` from the registered_taps array. */
  55. static void registered_taps_del_index(uint8_t i);
  56. /** Logs the registered_taps array for debugging. */
  57. static void debug_registered_taps(void);
  58. static bool is_mt_or_lt(uint16_t keycode) {
  59. return IS_QK_MOD_TAP(keycode) || IS_QK_LAYER_TAP(keycode);
  60. }
  61. # endif // defined(CHORDAL_HOLD) || defined(FLOW_TAP_TERM)
  62. # if defined(CHORDAL_HOLD)
  63. extern const char chordal_hold_layout[MATRIX_ROWS][MATRIX_COLS] PROGMEM;
  64. /** \brief Finds which queued events should be held according to Chordal Hold.
  65. *
  66. * In a situation with multiple unsettled tap-hold key presses, scan the queue
  67. * up until the first release, non-tap-hold, or one-shot event and find the
  68. * latest event in the queue that settles as held according to
  69. * get_chordal_hold().
  70. *
  71. * \return Index of the first tap, or equivalently, one past the latest hold.
  72. */
  73. static uint8_t waiting_buffer_find_chordal_hold_tap(void);
  74. /** Processes queued events up to and including `key` as tapped. */
  75. static void waiting_buffer_chordal_hold_taps_until(keypos_t key);
  76. /** \brief Processes and pops buffered events until the first tap-hold event. */
  77. static void waiting_buffer_process_regular(void);
  78. # endif // CHORDAL_HOLD
  79. # ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY
  80. __attribute__((weak)) bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) {
  81. return false;
  82. }
  83. # endif
  84. # if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)
  85. # include "process_auto_shift.h"
  86. # endif
  87. # if defined(FLOW_TAP_TERM)
  88. static uint16_t flow_tap_prev_keycode = KC_NO;
  89. static uint16_t flow_tap_prev_time = 0;
  90. static bool flow_tap_expired = true;
  91. static bool flow_tap_key_if_within_term(keyrecord_t *record, uint16_t prev_time);
  92. # endif // defined(FLOW_TAP_TERM)
  93. static keyrecord_t tapping_key = {};
  94. static keyrecord_t waiting_buffer[WAITING_BUFFER_SIZE] = {};
  95. static uint8_t waiting_buffer_head = 0;
  96. static uint8_t waiting_buffer_tail = 0;
  97. static bool process_tapping(keyrecord_t *record);
  98. static bool waiting_buffer_enq(keyrecord_t record);
  99. static void waiting_buffer_clear(void);
  100. static bool waiting_buffer_typed(keyevent_t event);
  101. static bool waiting_buffer_has_anykey_pressed(void);
  102. static void waiting_buffer_scan_tap(void);
  103. static void debug_tapping_key(void);
  104. static void debug_waiting_buffer(void);
  105. /** \brief Action Tapping Process
  106. *
  107. * FIXME: Needs doc
  108. */
  109. void action_tapping_process(keyrecord_t record) {
  110. if (process_tapping(&record)) {
  111. if (IS_EVENT(record.event)) {
  112. ac_dprintf("processed: ");
  113. debug_record(record);
  114. ac_dprintf("\n");
  115. }
  116. } else {
  117. if (!waiting_buffer_enq(record)) {
  118. // clear all in case of overflow.
  119. ac_dprintf("OVERFLOW: CLEAR ALL STATES\n");
  120. clear_keyboard();
  121. waiting_buffer_clear();
  122. tapping_key = (keyrecord_t){0};
  123. }
  124. }
  125. // process waiting_buffer
  126. if (IS_EVENT(record.event) && waiting_buffer_head != waiting_buffer_tail) {
  127. ac_dprintf("---- action_exec: process waiting_buffer -----\n");
  128. }
  129. for (; waiting_buffer_tail != waiting_buffer_head; waiting_buffer_tail = (waiting_buffer_tail + 1) % WAITING_BUFFER_SIZE) {
  130. if (process_tapping(&waiting_buffer[waiting_buffer_tail])) {
  131. ac_dprintf("processed: waiting_buffer[%u] =", waiting_buffer_tail);
  132. debug_record(waiting_buffer[waiting_buffer_tail]);
  133. ac_dprintf("\n\n");
  134. } else {
  135. break;
  136. }
  137. }
  138. if (IS_EVENT(record.event)) {
  139. ac_dprintf("\n");
  140. } else {
  141. # ifdef FLOW_TAP_TERM
  142. if (!flow_tap_expired && TIMER_DIFF_16(record.event.time, flow_tap_prev_time) >= INT16_MAX / 2) {
  143. flow_tap_expired = true;
  144. }
  145. # endif // FLOW_TAP_TERM
  146. }
  147. }
  148. /* Some conditionally defined helper macros to keep process_tapping more
  149. * readable. The conditional definition of tapping_keycode and all the
  150. * conditional uses of it are hidden inside macros named TAP_...
  151. */
  152. # define TAP_DEFINE_KEYCODE const uint16_t tapping_keycode = get_record_keycode(&tapping_key, false)
  153. # if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)
  154. # ifdef RETRO_TAPPING_PER_KEY
  155. # define TAP_GET_RETRO_TAPPING(keyp) get_auto_shifted_key(tapping_keycode, keyp) && get_retro_tapping(tapping_keycode, &tapping_key)
  156. # else
  157. # define TAP_GET_RETRO_TAPPING(keyp) get_auto_shifted_key(tapping_keycode, keyp)
  158. # endif
  159. /* Used to extend TAPPING_TERM:
  160. * indefinitely if RETRO_SHIFT does not have a value
  161. * to RETRO_SHIFT if RETRO_SHIFT is set
  162. * for possibly retro shifted keys.
  163. */
  164. # define MAYBE_RETRO_SHIFTING(ev, keyp) (get_auto_shifted_key(tapping_keycode, keyp) && TAP_GET_RETRO_TAPPING(keyp) && ((RETRO_SHIFT + 0) == 0 || TIMER_DIFF_16((ev).time, tapping_key.event.time) < (RETRO_SHIFT + 0)))
  165. # define TAP_IS_LT IS_QK_LAYER_TAP(tapping_keycode)
  166. # define TAP_IS_MT IS_QK_MOD_TAP(tapping_keycode)
  167. # define TAP_IS_RETRO IS_RETRO(tapping_keycode)
  168. # else
  169. # define TAP_GET_RETRO_TAPPING(keyp) false
  170. # define MAYBE_RETRO_SHIFTING(ev, kp) false
  171. # define TAP_IS_LT false
  172. # define TAP_IS_MT false
  173. # define TAP_IS_RETRO false
  174. # endif
  175. # ifdef PERMISSIVE_HOLD_PER_KEY
  176. # define TAP_GET_PERMISSIVE_HOLD get_permissive_hold(tapping_keycode, &tapping_key)
  177. # elif defined(PERMISSIVE_HOLD)
  178. # define TAP_GET_PERMISSIVE_HOLD true
  179. # else
  180. # define TAP_GET_PERMISSIVE_HOLD false
  181. # endif
  182. # ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY
  183. # define TAP_GET_HOLD_ON_OTHER_KEY_PRESS get_hold_on_other_key_press(tapping_keycode, &tapping_key)
  184. # elif defined(HOLD_ON_OTHER_KEY_PRESS)
  185. # define TAP_GET_HOLD_ON_OTHER_KEY_PRESS true
  186. # else
  187. # define TAP_GET_HOLD_ON_OTHER_KEY_PRESS false
  188. # endif
  189. /** \brief Tapping
  190. *
  191. * Rule: Tap key is typed(pressed and released) within TAPPING_TERM.
  192. * (without interfering by typing other key)
  193. */
  194. /* return true when key event is processed or consumed. */
  195. bool process_tapping(keyrecord_t *keyp) {
  196. const keyevent_t event = keyp->event;
  197. # if defined(CHORDAL_HOLD) || defined(FLOW_TAP_TERM)
  198. if (!event.pressed) {
  199. const int8_t i = registered_tap_find(event.key);
  200. if (i != -1) {
  201. // If a tap-hold key was previously settled as tapped, set its
  202. // tap.count correspondingly on release.
  203. keyp->tap.count = 1;
  204. registered_taps_del_index(i);
  205. ac_dprintf("Found tap release for [%d]\n", i);
  206. debug_registered_taps();
  207. }
  208. }
  209. # endif // defined(CHORDAL_HOLD) || defined(FLOW_TAP_TERM)
  210. // state machine is in the "reset" state, no tapping key is to be
  211. // processed
  212. if (IS_NOEVENT(tapping_key.event)) {
  213. if (!IS_EVENT(event)) {
  214. // early return for tick events
  215. } else if (event.pressed && is_tap_record(keyp)) {
  216. // the currently pressed key is a tapping key, therefore transition
  217. // into the "pressed" tapping key state
  218. # if defined(FLOW_TAP_TERM)
  219. if (flow_tap_key_if_within_term(keyp, flow_tap_prev_time)) {
  220. return true;
  221. }
  222. # endif // defined(FLOW_TAP_TERM)
  223. ac_dprintf("Tapping: Start(Press tap key).\n");
  224. tapping_key = *keyp;
  225. process_record_tap_hint(&tapping_key);
  226. waiting_buffer_scan_tap();
  227. debug_tapping_key();
  228. } else {
  229. // the current key is just a regular key, pass it on for regular
  230. // processing
  231. process_record(keyp);
  232. }
  233. return true;
  234. }
  235. # if (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)) || defined(PERMISSIVE_HOLD_PER_KEY) || defined(CHORDAL_HOLD) || defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY)
  236. TAP_DEFINE_KEYCODE;
  237. # endif
  238. // process "pressed" tapping key state
  239. if (tapping_key.event.pressed) {
  240. if (WITHIN_TAPPING_TERM(event) || MAYBE_RETRO_SHIFTING(event, keyp)) {
  241. if (IS_NOEVENT(event)) {
  242. // early return for tick events
  243. return true;
  244. }
  245. if (tapping_key.tap.count == 0) {
  246. if (IS_TAPPING_RECORD(keyp) && !event.pressed) {
  247. // first tap!
  248. ac_dprintf("Tapping: First tap(0->1).\n");
  249. tapping_key.tap.count = 1;
  250. debug_tapping_key();
  251. process_record(&tapping_key);
  252. // copy tapping state
  253. keyp->tap = tapping_key.tap;
  254. # if defined(FLOW_TAP_TERM)
  255. // Now that tapping_key has settled as tapped, check whether
  256. // Flow Tap applies to following yet-unsettled keys.
  257. uint16_t prev_time = tapping_key.event.time;
  258. for (; waiting_buffer_tail != waiting_buffer_head; waiting_buffer_tail = (waiting_buffer_tail + 1) % WAITING_BUFFER_SIZE) {
  259. keyrecord_t *record = &waiting_buffer[waiting_buffer_tail];
  260. if (!record->event.pressed) {
  261. break;
  262. }
  263. const int16_t next_time = record->event.time;
  264. if (!is_tap_record(record)) {
  265. process_record(record);
  266. } else if (!flow_tap_key_if_within_term(record, prev_time)) {
  267. break;
  268. }
  269. prev_time = next_time;
  270. }
  271. debug_waiting_buffer();
  272. # endif // defined(FLOW_TAP_TERM)
  273. // enqueue
  274. return false;
  275. }
  276. # if defined(CHORDAL_HOLD)
  277. else if (is_mt_or_lt(tapping_keycode) && !event.pressed && waiting_buffer_typed(event) && !get_chordal_hold(tapping_keycode, &tapping_key, get_record_keycode(keyp, false), keyp)) {
  278. // Key release that is not a chord with the tapping key.
  279. // Settle the tapping key and any other pending tap-hold
  280. // keys preceding the press of this key as tapped.
  281. ac_dprintf("Tapping: End. Chord considered a tap\n");
  282. tapping_key.tap.count = 1;
  283. registered_taps_add(tapping_key.event.key);
  284. process_record(&tapping_key);
  285. tapping_key = (keyrecord_t){0};
  286. waiting_buffer_chordal_hold_taps_until(event.key);
  287. debug_registered_taps();
  288. debug_waiting_buffer();
  289. // enqueue
  290. return false;
  291. }
  292. # endif // CHORDAL_HOLD
  293. /* Process a key typed within TAPPING_TERM
  294. * This can register the key before settlement of tapping,
  295. * useful for long TAPPING_TERM but may prevent fast typing.
  296. */
  297. // clang-format off
  298. else if (
  299. !event.pressed && waiting_buffer_typed(event) &&
  300. (
  301. TAP_GET_PERMISSIVE_HOLD ||
  302. // Causes nested taps to not wait past TAPPING_TERM/RETRO_SHIFT
  303. // unnecessarily and fixes them for Layer Taps.
  304. TAP_GET_RETRO_TAPPING(keyp)
  305. )
  306. ) {
  307. // clang-format on
  308. ac_dprintf("Tapping: End. No tap. Interfered by typing key\n");
  309. process_record(&tapping_key);
  310. # if defined(CHORDAL_HOLD)
  311. uint8_t first_tap = waiting_buffer_find_chordal_hold_tap();
  312. ac_dprintf("first_tap = %u\n", first_tap);
  313. if (first_tap < WAITING_BUFFER_SIZE) {
  314. for (; waiting_buffer_tail != first_tap; waiting_buffer_tail = (waiting_buffer_tail + 1) % WAITING_BUFFER_SIZE) {
  315. ac_dprintf("Processing [%u]\n", waiting_buffer_tail);
  316. process_record(&waiting_buffer[waiting_buffer_tail]);
  317. }
  318. }
  319. waiting_buffer_chordal_hold_taps_until(event.key);
  320. debug_registered_taps();
  321. debug_waiting_buffer();
  322. # endif // CHORDAL_HOLD
  323. tapping_key = (keyrecord_t){0};
  324. debug_tapping_key();
  325. // enqueue
  326. return false;
  327. }
  328. /* Process release event of a key pressed before tapping starts
  329. * Without this unexpected repeating will occur with having fast repeating setting
  330. * https://github.com/tmk/tmk_keyboard/issues/60
  331. *
  332. * NOTE: This workaround causes events to process out of order,
  333. * e.g. in a rolled press of three tap-hold keys like
  334. *
  335. * "A down, B down, C down, A up, B up, C up"
  336. *
  337. * events are processed as
  338. *
  339. * "A down, B down, A up, B up, C down, C up"
  340. *
  341. * It seems incorrect to process keyp before the tapping key.
  342. * This workaround is old, from 2013. This might no longer
  343. * be needed for the original problem it was meant to address.
  344. */
  345. else if (!event.pressed && !waiting_buffer_typed(event)) {
  346. // Modifier/Layer should be retained till end of this tapping.
  347. action_t action = layer_switch_get_action(event.key);
  348. switch (action.kind.id) {
  349. case ACT_LMODS:
  350. case ACT_RMODS:
  351. if (action.key.mods && !action.key.code) return false;
  352. if (IS_MODIFIER_KEYCODE(action.key.code)) return false;
  353. break;
  354. case ACT_LMODS_TAP:
  355. case ACT_RMODS_TAP:
  356. if (action.key.mods && keyp->tap.count == 0) return false;
  357. if (IS_MODIFIER_KEYCODE(action.key.code)) return false;
  358. break;
  359. case ACT_LAYER_TAP:
  360. case ACT_LAYER_TAP_EXT:
  361. switch (action.layer_tap.code) {
  362. case 0 ...(OP_TAP_TOGGLE - 1):
  363. case OP_ON_OFF:
  364. case OP_OFF_ON:
  365. case OP_SET_CLEAR:
  366. return false;
  367. }
  368. break;
  369. }
  370. // Release of key should be process immediately.
  371. ac_dprintf("Tapping: release event of a key pressed before tapping\n");
  372. process_record(keyp);
  373. return true;
  374. } else {
  375. // set interrupted flag when other key pressed during tapping
  376. if (event.pressed) {
  377. tapping_key.tap.interrupted = true;
  378. # if defined(CHORDAL_HOLD)
  379. if (is_mt_or_lt(tapping_keycode) && !get_chordal_hold(tapping_keycode, &tapping_key, get_record_keycode(keyp, false), keyp)) {
  380. // In process_action(), HOLD_ON_OTHER_KEY_PRESS
  381. // will revert interrupted events to holds, so
  382. // this needs to be set false.
  383. tapping_key.tap.interrupted = false;
  384. if (!is_tap_record(keyp)) {
  385. ac_dprintf("Tapping: End. Chord considered a tap\n");
  386. tapping_key.tap.count = 1;
  387. registered_taps_add(tapping_key.event.key);
  388. debug_registered_taps();
  389. process_record(&tapping_key);
  390. tapping_key = (keyrecord_t){0};
  391. }
  392. } else
  393. # endif // CHORDAL_HOLD
  394. if (TAP_GET_HOLD_ON_OTHER_KEY_PRESS
  395. # if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)
  396. // Auto Shift cannot evaluate this early
  397. // Retro Shift uses the hold action for all nested taps even without HOLD_ON_OTHER_KEY_PRESS, so this is fine to skip
  398. && !(MAYBE_RETRO_SHIFTING(event, keyp) && get_auto_shifted_key(get_record_keycode(keyp, false), keyp))
  399. # endif
  400. ) {
  401. // Settle the tapping key as *held*, since
  402. // HOLD_ON_OTHER_KEY_PRESS is enabled for this key.
  403. ac_dprintf("Tapping: End. No tap. Interfered by pressed key\n");
  404. process_record(&tapping_key);
  405. # if defined(CHORDAL_HOLD)
  406. if (waiting_buffer_tail != waiting_buffer_head && is_tap_record(&waiting_buffer[waiting_buffer_tail])) {
  407. tapping_key = waiting_buffer[waiting_buffer_tail];
  408. // Pop tail from the queue.
  409. waiting_buffer_tail = (waiting_buffer_tail + 1) % WAITING_BUFFER_SIZE;
  410. debug_waiting_buffer();
  411. } else
  412. # endif // CHORDAL_HOLD
  413. {
  414. tapping_key = (keyrecord_t){0};
  415. }
  416. debug_tapping_key();
  417. # if defined(CHORDAL_HOLD)
  418. waiting_buffer_process_regular();
  419. # endif // CHORDAL_HOLD
  420. }
  421. }
  422. // enqueue
  423. return false;
  424. }
  425. }
  426. // tap_count > 0
  427. else {
  428. if (IS_TAPPING_RECORD(keyp) && !event.pressed) {
  429. ac_dprintf("Tapping: Tap release(%u)\n", tapping_key.tap.count);
  430. keyp->tap = tapping_key.tap;
  431. process_record(keyp);
  432. tapping_key = *keyp;
  433. debug_tapping_key();
  434. return true;
  435. } else if (is_tap_record(keyp) && event.pressed) {
  436. if (tapping_key.tap.count > 1) {
  437. ac_dprintf("Tapping: Start new tap with releasing last tap(>1).\n");
  438. // unregister key
  439. process_record(&(keyrecord_t){
  440. .tap = tapping_key.tap,
  441. .event.key = tapping_key.event.key,
  442. .event.time = event.time,
  443. .event.pressed = false,
  444. .event.type = tapping_key.event.type,
  445. # ifdef COMBO_ENABLE
  446. .keycode = tapping_key.keycode,
  447. # endif
  448. });
  449. } else {
  450. ac_dprintf("Tapping: Start while last tap(1).\n");
  451. }
  452. tapping_key = *keyp;
  453. waiting_buffer_scan_tap();
  454. debug_tapping_key();
  455. return true;
  456. } else {
  457. ac_dprintf("Tapping: key event while last tap(>0).\n");
  458. # if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)
  459. retroshift_swap_times();
  460. # endif
  461. process_record(keyp);
  462. return true;
  463. }
  464. }
  465. }
  466. // after TAPPING_TERM
  467. else {
  468. if (tapping_key.tap.count == 0) {
  469. ac_dprintf("Tapping: End. Timeout. Not tap(0): ");
  470. debug_event(event);
  471. ac_dprintf("\n");
  472. process_record(&tapping_key);
  473. tapping_key = (keyrecord_t){0};
  474. debug_tapping_key();
  475. return false;
  476. } else {
  477. if (IS_NOEVENT(event)) {
  478. return true;
  479. }
  480. if (IS_TAPPING_RECORD(keyp) && !event.pressed) {
  481. ac_dprintf("Tapping: End. last timeout tap release(>0).");
  482. keyp->tap = tapping_key.tap;
  483. process_record(keyp);
  484. tapping_key = (keyrecord_t){0};
  485. return true;
  486. } else if (is_tap_record(keyp) && event.pressed) {
  487. if (tapping_key.tap.count > 1) {
  488. ac_dprintf("Tapping: Start new tap with releasing last timeout tap(>1).\n");
  489. // unregister key
  490. process_record(&(keyrecord_t){
  491. .tap = tapping_key.tap,
  492. .event.key = tapping_key.event.key,
  493. .event.time = event.time,
  494. .event.pressed = false,
  495. .event.type = tapping_key.event.type,
  496. # ifdef COMBO_ENABLE
  497. .keycode = tapping_key.keycode,
  498. # endif
  499. });
  500. } else {
  501. ac_dprintf("Tapping: Start while last timeout tap(1).\n");
  502. }
  503. tapping_key = *keyp;
  504. waiting_buffer_scan_tap();
  505. debug_tapping_key();
  506. return true;
  507. } else {
  508. ac_dprintf("Tapping: key event while last timeout tap(>0).\n");
  509. process_record(keyp);
  510. return true;
  511. }
  512. }
  513. }
  514. }
  515. // process "released" tapping key state
  516. else {
  517. if (WITHIN_TAPPING_TERM(event) || MAYBE_RETRO_SHIFTING(event, keyp)) {
  518. if (IS_NOEVENT(event)) {
  519. // early return for tick events
  520. return true;
  521. }
  522. if (event.pressed) {
  523. if (IS_TAPPING_RECORD(keyp)) {
  524. if (WITHIN_QUICK_TAP_TERM(event) && !tapping_key.tap.interrupted && tapping_key.tap.count > 0) {
  525. // sequential tap.
  526. keyp->tap = tapping_key.tap;
  527. if (keyp->tap.count < 15) keyp->tap.count += 1;
  528. ac_dprintf("Tapping: Tap press(%u)\n", keyp->tap.count);
  529. process_record(keyp);
  530. tapping_key = *keyp;
  531. debug_tapping_key();
  532. return true;
  533. }
  534. // FIX: start new tap again
  535. tapping_key = *keyp;
  536. return true;
  537. } else if (is_tap_record(keyp)) {
  538. // Sequential tap can be interfered with other tap key.
  539. # if defined(FLOW_TAP_TERM)
  540. if (flow_tap_key_if_within_term(keyp, flow_tap_prev_time)) {
  541. tapping_key = (keyrecord_t){0};
  542. debug_tapping_key();
  543. return true;
  544. }
  545. # endif // defined(FLOW_TAP_TERM)
  546. ac_dprintf("Tapping: Start with interfering other tap.\n");
  547. tapping_key = *keyp;
  548. waiting_buffer_scan_tap();
  549. debug_tapping_key();
  550. return true;
  551. } else {
  552. // should none in buffer
  553. // FIX: interrupted when other key is pressed
  554. tapping_key.tap.interrupted = true;
  555. process_record(keyp);
  556. return true;
  557. }
  558. } else {
  559. ac_dprintf("Tapping: other key just after tap.\n");
  560. process_record(keyp);
  561. return true;
  562. }
  563. } else {
  564. // Timeout - reset state machine.
  565. ac_dprintf("Tapping: End(Timeout after releasing last tap): ");
  566. debug_event(event);
  567. ac_dprintf("\n");
  568. tapping_key = (keyrecord_t){0};
  569. debug_tapping_key();
  570. return false;
  571. }
  572. }
  573. }
  574. /** \brief Waiting buffer enq
  575. *
  576. * FIXME: Needs docs
  577. */
  578. bool waiting_buffer_enq(keyrecord_t record) {
  579. if (IS_NOEVENT(record.event)) {
  580. return true;
  581. }
  582. if ((waiting_buffer_head + 1) % WAITING_BUFFER_SIZE == waiting_buffer_tail) {
  583. ac_dprintf("waiting_buffer_enq: Over flow.\n");
  584. return false;
  585. }
  586. waiting_buffer[waiting_buffer_head] = record;
  587. waiting_buffer_head = (waiting_buffer_head + 1) % WAITING_BUFFER_SIZE;
  588. ac_dprintf("waiting_buffer_enq: ");
  589. debug_waiting_buffer();
  590. return true;
  591. }
  592. /** \brief Waiting buffer clear
  593. *
  594. * FIXME: Needs docs
  595. */
  596. void waiting_buffer_clear(void) {
  597. waiting_buffer_head = 0;
  598. waiting_buffer_tail = 0;
  599. }
  600. /** \brief Waiting buffer typed
  601. *
  602. * FIXME: Needs docs
  603. */
  604. bool waiting_buffer_typed(keyevent_t event) {
  605. for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
  606. if (KEYEQ(event.key, waiting_buffer[i].event.key) && event.pressed != waiting_buffer[i].event.pressed) {
  607. return true;
  608. }
  609. }
  610. return false;
  611. }
  612. /** \brief Waiting buffer has anykey pressed
  613. *
  614. * FIXME: Needs docs
  615. */
  616. __attribute__((unused)) bool waiting_buffer_has_anykey_pressed(void) {
  617. for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
  618. if (waiting_buffer[i].event.pressed) return true;
  619. }
  620. return false;
  621. }
  622. /** \brief Scan buffer for tapping
  623. *
  624. * FIXME: Needs docs
  625. */
  626. void waiting_buffer_scan_tap(void) {
  627. // early return if:
  628. // - tapping already is settled
  629. // - invalid state: tapping_key released && tap.count == 0
  630. if ((tapping_key.tap.count > 0) || !tapping_key.event.pressed) {
  631. return;
  632. }
  633. # if (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT))
  634. TAP_DEFINE_KEYCODE;
  635. # endif
  636. for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
  637. keyrecord_t *candidate = &waiting_buffer[i];
  638. // clang-format off
  639. if (IS_EVENT(candidate->event) && KEYEQ(candidate->event.key, tapping_key.event.key) && !candidate->event.pressed && (
  640. WITHIN_TAPPING_TERM(waiting_buffer[i].event) || MAYBE_RETRO_SHIFTING(waiting_buffer[i].event, &tapping_key)
  641. )) {
  642. // clang-format on
  643. tapping_key.tap.count = 1;
  644. candidate->tap.count = 1;
  645. process_record(&tapping_key);
  646. ac_dprintf("waiting_buffer_scan_tap: found at [%u]\n", i);
  647. debug_waiting_buffer();
  648. return;
  649. }
  650. }
  651. }
  652. # if defined(CHORDAL_HOLD) || defined(FLOW_TAP_TERM)
  653. static void registered_taps_add(keypos_t key) {
  654. if (num_registered_taps >= REGISTERED_TAPS_SIZE) {
  655. ac_dprintf("TAPS OVERFLOW: CLEAR ALL STATES\n");
  656. clear_keyboard();
  657. num_registered_taps = 0;
  658. }
  659. registered_taps[num_registered_taps] = key;
  660. ++num_registered_taps;
  661. }
  662. static int8_t registered_tap_find(keypos_t key) {
  663. for (int8_t i = 0; i < num_registered_taps; ++i) {
  664. if (KEYEQ(registered_taps[i], key)) {
  665. return i;
  666. }
  667. }
  668. return -1;
  669. }
  670. static void registered_taps_del_index(uint8_t i) {
  671. if (i < num_registered_taps) {
  672. --num_registered_taps;
  673. if (i < num_registered_taps) {
  674. registered_taps[i] = registered_taps[num_registered_taps];
  675. }
  676. }
  677. }
  678. static void debug_registered_taps(void) {
  679. ac_dprintf("registered_taps = { ");
  680. for (int8_t i = 0; i < num_registered_taps; ++i) {
  681. ac_dprintf("%02X%02X ", registered_taps[i].row, registered_taps[i].col);
  682. }
  683. ac_dprintf("}\n");
  684. }
  685. # endif // defined(CHORDAL_HOLD) || defined(FLOW_TAP_TERM)
  686. # ifdef CHORDAL_HOLD
  687. __attribute__((weak)) bool get_chordal_hold(uint16_t tap_hold_keycode, keyrecord_t *tap_hold_record, uint16_t other_keycode, keyrecord_t *other_record) {
  688. return get_chordal_hold_default(tap_hold_record, other_record);
  689. }
  690. bool get_chordal_hold_default(keyrecord_t *tap_hold_record, keyrecord_t *other_record) {
  691. if (tap_hold_record->event.type != KEY_EVENT || other_record->event.type != KEY_EVENT) {
  692. return true; // Return true on combos or other non-key events.
  693. }
  694. char tap_hold_hand = chordal_hold_handedness(tap_hold_record->event.key);
  695. if (tap_hold_hand == '*') {
  696. return true;
  697. }
  698. char other_hand = chordal_hold_handedness(other_record->event.key);
  699. return other_hand == '*' || tap_hold_hand != other_hand;
  700. }
  701. __attribute__((weak)) char chordal_hold_handedness(keypos_t key) {
  702. return (char)pgm_read_byte(&chordal_hold_layout[key.row][key.col]);
  703. }
  704. static uint8_t waiting_buffer_find_chordal_hold_tap(void) {
  705. keyrecord_t *prev = &tapping_key;
  706. uint16_t prev_keycode = get_record_keycode(&tapping_key, false);
  707. uint8_t first_tap = WAITING_BUFFER_SIZE;
  708. for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
  709. keyrecord_t * cur = &waiting_buffer[i];
  710. const uint16_t cur_keycode = get_record_keycode(cur, false);
  711. if (!cur->event.pressed || !is_mt_or_lt(prev_keycode)) {
  712. break;
  713. } else if (get_chordal_hold(prev_keycode, prev, cur_keycode, cur)) {
  714. first_tap = i; // Track one index past the latest hold.
  715. }
  716. prev = cur;
  717. prev_keycode = cur_keycode;
  718. }
  719. return first_tap;
  720. }
  721. static void waiting_buffer_chordal_hold_taps_until(keypos_t key) {
  722. while (waiting_buffer_tail != waiting_buffer_head) {
  723. keyrecord_t *record = &waiting_buffer[waiting_buffer_tail];
  724. ac_dprintf("waiting_buffer_chordal_hold_taps_until: processing [%u]\n", waiting_buffer_tail);
  725. if (record->event.pressed && is_tap_record(record)) {
  726. record->tap.count = 1;
  727. registered_taps_add(record->event.key);
  728. }
  729. process_record(record);
  730. waiting_buffer_tail = (waiting_buffer_tail + 1) % WAITING_BUFFER_SIZE;
  731. if (KEYEQ(key, record->event.key) && record->event.pressed) {
  732. break;
  733. }
  734. }
  735. }
  736. static void waiting_buffer_process_regular(void) {
  737. for (; waiting_buffer_tail != waiting_buffer_head; waiting_buffer_tail = (waiting_buffer_tail + 1) % WAITING_BUFFER_SIZE) {
  738. if (is_tap_record(&waiting_buffer[waiting_buffer_tail])) {
  739. break; // Stop once a tap-hold key event is reached.
  740. }
  741. ac_dprintf("waiting_buffer_process_regular: processing [%u]\n", waiting_buffer_tail);
  742. process_record(&waiting_buffer[waiting_buffer_tail]);
  743. }
  744. debug_waiting_buffer();
  745. }
  746. # endif // CHORDAL_HOLD
  747. # ifdef FLOW_TAP_TERM
  748. void flow_tap_update_last_event(keyrecord_t *record) {
  749. const uint16_t keycode = get_record_keycode(record, false);
  750. // Don't update while a tap-hold key is unsettled.
  751. if (record->tap.count == 0 && (waiting_buffer_tail != waiting_buffer_head || (tapping_key.event.pressed && tapping_key.tap.count == 0))) {
  752. return;
  753. }
  754. // Ignore releases of modifiers and held layer switches.
  755. if (!record->event.pressed) {
  756. switch (keycode) {
  757. case MODIFIER_KEYCODE_RANGE:
  758. case QK_MOMENTARY ... QK_MOMENTARY_MAX:
  759. case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX:
  760. # ifndef NO_ACTION_ONESHOT // Ignore one-shot keys.
  761. case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX:
  762. case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX:
  763. # endif // NO_ACTION_ONESHOT
  764. # ifdef TRI_LAYER_ENABLE // Ignore Tri Layer keys.
  765. case QK_TRI_LAYER_LOWER:
  766. case QK_TRI_LAYER_UPPER:
  767. # endif // TRI_LAYER_ENABLE
  768. return;
  769. case QK_MODS ... QK_MODS_MAX:
  770. if (QK_MODS_GET_BASIC_KEYCODE(keycode) == KC_NO) {
  771. return;
  772. }
  773. break;
  774. case QK_MOD_TAP ... QK_MOD_TAP_MAX:
  775. case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
  776. if (record->tap.count == 0) {
  777. return;
  778. }
  779. break;
  780. }
  781. }
  782. flow_tap_prev_keycode = keycode;
  783. flow_tap_prev_time = record->event.time;
  784. flow_tap_expired = false;
  785. }
  786. static bool flow_tap_key_if_within_term(keyrecord_t *record, uint16_t prev_time) {
  787. const uint16_t idle_time = TIMER_DIFF_16(record->event.time, prev_time);
  788. if (flow_tap_expired || idle_time >= 500) {
  789. return false;
  790. }
  791. const uint16_t keycode = get_record_keycode(record, false);
  792. if (is_mt_or_lt(keycode)) {
  793. uint16_t term = get_flow_tap_term(keycode, record, flow_tap_prev_keycode);
  794. if (term > 500) {
  795. term = 500;
  796. }
  797. if (idle_time < term) {
  798. debug_event(record->event);
  799. ac_dprintf(" within flow tap term (%u < %u) considered a tap\n", idle_time, term);
  800. record->tap.count = 1;
  801. registered_taps_add(record->event.key);
  802. debug_registered_taps();
  803. process_record(record);
  804. return true;
  805. }
  806. }
  807. return false;
  808. }
  809. // By default, enable Flow Tap for the keys in the main alphas area and Space.
  810. // This should work reasonably even if the layout is remapped on the host to an
  811. // alt layout or international layout (e.g. Dvorak or AZERTY), where these same
  812. // key positions are mostly used for typing letters.
  813. __attribute__((weak)) bool is_flow_tap_key(uint16_t keycode) {
  814. if ((get_mods() & (MOD_MASK_CG | MOD_BIT_LALT)) != 0) {
  815. return false; // Disable Flow Tap on hotkeys.
  816. }
  817. switch (get_tap_keycode(keycode)) {
  818. case KC_SPC:
  819. case KC_A ... KC_Z:
  820. case KC_DOT:
  821. case KC_COMM:
  822. case KC_SCLN:
  823. case KC_SLSH:
  824. return true;
  825. }
  826. return false;
  827. }
  828. __attribute__((weak)) uint16_t get_flow_tap_term(uint16_t keycode, keyrecord_t *record, uint16_t prev_keycode) {
  829. if (is_flow_tap_key(keycode) && is_flow_tap_key(prev_keycode)) {
  830. return FLOW_TAP_TERM;
  831. }
  832. return 0;
  833. }
  834. # endif // FLOW_TAP_TERM
  835. /** \brief Logs tapping key if ACTION_DEBUG is enabled. */
  836. static void debug_tapping_key(void) {
  837. ac_dprintf("TAPPING_KEY=");
  838. debug_record(tapping_key);
  839. ac_dprintf("\n");
  840. }
  841. /** \brief Logs waiting buffer if ACTION_DEBUG is enabled. */
  842. static void debug_waiting_buffer(void) {
  843. ac_dprintf("{");
  844. for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
  845. ac_dprintf(" [%u]=", i);
  846. debug_record(waiting_buffer[i]);
  847. }
  848. ac_dprintf("}\n");
  849. }
  850. #endif