4 #include "process_keycode/process_tap_dance.h"
6 #if (__has_include("secret.h"))
9 const char secret[][64] = {
21 void register_hyper (void) { //Helper function to invoke Hyper
22 register_code (KC_LSFT);
23 register_code (KC_LCTL);
24 register_code (KC_LALT);
25 register_code (KC_LGUI);
27 void unregister_hyper (void) { //Helper function to invoke Hyper
28 unregister_code (KC_LSFT);
29 unregister_code (KC_LCTL);
30 unregister_code (KC_LALT);
31 unregister_code (KC_LGUI);
34 void register_ctrl_a (void) {
35 register_code(KC_LCTL);
39 void unregister_ctrl_a (void) {
40 unregister_code(KC_LCTL);
41 unregister_code(KC_A);
44 void register_alt_f7 (void) {
45 register_code (KC_LALT);
46 register_code (KC_F7);
49 void unregister_alt_f7 (void) {
50 unregister_code (KC_LALT);
51 unregister_code (KC_F7);
54 void register_shift_f6 (void) {
55 register_code (KC_LSFT);
56 register_code (KC_F6);
59 void unregister_shift_f6 (void) {
60 unregister_code (KC_LSFT);
61 unregister_code (KC_F6);
64 void register_ctrl_shift (void) {
65 register_code (KC_LSFT);
66 register_code (KC_LCTRL);
69 void unregister_ctrl_shift (void) {
70 unregister_code (KC_LSFT);
71 unregister_code (KC_LCTRL);
74 void register_alt_shift (void) {
75 register_code (KC_LSFT);
76 register_code (KC_LALT);
79 void unregister_alt_shift (void) {
80 unregister_code (KC_LSFT);
81 unregister_code (KC_LALT);
84 // To activate SINGLE_HOLD, you will need to hold for 200ms first.
85 // This tap dance favors keys that are used frequently in typing like 'f'
86 int cur_dance (qk_tap_dance_state_t *state) {
87 if (state->count == 1) {
88 //If count = 1, and it has been interrupted - it doesn't matter if it is pressed or not: Send SINGLE_TAP
89 if (state->interrupted) {
90 // if (!state->pressed) return SINGLE_TAP;
91 //need "permissive hold" here.
92 // else return SINsGLE_HOLD;
93 //If the interrupting key is released before the tap-dance key, then it is a single HOLD
94 //However, if the tap-dance key is released first, then it is a single TAP
95 //But how to get access to the state of the interrupting key????
99 if (!state->pressed) return SINGLE_TAP;
100 else return SINGLE_HOLD;
103 //If count = 2, and it has been interrupted - assume that user is trying to type the letter associated
105 else if (state->count == 2) {
106 if (state->interrupted) return DOUBLE_SINGLE_TAP;
107 else if (state->pressed) return DOUBLE_HOLD;
108 else return DOUBLE_TAP;
110 else if ((state->count == 3) && ((state->interrupted) || (!state->pressed))) return TRIPLE_TAP;
111 else if (state->count == 3) return TRIPLE_HOLD;
112 else return 8; //magic number. At some point this method will expand to work for more presses
115 //This works well if you want this key to work as a "fast modifier". It favors being held over being tapped.
116 int hold_cur_dance (qk_tap_dance_state_t *state) {
117 if (state->count == 1) {
118 if (state->interrupted) {
119 if (!state->pressed) return SINGLE_TAP;
120 else return SINGLE_HOLD;
123 if (!state->pressed) return SINGLE_TAP;
124 else return SINGLE_HOLD;
127 //If count = 2, and it has been interrupted - assume that user is trying to type the letter associated
129 else if (state->count == 2) {
130 if (state->pressed) return DOUBLE_HOLD;
131 else return DOUBLE_TAP;
133 else if (state->count == 3) {
134 if (!state->pressed) return TRIPLE_TAP;
135 else return TRIPLE_HOLD;
137 else return 8; //magic number. At some point this method will expand to work for more presses
141 static xtap htap_state = {
142 .is_press_action = true,
146 void h_finished (qk_tap_dance_state_t *state, void *user_data) {
147 htap_state.state = cur_dance(state);
148 switch (htap_state.state) {
149 case SINGLE_TAP: register_code(KC_H); break;
150 case SINGLE_HOLD: layer_on(8); register_code(KC_LALT); break;
151 case DOUBLE_TAP: layer_invert(8); register_code(KC_LALT); break;
152 // case DOUBLE_HOLD: register_code(KC_LALT);
153 case DOUBLE_SINGLE_TAP: register_code(KC_H);unregister_code(KC_H);register_code(KC_H);
157 void h_reset (qk_tap_dance_state_t *state, void *user_data) {
158 switch (htap_state.state) {
159 case SINGLE_TAP: unregister_code(KC_H); break;
160 case SINGLE_HOLD: layer_off(8); unregister_code(KC_LALT); break;
161 case DOUBLE_TAP: unregister_code(KC_LALT);break;
162 // case DOUBLE_HOLD: unregister_code(KC_LALT);
163 case DOUBLE_SINGLE_TAP: unregister_code(KC_H);
165 htap_state.state = 0;
169 /**************** QUAD FUNCTION FOR TAB ****************/
170 // TAB, ALT + SHIFT, TAB TAB, CTRL + SHIFT
171 static xtap tab_state = {
172 .is_press_action = true,
176 void tab_finished (qk_tap_dance_state_t *state, void *user_data) {
177 tab_state.state = cur_dance(state);
178 switch (tab_state.state) {
179 case SINGLE_TAP: register_code(KC_TAB); break; //send tab on single press
180 case SINGLE_HOLD: register_ctrl_shift(); break;
181 case DOUBLE_HOLD: register_alt_shift(); break; //alt shift on single hold
182 case DOUBLE_TAP: register_code(KC_TAB); unregister_code(KC_TAB); register_code(KC_TAB); break; //tab tab
183 case TRIPLE_TAP: register_code(KC_LSHIFT) ;register_code(KC_ESC); break;
184 case TRIPLE_HOLD: register_code(KC_LSHIFT); register_code(KC_LGUI); break;
188 void tab_reset (qk_tap_dance_state_t *state, void *user_data) {
189 switch (tab_state.state) {
190 case SINGLE_TAP: unregister_code(KC_TAB); break; //unregister tab
191 case DOUBLE_HOLD: unregister_alt_shift(); break; //let go of alt shift
192 case DOUBLE_TAP: unregister_code(KC_TAB); break;
193 case SINGLE_HOLD: unregister_ctrl_shift(); break;
194 case TRIPLE_TAP: unregister_code(KC_LSHIFT); unregister_code(KC_ESC); break;
195 case TRIPLE_HOLD: unregister_code(KC_LSHIFT); unregister_code(KC_LGUI); break;
199 /**************** QUAD FUNCTION FOR TAB ****************/
201 //*************** SUPER COMMA *******************//
202 // Assumption: we don't care about trying to hit ,, quickly
203 //*************** SUPER COMMA *******************//
204 static xtap comma_state = {
205 .is_press_action = true,
209 void comma_finished (qk_tap_dance_state_t *state, void *user_data) {
210 comma_state.state = hold_cur_dance(state); //Use the dance that favors being held
211 switch (comma_state.state) {
212 case SINGLE_TAP: register_code(KC_COMMA); break;
213 case SINGLE_HOLD: layer_on(1); break; //turn on symbols layer
214 case DOUBLE_TAP: layer_invert(4); break; //toggle numbers layer
215 case DOUBLE_HOLD: layer_on(2); break;
216 case TRIPLE_TAP: register_code(KC_CALCULATOR); break;
217 case TRIPLE_HOLD: layer_on(3);
221 void comma_reset (qk_tap_dance_state_t *state, void *user_data) {
222 switch (comma_state.state) {
223 case SINGLE_TAP: unregister_code(KC_COMMA); break; //unregister comma
224 case SINGLE_HOLD: layer_off(1); break;
225 case DOUBLE_TAP: ;break;
226 case DOUBLE_HOLD: layer_off(2); break;
227 case TRIPLE_TAP: unregister_code(KC_CALCULATOR); break;
228 case TRIPLE_HOLD: layer_off(3);
230 comma_state.state = 0;
232 //*************** SUPER COMMA *******************//
233 //*************** SUPER COMMA *******************//
236 //*************** F3 TAP DANCE *******************//
237 //Good example for accessing multiple layers from the same key.
238 static xtap S1_state = {
239 .is_press_action = true,
243 void bt_finished (qk_tap_dance_state_t *state, void *user_data) {
244 S1_state.state = cur_dance(state);
245 switch (S1_state.state) {
246 case SINGLE_TAP: register_code(KC_F3); break;
247 case SINGLE_HOLD: layer_on(4); break;
248 case DOUBLE_TAP: layer_invert(4); break;
249 case DOUBLE_HOLD: layer_on(5); break;
250 case DOUBLE_SINGLE_TAP: layer_invert(4); break;
254 void bt_reset (qk_tap_dance_state_t *state, void *user_data) {
255 switch (S1_state.state) {
256 case SINGLE_TAP: unregister_code(KC_F3); break;
257 case SINGLE_HOLD: layer_off(4); break;
258 case DOUBLE_TAP: break; //already inverted. Don't do anything.
259 case DOUBLE_HOLD: layer_off(5); break;
260 case DOUBLE_SINGLE_TAP: break;
265 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
267 case KC_SECRET_1 ... KC_SECRET_5:
268 if (!record->event.pressed) {
269 send_string(secret[keycode - KC_SECRET_1]);