process_tap_dance.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /* Copyright 2016 Jack Humbert
  2. *
  3. * This program is free software: you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation, either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include "process_tap_dance.h"
  17. #include "quantum.h"
  18. #include "action_layer.h"
  19. #include "action_tapping.h"
  20. #include "action_util.h"
  21. #include "timer.h"
  22. #include "wait.h"
  23. #include "keymap_introspection.h"
  24. static uint16_t active_td;
  25. #ifndef TAP_DANCE_MAX_SIMULTANEOUS
  26. # define TAP_DANCE_MAX_SIMULTANEOUS 3
  27. #endif
  28. static tap_dance_state_t tap_dance_states[TAP_DANCE_MAX_SIMULTANEOUS];
  29. static uint16_t last_tap_time;
  30. static tap_dance_state_t *tap_dance_get_or_allocate_state(uint8_t tap_dance_idx, bool allocate) {
  31. uint8_t i;
  32. if (tap_dance_idx >= tap_dance_count()) {
  33. return NULL;
  34. }
  35. // Search for a state already used for this keycode
  36. for (i = 0; i < TAP_DANCE_MAX_SIMULTANEOUS; i++) {
  37. if (tap_dance_states[i].in_use && tap_dance_states[i].index == tap_dance_idx) {
  38. return &tap_dance_states[i];
  39. }
  40. }
  41. // No existing state found; bail out if new state allocation is not allowed
  42. if (!allocate) {
  43. return NULL;
  44. }
  45. // Search for the first available state
  46. for (i = 0; i < TAP_DANCE_MAX_SIMULTANEOUS; i++) {
  47. if (!tap_dance_states[i].in_use) {
  48. tap_dance_states[i].index = tap_dance_idx;
  49. tap_dance_states[i].in_use = true;
  50. return &tap_dance_states[i];
  51. }
  52. }
  53. // No states are available, tap dance won't happen
  54. return NULL;
  55. }
  56. tap_dance_state_t *tap_dance_get_state(uint8_t tap_dance_idx) {
  57. return tap_dance_get_or_allocate_state(tap_dance_idx, false);
  58. }
  59. void tap_dance_pair_on_each_tap(tap_dance_state_t *state, void *user_data) {
  60. tap_dance_pair_t *pair = (tap_dance_pair_t *)user_data;
  61. if (state->count == 2) {
  62. register_code16(pair->kc2);
  63. state->finished = true;
  64. }
  65. }
  66. void tap_dance_pair_finished(tap_dance_state_t *state, void *user_data) {
  67. tap_dance_pair_t *pair = (tap_dance_pair_t *)user_data;
  68. register_code16(pair->kc1);
  69. }
  70. void tap_dance_pair_reset(tap_dance_state_t *state, void *user_data) {
  71. tap_dance_pair_t *pair = (tap_dance_pair_t *)user_data;
  72. if (state->count == 1) {
  73. wait_ms(TAP_CODE_DELAY);
  74. unregister_code16(pair->kc1);
  75. } else if (state->count == 2) {
  76. unregister_code16(pair->kc2);
  77. }
  78. }
  79. void tap_dance_dual_role_on_each_tap(tap_dance_state_t *state, void *user_data) {
  80. tap_dance_dual_role_t *pair = (tap_dance_dual_role_t *)user_data;
  81. if (state->count == 2) {
  82. layer_move(pair->layer);
  83. state->finished = true;
  84. }
  85. }
  86. void tap_dance_dual_role_finished(tap_dance_state_t *state, void *user_data) {
  87. tap_dance_dual_role_t *pair = (tap_dance_dual_role_t *)user_data;
  88. if (state->count == 1) {
  89. register_code16(pair->kc);
  90. } else if (state->count == 2) {
  91. pair->layer_function(pair->layer);
  92. }
  93. }
  94. void tap_dance_dual_role_reset(tap_dance_state_t *state, void *user_data) {
  95. tap_dance_dual_role_t *pair = (tap_dance_dual_role_t *)user_data;
  96. if (state->count == 1) {
  97. wait_ms(TAP_CODE_DELAY);
  98. unregister_code16(pair->kc);
  99. }
  100. }
  101. static inline void _process_tap_dance_action_fn(tap_dance_state_t *state, void *user_data, tap_dance_user_fn_t fn) {
  102. if (fn) {
  103. fn(state, user_data);
  104. }
  105. }
  106. static inline void process_tap_dance_action_on_each_tap(tap_dance_action_t *action, tap_dance_state_t *state) {
  107. state->count++;
  108. state->weak_mods = get_mods();
  109. state->weak_mods |= get_weak_mods();
  110. #ifndef NO_ACTION_ONESHOT
  111. state->oneshot_mods = get_oneshot_mods();
  112. #endif
  113. _process_tap_dance_action_fn(state, action->user_data, action->fn.on_each_tap);
  114. }
  115. static inline void process_tap_dance_action_on_each_release(tap_dance_action_t *action, tap_dance_state_t *state) {
  116. _process_tap_dance_action_fn(state, action->user_data, action->fn.on_each_release);
  117. }
  118. static inline void process_tap_dance_action_on_reset(tap_dance_action_t *action, tap_dance_state_t *state) {
  119. _process_tap_dance_action_fn(state, action->user_data, action->fn.on_reset);
  120. del_weak_mods(state->weak_mods);
  121. #ifndef NO_ACTION_ONESHOT
  122. del_mods(state->oneshot_mods);
  123. #endif
  124. send_keyboard_report();
  125. // Clear the tap dance state and mark it as unused
  126. memset(state, 0, sizeof(tap_dance_state_t));
  127. }
  128. static inline void process_tap_dance_action_on_dance_finished(tap_dance_action_t *action, tap_dance_state_t *state) {
  129. if (!state->finished) {
  130. state->finished = true;
  131. add_weak_mods(state->weak_mods);
  132. #ifndef NO_ACTION_ONESHOT
  133. add_mods(state->oneshot_mods);
  134. #endif
  135. send_keyboard_report();
  136. _process_tap_dance_action_fn(state, action->user_data, action->fn.on_dance_finished);
  137. }
  138. active_td = 0;
  139. if (!state->pressed) {
  140. // There will not be a key release event, so reset now.
  141. process_tap_dance_action_on_reset(action, state);
  142. }
  143. }
  144. bool preprocess_tap_dance(uint16_t keycode, keyrecord_t *record) {
  145. tap_dance_action_t *action;
  146. tap_dance_state_t *state;
  147. if (!record->event.pressed) return false;
  148. if (!active_td || keycode == active_td) return false;
  149. action = tap_dance_get(QK_TAP_DANCE_GET_INDEX(active_td));
  150. state = tap_dance_get_state(QK_TAP_DANCE_GET_INDEX(active_td));
  151. if (state == NULL) {
  152. return false;
  153. }
  154. state->interrupted = true;
  155. state->interrupting_keycode = keycode;
  156. process_tap_dance_action_on_dance_finished(action, state);
  157. // Tap dance actions can leave some weak mods active (e.g., if the tap dance is mapped to a keycode with
  158. // modifiers), but these weak mods should not affect the keypress which interrupted the tap dance.
  159. clear_weak_mods();
  160. // Signal that a tap dance has been finished due to being interrupted,
  161. // therefore the keymap lookup for the currently processed event needs to
  162. // be repeated with the current layer state that might have been updated by
  163. // the finished tap dance.
  164. return true;
  165. }
  166. bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
  167. uint8_t td_index;
  168. tap_dance_action_t *action;
  169. tap_dance_state_t *state;
  170. switch (keycode) {
  171. case QK_TAP_DANCE ... QK_TAP_DANCE_MAX:
  172. td_index = QK_TAP_DANCE_GET_INDEX(keycode);
  173. if (td_index >= tap_dance_count()) {
  174. return false;
  175. }
  176. action = tap_dance_get(td_index);
  177. state = tap_dance_get_or_allocate_state(td_index, record->event.pressed);
  178. if (state == NULL) {
  179. return false;
  180. }
  181. state->pressed = record->event.pressed;
  182. if (record->event.pressed) {
  183. last_tap_time = timer_read();
  184. process_tap_dance_action_on_each_tap(action, state);
  185. active_td = state->finished ? 0 : keycode;
  186. } else {
  187. process_tap_dance_action_on_each_release(action, state);
  188. if (state->finished) {
  189. process_tap_dance_action_on_reset(action, state);
  190. if (active_td == keycode) {
  191. active_td = 0;
  192. }
  193. }
  194. }
  195. break;
  196. }
  197. return true;
  198. }
  199. void tap_dance_task(void) {
  200. tap_dance_action_t *action;
  201. tap_dance_state_t *state;
  202. if (!active_td || timer_elapsed(last_tap_time) <= GET_TAPPING_TERM(active_td, &(keyrecord_t){})) return;
  203. action = tap_dance_get(QK_TAP_DANCE_GET_INDEX(active_td));
  204. state = tap_dance_get_state(QK_TAP_DANCE_GET_INDEX(active_td));
  205. if (state != NULL && !state->interrupted) {
  206. process_tap_dance_action_on_dance_finished(action, state);
  207. }
  208. }
  209. void reset_tap_dance(tap_dance_state_t *state) {
  210. active_td = 0;
  211. process_tap_dance_action_on_reset(tap_dance_get(state->index), state);
  212. }