process_tap_dance.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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. static uint16_t active_td;
  24. static uint16_t last_tap_time;
  25. void tap_dance_pair_on_each_tap(tap_dance_state_t *state, void *user_data) {
  26. tap_dance_pair_t *pair = (tap_dance_pair_t *)user_data;
  27. if (state->count == 2) {
  28. register_code16(pair->kc2);
  29. state->finished = true;
  30. }
  31. }
  32. void tap_dance_pair_finished(tap_dance_state_t *state, void *user_data) {
  33. tap_dance_pair_t *pair = (tap_dance_pair_t *)user_data;
  34. register_code16(pair->kc1);
  35. }
  36. void tap_dance_pair_reset(tap_dance_state_t *state, void *user_data) {
  37. tap_dance_pair_t *pair = (tap_dance_pair_t *)user_data;
  38. if (state->count == 1) {
  39. wait_ms(TAP_CODE_DELAY);
  40. unregister_code16(pair->kc1);
  41. } else if (state->count == 2) {
  42. unregister_code16(pair->kc2);
  43. }
  44. }
  45. void tap_dance_dual_role_on_each_tap(tap_dance_state_t *state, void *user_data) {
  46. tap_dance_dual_role_t *pair = (tap_dance_dual_role_t *)user_data;
  47. if (state->count == 2) {
  48. layer_move(pair->layer);
  49. state->finished = true;
  50. }
  51. }
  52. void tap_dance_dual_role_finished(tap_dance_state_t *state, void *user_data) {
  53. tap_dance_dual_role_t *pair = (tap_dance_dual_role_t *)user_data;
  54. if (state->count == 1) {
  55. register_code16(pair->kc);
  56. } else if (state->count == 2) {
  57. pair->layer_function(pair->layer);
  58. }
  59. }
  60. void tap_dance_dual_role_reset(tap_dance_state_t *state, void *user_data) {
  61. tap_dance_dual_role_t *pair = (tap_dance_dual_role_t *)user_data;
  62. if (state->count == 1) {
  63. wait_ms(TAP_CODE_DELAY);
  64. unregister_code16(pair->kc);
  65. }
  66. }
  67. static inline void _process_tap_dance_action_fn(tap_dance_state_t *state, void *user_data, tap_dance_user_fn_t fn) {
  68. if (fn) {
  69. fn(state, user_data);
  70. }
  71. }
  72. static inline void process_tap_dance_action_on_each_tap(tap_dance_action_t *action) {
  73. action->state.count++;
  74. action->state.weak_mods = get_mods();
  75. action->state.weak_mods |= get_weak_mods();
  76. #ifndef NO_ACTION_ONESHOT
  77. action->state.oneshot_mods = get_oneshot_mods();
  78. #endif
  79. _process_tap_dance_action_fn(&action->state, action->user_data, action->fn.on_each_tap);
  80. }
  81. static inline void process_tap_dance_action_on_each_release(tap_dance_action_t *action) {
  82. _process_tap_dance_action_fn(&action->state, action->user_data, action->fn.on_each_release);
  83. }
  84. static inline void process_tap_dance_action_on_reset(tap_dance_action_t *action) {
  85. _process_tap_dance_action_fn(&action->state, action->user_data, action->fn.on_reset);
  86. del_weak_mods(action->state.weak_mods);
  87. #ifndef NO_ACTION_ONESHOT
  88. del_mods(action->state.oneshot_mods);
  89. #endif
  90. send_keyboard_report();
  91. action->state = (const tap_dance_state_t){0};
  92. }
  93. static inline void process_tap_dance_action_on_dance_finished(tap_dance_action_t *action) {
  94. if (!action->state.finished) {
  95. action->state.finished = true;
  96. add_weak_mods(action->state.weak_mods);
  97. #ifndef NO_ACTION_ONESHOT
  98. add_mods(action->state.oneshot_mods);
  99. #endif
  100. send_keyboard_report();
  101. _process_tap_dance_action_fn(&action->state, action->user_data, action->fn.on_dance_finished);
  102. }
  103. active_td = 0;
  104. if (!action->state.pressed) {
  105. // There will not be a key release event, so reset now.
  106. process_tap_dance_action_on_reset(action);
  107. }
  108. }
  109. bool preprocess_tap_dance(uint16_t keycode, keyrecord_t *record) {
  110. tap_dance_action_t *action;
  111. if (!record->event.pressed) return false;
  112. if (!active_td || keycode == active_td) return false;
  113. action = &tap_dance_actions[TD_INDEX(active_td)];
  114. action->state.interrupted = true;
  115. action->state.interrupting_keycode = keycode;
  116. process_tap_dance_action_on_dance_finished(action);
  117. // Tap dance actions can leave some weak mods active (e.g., if the tap dance is mapped to a keycode with
  118. // modifiers), but these weak mods should not affect the keypress which interrupted the tap dance.
  119. clear_weak_mods();
  120. // Signal that a tap dance has been finished due to being interrupted,
  121. // therefore the keymap lookup for the currently processed event needs to
  122. // be repeated with the current layer state that might have been updated by
  123. // the finished tap dance.
  124. return true;
  125. }
  126. bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
  127. tap_dance_action_t *action;
  128. switch (keycode) {
  129. case QK_TAP_DANCE ... QK_TAP_DANCE_MAX:
  130. action = &tap_dance_actions[TD_INDEX(keycode)];
  131. action->state.pressed = record->event.pressed;
  132. if (record->event.pressed) {
  133. last_tap_time = timer_read();
  134. process_tap_dance_action_on_each_tap(action);
  135. active_td = action->state.finished ? 0 : keycode;
  136. } else {
  137. process_tap_dance_action_on_each_release(action);
  138. if (action->state.finished) {
  139. process_tap_dance_action_on_reset(action);
  140. if (active_td == keycode) {
  141. active_td = 0;
  142. }
  143. }
  144. }
  145. break;
  146. }
  147. return true;
  148. }
  149. void tap_dance_task(void) {
  150. tap_dance_action_t *action;
  151. if (!active_td || timer_elapsed(last_tap_time) <= GET_TAPPING_TERM(active_td, &(keyrecord_t){})) return;
  152. action = &tap_dance_actions[TD_INDEX(active_td)];
  153. if (!action->state.interrupted) {
  154. process_tap_dance_action_on_dance_finished(action);
  155. }
  156. }
  157. void reset_tap_dance(tap_dance_state_t *state) {
  158. active_td = 0;
  159. process_tap_dance_action_on_reset((tap_dance_action_t *)state);
  160. }