action_tapping.h 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /*
  2. Copyright 2013 Jun Wako <wakojun@gmail.com>
  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. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #pragma once
  15. /* period of tapping(ms) */
  16. #ifndef TAPPING_TERM
  17. # define TAPPING_TERM 200
  18. #endif
  19. /* period of quick tap(ms) */
  20. #if !defined(QUICK_TAP_TERM) || QUICK_TAP_TERM > TAPPING_TERM
  21. # define QUICK_TAP_TERM TAPPING_TERM
  22. #endif
  23. /* tap count needed for toggling a feature */
  24. #ifndef TAPPING_TOGGLE
  25. # define TAPPING_TOGGLE 5
  26. #endif
  27. #define WAITING_BUFFER_SIZE 8
  28. #ifndef NO_ACTION_TAPPING
  29. uint16_t get_record_keycode(keyrecord_t *record, bool update_layer_cache);
  30. uint16_t get_event_keycode(keyevent_t event, bool update_layer_cache);
  31. void action_tapping_process(keyrecord_t record);
  32. #endif
  33. uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record);
  34. uint16_t get_quick_tap_term(uint16_t keycode, keyrecord_t *record);
  35. bool get_permissive_hold(uint16_t keycode, keyrecord_t *record);
  36. bool get_retro_tapping(uint16_t keycode, keyrecord_t *record);
  37. bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record);
  38. #ifdef SPECULATIVE_HOLD
  39. /** Gets the currently active speculative mods. */
  40. uint8_t get_speculative_mods(void);
  41. /**
  42. * Callback to say if a mod-tap key may be speculatively held.
  43. *
  44. * By default, speculative hold is enabled for mod-tap keys where the mod is
  45. * Ctrl, Shift, and Ctrl+Shift for either hand.
  46. *
  47. * @param keycode Keycode of the mod-tap key.
  48. * @param record Record associated with the mod-tap press event.
  49. * @return True if the mod-tap key may be speculatively held.
  50. */
  51. bool get_speculative_hold(uint16_t keycode, keyrecord_t *record);
  52. /**
  53. * Handler to be called on press events after tap-holds are settled.
  54. *
  55. * This function is to be called in process_record() in action.c, that is, just
  56. * after tap-hold events are settled as either tapped or held. When `record`
  57. * corresponds to a speculatively-held key, the speculative mod is cleared.
  58. *
  59. * @param record Record associated with the mod-tap press event.
  60. */
  61. void speculative_key_settled(keyrecord_t *record);
  62. #else
  63. # define get_speculative_mods() 0
  64. #endif // SPECULATIVE_HOLD
  65. #ifdef CHORDAL_HOLD
  66. /**
  67. * Callback to say when a key chord before the tapping term may be held.
  68. *
  69. * In keymap.c, define the callback
  70. *
  71. * bool get_chordal_hold(uint16_t tap_hold_keycode,
  72. * keyrecord_t* tap_hold_record,
  73. * uint16_t other_keycode,
  74. * keyrecord_t* other_record) {
  75. * // Conditions...
  76. * }
  77. *
  78. * This callback is called when:
  79. *
  80. * 1. `tap_hold_keycode` is pressed.
  81. * 2. `other_keycode` is pressed while `tap_hold_keycode` is still held,
  82. * provided `other_keycode` is *not* also a tap-hold key and it is pressed
  83. * before the tapping term.
  84. *
  85. * If false is returned, this has the effect of immediately settling the
  86. * tap-hold key as tapped. If true is returned, the tap-hold key is still
  87. * unsettled, and may be settled as held depending on configuration and
  88. * subsequent events.
  89. *
  90. * @param tap_hold_keycode Keycode of the tap-hold key.
  91. * @param tap_hold_record Record from the tap-hold press event.
  92. * @param other_keycode Keycode of the other key.
  93. * @param other_record Record from the other key's press event.
  94. * @return True if the tap-hold key may be considered held; false if tapped.
  95. */
  96. bool get_chordal_hold(uint16_t tap_hold_keycode, keyrecord_t *tap_hold_record, uint16_t other_keycode, keyrecord_t *other_record);
  97. /**
  98. * Default "opposite hands rule" for whether a key chord may settle as held.
  99. *
  100. * This function returns true when the tap-hold key and other key are on
  101. * "opposite hands." In detail, handedness of the two keys are compared. If
  102. * handedness values differ, or if either handedness is '*', the function
  103. * returns true, indicating that it may be held. Otherwise, it returns false,
  104. * in which case the tap-hold key is immediately settled at tapped.
  105. *
  106. * @param tap_hold_record Record of the active tap-hold key press.
  107. * @param other_record Record of the other, interrupting key press.
  108. * @return True if the tap-hold key may be considered held; false if tapped.
  109. */
  110. bool get_chordal_hold_default(keyrecord_t *tap_hold_record, keyrecord_t *other_record);
  111. /**
  112. * Gets the handedness of a key.
  113. *
  114. * This function returns:
  115. * 'L' for keys pressed by the left hand,
  116. * 'R' for keys on the right hand,
  117. * '*' for keys exempt from the "opposite hands rule." This could be used
  118. * perhaps on thumb keys or keys that might be pressed by either hand.
  119. *
  120. * @param key A key matrix position.
  121. * @return Handedness value.
  122. */
  123. char chordal_hold_handedness(keypos_t key);
  124. extern const char chordal_hold_layout[MATRIX_ROWS][MATRIX_COLS] PROGMEM;
  125. #endif
  126. #ifdef FLOW_TAP_TERM
  127. /**
  128. * Callback to specify the keys where Flow Tap is enabled.
  129. *
  130. * Flow Tap is constrained to certain keys by the following rule: this callback
  131. * is called for both the tap-hold key *and* the key press immediately preceding
  132. * it. If the callback returns true for both keycodes, Flow Tap is enabled.
  133. *
  134. * The default implementation of this callback corresponds to
  135. *
  136. * bool is_flow_tap_key(uint16_t keycode) {
  137. * switch (get_tap_keycode(keycode)) {
  138. * case KC_SPC:
  139. * case KC_A ... KC_Z:
  140. * case KC_DOT:
  141. * case KC_COMM:
  142. * case KC_SCLN:
  143. * case KC_SLSH:
  144. * return true;
  145. * }
  146. * return false;
  147. * }
  148. *
  149. * @param keycode Keycode of the key.
  150. * @return Whether to enable Flow Tap for this key.
  151. */
  152. bool is_flow_tap_key(uint16_t keycode);
  153. /**
  154. * Callback to customize Flow Tap filtering.
  155. *
  156. * Flow Tap acts only when key events are closer together than this time.
  157. *
  158. * Return a time of 0 to disable filtering. In this way, Flow Tap may be
  159. * disabled for certain tap-hold keys, or when following certain previous keys.
  160. *
  161. * The default implementation of this callback is
  162. *
  163. * uint16_t get_flow_tap_term(uint16_t keycode, keyrecord_t* record,
  164. * uint16_t prev_keycode) {
  165. * if (is_flow_tap_key(keycode) && is_flow_tap_key(prev_keycode)) {
  166. * return g_flow_tap_term;
  167. * }
  168. * return 0;
  169. * }
  170. *
  171. * NOTE: If both `is_flow_tap_key()` and `get_flow_tap_term()` are defined, then
  172. * `get_flow_tap_term()` takes precedence.
  173. *
  174. * @param keycode Keycode of the tap-hold key.
  175. * @param record keyrecord_t of the tap-hold event.
  176. * @param prev_keycode Keycode of the previously pressed key.
  177. * @return Time in milliseconds.
  178. */
  179. uint16_t get_flow_tap_term(uint16_t keycode, keyrecord_t *record, uint16_t prev_keycode);
  180. /**
  181. * Checks if the pressed key is within the flow tap term.
  182. * Can be used to avoid triggering combos or other actions within the flow tap term.
  183. *
  184. * @param keycode The keycode of the pressed key.
  185. * @param record The keyrecord of the pressed key.
  186. * @return True if the pressed key is within the flow tap term; false otherwise.
  187. */
  188. bool within_flow_tap_term(uint16_t keycode, keyrecord_t *record);
  189. #endif // FLOW_TAP_TERM
  190. #if defined(FLOW_TAP_TERM) || defined(SPECULATIVE_HOLD_FLOW_TERM)
  191. /** Updates the Flow Tap last key and timer. */
  192. void flow_tap_update_last_event(keyrecord_t *record);
  193. #endif // defined(FLOW_TAP_TERM) || defined(SPECULATIVE_HOLD_FLOW_TERM)
  194. #ifdef DYNAMIC_TAPPING_TERM_ENABLE
  195. extern uint16_t g_tapping_term;
  196. #endif
  197. #if defined(TAPPING_TERM_PER_KEY) && !defined(NO_ACTION_TAPPING)
  198. # define GET_TAPPING_TERM(keycode, record) get_tapping_term(keycode, record)
  199. #elif defined(DYNAMIC_TAPPING_TERM_ENABLE) && !defined(NO_ACTION_TAPPING)
  200. # define GET_TAPPING_TERM(keycode, record) g_tapping_term
  201. #else
  202. # define GET_TAPPING_TERM(keycode, record) (TAPPING_TERM)
  203. #endif
  204. #ifdef QUICK_TAP_TERM_PER_KEY
  205. # define GET_QUICK_TAP_TERM(keycode, record) get_quick_tap_term(keycode, record)
  206. #else
  207. # define GET_QUICK_TAP_TERM(keycode, record) (QUICK_TAP_TERM)
  208. #endif