tap_dance.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #include "tap_dance.h"
  2. #include "konstantin.h"
  3. #define ACTION_TAP_DANCE_DOUBLE_MODS(mod1, mod2) { \
  4. .fn = { td_double_mods_each, NULL, td_double_mods_reset }, \
  5. .user_data = &(qk_tap_dance_pair_t){ mod1, mod2 }, \
  6. }
  7. void td_double_mods_each(qk_tap_dance_state_t *state, void *user_data) {
  8. qk_tap_dance_pair_t *mods = (qk_tap_dance_pair_t *)user_data;
  9. // Single tap → mod1, double tap → mod2, triple tap etc. → mod1+mod2
  10. if (state->count == 1 || state->count == 3) {
  11. register_code(mods->kc1);
  12. } else if (state->count == 2) {
  13. unregister_code(mods->kc1);
  14. register_code(mods->kc2);
  15. }
  16. // Prevent tap dance from sending kc1 and kc2 as weak mods
  17. state->weak_mods &= ~(MOD_BIT(mods->kc1) | MOD_BIT(mods->kc2));
  18. }
  19. void td_double_mods_reset(qk_tap_dance_state_t *state, void *user_data) {
  20. qk_tap_dance_pair_t *mods = (qk_tap_dance_pair_t *)user_data;
  21. if (state->count == 1 || state->count >= 3) {
  22. unregister_code(mods->kc1);
  23. }
  24. if (state->count >= 2) {
  25. unregister_code(mods->kc2);
  26. }
  27. }
  28. struct {
  29. bool fn_on; // Layer state when tap dance started
  30. bool started;
  31. } td_fn_rctrl_data;
  32. void td_fn_rctrl_each(qk_tap_dance_state_t *state, void *user_data) {
  33. if (!td_fn_rctrl_data.started) {
  34. td_fn_rctrl_data.fn_on = IS_LAYER_ON(L_FN);
  35. td_fn_rctrl_data.started = true;
  36. }
  37. // Single tap → Fn, double tap → RCtrl, triple tap etc. → Fn+RCtrl
  38. if (state->count == 1 || state->count == 3) {
  39. layer_on(L_FN);
  40. } else if (state->count == 2) {
  41. if (!td_fn_rctrl_data.fn_on) {
  42. layer_off(L_FN);
  43. }
  44. register_code(KC_RCTL);
  45. }
  46. }
  47. void td_fn_rctrl_reset(qk_tap_dance_state_t *state, void *user_data) {
  48. if ((state->count == 1 || state->count >= 3) && !td_fn_rctrl_data.fn_on) {
  49. layer_off(L_FN);
  50. }
  51. if (state->count >= 2) {
  52. unregister_code(KC_RCTL);
  53. }
  54. td_fn_rctrl_data.started = false;
  55. }
  56. void td_lsft_fn_each(qk_tap_dance_state_t *state, void *user_data) {
  57. // Single tap → LShift, double tap → Fn, triple tap etc. → Fn+LShift
  58. if (state->count == 1 || state->count == 3) {
  59. register_code(KC_LSFT);
  60. } else if (state->count == 2) {
  61. unregister_code(KC_LSFT);
  62. // Prevent tap dance from sending LShift as a weak mod
  63. state->weak_mods &= ~MOD_BIT(KC_LSFT);
  64. layer_on(L_FN);
  65. }
  66. }
  67. void td_lsft_fn_reset(qk_tap_dance_state_t *state, void *user_data) {
  68. if (state->count == 1 || state->count >= 3) {
  69. unregister_code(KC_LSFT);
  70. }
  71. if (state->count >= 2) {
  72. layer_off(L_FN);
  73. }
  74. }
  75. qk_tap_dance_action_t tap_dance_actions[] = {
  76. [TD_DESKTOP] = ACTION_TAP_DANCE_DOUBLE(LCTL(LGUI(KC_D)), LCTL(LGUI(KC_F4))), // Add/close virtual desktop
  77. [TD_RAL_LAL] = ACTION_TAP_DANCE_DOUBLE_MODS(KC_RALT, KC_LALT),
  78. [TD_RAL_RGU] = ACTION_TAP_DANCE_DOUBLE_MODS(KC_RALT, KC_RGUI),
  79. [TD_RCT_RSF] = ACTION_TAP_DANCE_DOUBLE_MODS(KC_RCTL, KC_RSFT),
  80. [TD_FN_RCTL] = ACTION_TAP_DANCE_FN_ADVANCED(td_fn_rctrl_each, NULL, td_fn_rctrl_reset),
  81. [TD_LSFT_FN] = ACTION_TAP_DANCE_FN_ADVANCED(td_lsft_fn_each, NULL, td_lsft_fn_reset),
  82. };