Tapdance config in progmem

This commit is contained in:
Stephen Ostermiller 2025-06-29 15:40:02 -04:00
parent 24fae67788
commit 1958e4d63d
43 changed files with 725 additions and 250 deletions

View File

@ -0,0 +1,80 @@
# Tap dance actions moved to PROGEM
Tap dance actions are moved to PROGMEM so that they no longer use RAM.
## Changes for tap dance action array
Every layout that uses tap dances will need to change
```c
tap_dance_action_t tap_dance_actions[] = {
```
to
```c
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
```
## New syntax for `ACTION_TAP_DANCE_DOUBLE`
`ACTION_TAP_DANCE_DOUBLE` no longer accepts two keycode literals, now it needs a variable containing the key code pair.
```c
tap_dance_action_t tap_dance_actions[] = {
[TD_DEL_BSPC] = ACTION_TAP_DANCE_DOUBLE(KC_DEL, KC_BSPC),
[TD_ESC_GRAVE] = ACTION_TAP_DANCE_DOUBLE(KC_ESC, KC_GRAVE),
};
```
to
```c
enum {
P_DEL_BSPC,
P_ESC_GRAVE,
};
const tap_dance_pair_t tap_dance_pairs[] PROGMEM = {
[P_DEL_BSPC] = {KC_DEL, KC_BSPC},
[P_ESC_GRAVE] = {KC_ESC, KC_GRAVE},
};
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[TD_DEL_BSPC] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_DEL_BSPC]),
[TD_ESC_GRAVE] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_ESC_GRAVE]),
};
```
## New syntax for `ACTION_TAP_DANCE_LAYER_MOVE` and `ACTION_TAP_DANCE_LAYER_TOGGLE`
```c
tap_dance_action_t tap_dance_actions[] = {
[TD_Q_ALT] = ACTION_TAP_DANCE_LAYER_MOVE(KC_Q, _ALT),
[TD_R_RAISE] = ACTION_TAP_DANCE_LAYER_TOGGLE(KC_R, _RAISE),
};
```
to
```c
enum {
DR_Q_ALT,
DR_R_RAISE,
};
const tap_dance_dual_role_t tap_dance_dual_roles[] PROGMEM = {
[DR_Q_ALT] = DUAL_ROLE_TAP_DANCE_LAYER_MOVE(KC_Q, _ALT),
[DR_R_RAISE] = DUAL_ROLE_TAP_DANCE_LAYER_TOGGLE(KC_R, _RAISE),
};
tap_dance_action_t tap_dance_actions[] = {
[TD_Q_ALT] = ACTION_TAP_DANCE_DUAL_ROLE(tap_dance_dual_roles[DR_Q_ALT]),
[TD_R_RAISE] = ACTION_TAP_DANCE_DUAL_ROLE(tap_dance_dual_roles[DR_R_RAISE]),
};
```

View File

@ -21,16 +21,17 @@ The `TAPPING_TERM` time is the maximum time allowed between taps of your Tap Dan
Next, you will want to define some tap-dance keys, which is easiest to do with the `TD()` macro. That macro takes a number which will later be used as an index into the `tap_dance_actions` array and turns it into a tap-dance keycode.
After this, you'll want to use the `tap_dance_actions` array to specify what actions shall be taken when a tap-dance key is in action. Currently, there are five possible options:
After this, you'll want to use the `tap_dance_actions` array to specify what actions shall be taken when a tap-dance key is in action. Currently, there several possible options:
* `ACTION_TAP_DANCE_DOUBLE(kc1, kc2)`: Sends the `kc1` keycode when tapped once, `kc2` otherwise. When the key is held, the appropriate keycode is registered: `kc1` when pressed and held, `kc2` when tapped once, then pressed and held.
* `ACTION_TAP_DANCE_LAYER_MOVE(kc, layer)`: Sends the `kc` keycode when tapped once, or moves to `layer`. (this functions like the `TO` layer keycode).
* `ACTION_TAP_DANCE_LAYER_TOGGLE(kc, layer)`: Sends the `kc` keycode when tapped once, or toggles the state of `layer`. (this functions like the `TG` layer keycode).
* `ACTION_TAP_DANCE_DOUBLE(pair)`: Define keycode pairs in a separate progmem array. With the pair `{kc1, kc2}`, it sends the `kc1` keycode when tapped once, `kc2` otherwise. When the key is held, the appropriate keycode is registered: `kc1` when pressed and held, `kc2` when tapped once, then pressed and held.
* `ACTION_TAP_DANCE_DUAL_ROLE(dual_role)`: Define dual roles in a separate progmem array. Using the following:
* `DUAL_ROLE_TAP_DANCE_LAYER_MOVE(kc, layer)`: Sends the `kc` keycode when tapped once, or moves to `layer`. (this functions like the `TO` layer keycode).
* `DUAL_ROLE_TAP_DANCE_LAYER_TOGGLE(kc, layer)`: Sends the `kc` keycode when tapped once, or toggles the state of `layer`. (this functions like the `TG` layer keycode).
* `ACTION_TAP_DANCE_FN(fn)`: Calls the specified function - defined in the user keymap - with the final tap count of the tap dance action.
* `ACTION_TAP_DANCE_FN_ADVANCED(on_each_tap_fn, on_dance_finished_fn, on_dance_reset_fn)`: Calls the first specified function - defined in the user keymap - on every tap, the second function when the dance action finishes (like the previous option), and the last function when the tap dance action resets.
* `ACTION_TAP_DANCE_FN_ADVANCED_WITH_RELEASE(on_each_tap_fn, on_each_release_fn, on_dance_finished_fn, on_dance_reset_fn)`: This macro is identical to `ACTION_TAP_DANCE_FN_ADVANCED` with the addition of `on_each_release_fn` which is invoked every time the key for the tap dance is released. It is worth noting that `on_each_release_fn` will still be called even when the key is released after the dance finishes (e.g. if the key is released after being pressed and held for longer than the `TAPPING_TERM`).
The first option is enough for a lot of cases, that just want dual roles. For example, `ACTION_TAP_DANCE_DOUBLE(KC_SPC, KC_ENT)` will result in `Space` being sent on single-tap, `Enter` otherwise.
The first option is enough for a lot of cases that just want dual roles.
::: warning
Keep in mind that only [basic keycodes](../keycodes_basic) are supported here. Custom keycodes are not supported.
@ -60,15 +61,25 @@ Here's a simple example for a single definition:
2. In your `keymap.c` file, define the variables and definitions, then add to your keymap:
```c
// Tap Dance declarations
// Tap dance pair declarations
enum {
P_ESC_CAPS,
};
// Tap dance pair definitions
const tap_dance_pair_t tap_dance_pairs[] PROGMEM = {
[P_ESC_CAPS] = {KC_ESC, KC_CAPS},
};
// Tap dance declarations
enum {
TD_ESC_CAPS,
};
// Tap Dance definitions
tap_dance_action_t tap_dance_actions[] = {
// Tap dance action definitions
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
// Tap once for Escape, twice for Caps Lock
[TD_ESC_CAPS] = ACTION_TAP_DANCE_DOUBLE(KC_ESC, KC_CAPS),
[TD_ESC_CAPS] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_ESC_CAPS]),
};
// Add tap dance item to your keymap in place of a keycode
@ -105,7 +116,7 @@ void dance_egg(tap_dance_state_t *state, void *user_data) {
}
}
tap_dance_action_t tap_dance_actions[] = {
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[CT_EGG] = ACTION_TAP_DANCE_FN(dance_egg),
};
```
@ -152,8 +163,8 @@ void dance_flsh_reset(tap_dance_state_t *state, void *user_data) {
}
// All tap dances now put together. Example 2 is "CT_FLSH"
tap_dance_action_t tap_dance_actions[] = {
[TD_ESC_CAPS] = ACTION_TAP_DANCE_DOUBLE(KC_ESC, KC_CAPS),
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[TD_ESC_CAPS] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_ESC_CAPS])
[CT_EGG] = ACTION_TAP_DANCE_FN(dance_egg),
[CT_FLSH] = ACTION_TAP_DANCE_FN_ADVANCED(dance_flsh_each, dance_flsh_finished, dance_flsh_reset)
};
@ -167,11 +178,17 @@ With a little effort, powerful tap-hold configurations can be implemented as tap
typedef struct {
uint16_t tap;
uint16_t hold;
uint16_t held;
} tap_dance_tap_hold_t;
typedef struct {
uint16_t held;
} tap_dance_tap_hold_state_t;
static tap_dance_tap_hold_state_t tap_dance_tap_hold_states[TAP_DANCE_MAX_SIMULTANEOUS];
void tap_dance_tap_hold_finished(tap_dance_state_t *state, void *user_data) {
tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)user_data;
tap_dance_tap_hold_t tap_hold;
memcpy_P(&tap_hold, user_data, sizeof(tap_dance_tap_hold_t));
if (state->pressed) {
if (state->count == 1
@ -179,45 +196,45 @@ void tap_dance_tap_hold_finished(tap_dance_state_t *state, void *user_data) {
&& !state->interrupted
#endif
) {
register_code16(tap_hold->hold);
tap_hold->held = tap_hold->hold;
register_code16(tap_hold.hold);
tap_dance_tap_hold_states[state->state_idx].held = tap_hold.hold;
} else {
register_code16(tap_hold->tap);
tap_hold->held = tap_hold->tap;
register_code16(tap_hold.tap);
tap_dance_tap_hold_states[state->state_idx].held = tap_hold.tap;
}
}
}
void tap_dance_tap_hold_reset(tap_dance_state_t *state, void *user_data) {
tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)user_data;
tap_dance_tap_hold_t tap_hold;
memcpy_P(&tap_hold, user_data, sizeof(tap_dance_tap_hold_t));
if (tap_hold->held) {
unregister_code16(tap_hold->held);
tap_hold->held = 0;
if (tap_dance_tap_hold_states[state->state_idx].held) {
unregister_code16(tap_dance_tap_hold_states[state->state_idx].held);
tap_dance_tap_hold_states[state->state_idx].held = 0;
}
}
#define ACTION_TAP_DANCE_TAP_HOLD(tap, hold) \
{ \
.fn = {NULL, tap_dance_tap_hold_finished, tap_dance_tap_hold_reset}, \
.user_data = (void *)&((tap_dance_tap_hold_t){tap, hold, 0}), \
}
#define ACTION_TAP_DANCE_TAP_HOLD(tap_hold) {{NULL, tap_dance_tap_hold_finished, tap_dance_tap_hold_reset}, (void *)&(tap_hold)}
tap_dance_action_t tap_dance_actions[] = {
[CT_CLN] = ACTION_TAP_DANCE_TAP_HOLD(KC_COLN, KC_SCLN),
const tap_dance_tap_hold_t d_ct_cln PROGMEM = {KC_COLN, KC_SCLN};
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[CT_CLN] = ACTION_TAP_DANCE_TAP_HOLD(d_ct_cln),
};
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
tap_dance_action_t *action;
tap_dance_state_t* state;
tap_dance_tap_hold_t tap_hold;
switch (keycode) {
case TD(CT_CLN):
action = tap_dance_get(QK_TAP_DANCE_GET_INDEX(keycode));
state = tap_dance_get_state(QK_TAP_DANCE_GET_INDEX(keycode));
if (!record->event.pressed && state != NULL && state->count && !state->finished) {
tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)action->user_data;
tap_code16(tap_hold->tap);
memcpy_P(&tap_hold, (tap_dance_tap_hold_t *)action->user_data, sizeof(tap_dance_tap_hold_t));
tap_code16(tap_hold.tap);
}
}
return true;
@ -356,7 +373,7 @@ void x_reset(tap_dance_state_t *state, void *user_data) {
xtap_state.state = TD_NONE;
}
tap_dance_action_t tap_dance_actions[] = {
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[X_CTL] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, x_finished, x_reset)
};
```
@ -452,7 +469,7 @@ void altlp_reset(tap_dance_state_t *state, void *user_data) {
}
// Define `ACTION_TAP_DANCE_FN_ADVANCED()` for each tapdance keycode, passing in `finished` and `reset` functions
tap_dance_action_t tap_dance_actions[] = {
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[ALT_LP] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, altlp_finished, altlp_reset)
};
```
@ -546,7 +563,7 @@ void ql_reset(tap_dance_state_t *state, void *user_data) {
}
// Associate our tap dance key with its functionality
tap_dance_action_t tap_dance_actions[] = {
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[QUOT_LAYR] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, ql_finished, ql_reset)
};

View File

@ -38,9 +38,14 @@ enum tapdances{
TD_ESQW,
};
tap_dance_action_t tap_dance_actions[] = {
[TD_ESFL] = ACTION_TAP_DANCE_LAYER_MOVE(KC_ESC, _FLOCK),
[TD_ESQW] = ACTION_TAP_DANCE_LAYER_MOVE(KC_ESC, _QWERTY),
const tap_dance_dual_role_t tap_dance_dual_roles[] PROGMEM = {
[TD_ESFL] = DUAL_ROLE_TAP_DANCE_LAYER_MOVE(KC_ESC, _FLOCK),
[TD_ESQW] = DUAL_ROLE_TAP_DANCE_LAYER_MOVE(KC_ESC, _QWERTY),
};
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[TD_ESFL] = ACTION_TAP_DANCE_DUAL_ROLE(tap_dance_dual_roles[TD_ESFL]),
[TD_ESQW] = ACTION_TAP_DANCE_DUAL_ROLE(tap_dance_dual_roles[TD_ESQW]),
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {

View File

@ -28,12 +28,18 @@ enum tapdances{
#define KC_DSTP LGUI(KC_D)
#define KC_ESLO LT(_LOWER, KC_ESC)
const tap_dance_pair_t tap_dance_pairs[] PROGMEM = {
[TD_SCCL] = {KC_SCLN, KC_QUOT},
[TD_ENSL] = {KC_SLSH, KC_ENT},
[TD_N0BS] = {KC_0, KC_BSLS},
[TD_RPPI] = {KC_RPRN, KC_PIPE},
};
tap_dance_action_t tap_dance_actions[] = {
[TD_SCCL] = ACTION_TAP_DANCE_DOUBLE(KC_SCLN, KC_QUOT),
[TD_ENSL] = ACTION_TAP_DANCE_DOUBLE(KC_SLSH, KC_ENT),
[TD_N0BS] = ACTION_TAP_DANCE_DOUBLE(KC_0, KC_BSLS),
[TD_RPPI] = ACTION_TAP_DANCE_DOUBLE(KC_RPRN, KC_PIPE),
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[TD_SCCL] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[TD_SCCL]),
[TD_ENSL] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[TD_ENSL]),
[TD_N0BS] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[TD_N0BS]),
[TD_RPPI] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[TD_RPPI]),
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {

View File

@ -112,13 +112,29 @@ void cvxa_reset(tap_dance_state_t *state, void *user_data) {
cvxa_state.state = TD_NONE;
}
enum {
P_CUT_REDO,
P_PLAY_PAUSE_MUTE,
P_MNXT_RIGHT,
P_MPRV_LEFT,
P_SEARCH_REFRESH,
};
const tap_dance_pair_t tap_dance_pairs[] PROGMEM = {
[P_CUT_REDO] = {C(KC_Z), S(C(KC_Z))},
[P_PLAY_PAUSE_MUTE] = {KC_MPLY, KC_MUTE},
[P_MNXT_RIGHT] = {KC_MNXT, KC_RIGHT},
[P_MPRV_LEFT] = {KC_MPRV, KC_LEFT},
[P_SEARCH_REFRESH] = {KC_WREF, KC_WSCH},
};
// Tap Dance definitions
tap_dance_action_t tap_dance_actions[] = {
[TD_CUT_REDO] = ACTION_TAP_DANCE_DOUBLE(C(KC_Z), S(C(KC_Z))),
[TD_PLAY_PAUSE_MUTE] = ACTION_TAP_DANCE_DOUBLE(KC_MPLY, KC_MUTE),
[TD_MNXT_RIGHT] = ACTION_TAP_DANCE_DOUBLE(KC_MNXT, KC_RIGHT),
[TD_MPRV_LEFT] = ACTION_TAP_DANCE_DOUBLE(KC_MPRV, KC_LEFT),
[TD_SEARCH_REFRESH] = ACTION_TAP_DANCE_DOUBLE(KC_WREF, KC_WSCH),
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[TD_CUT_REDO] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_CUT_REDO]),
[TD_PLAY_PAUSE_MUTE] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_PLAY_PAUSE_MUTE]),
[TD_MNXT_RIGHT] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_MNXT_RIGHT]),
[TD_MPRV_LEFT] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_MPRV_LEFT]),
[TD_SEARCH_REFRESH] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_SEARCH_REFRESH]),
[QUAD_LAYER_SWITCH] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, layer_finished, layer_reset),
[QUAD_CVXA] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, cvxa_finished, cvxa_reset)
};
@ -167,7 +183,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
break;
}
return true;
};
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
@ -182,8 +198,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[2] = LAYOUT(
A(KC_F4), SGUI(KC_S), KC_MYCM, LCA(KC_DEL), KC_CALC, TD(QUAD_LAYER_SWITCH)
),
[3] = LAYOUT(
C(KC_SLSH), VALORANT, VSCODE, DISCORD, LSA(KC_A), TD(QUAD_LAYER_SWITCH)
),
};
};

View File

@ -47,7 +47,7 @@ void dance_cln_finished(tap_dance_state_t *state, void *user_data) {
}
/* All tap dance functions would go here. Only showing this one. */
tap_dance_action_t tap_dance_actions[] = {
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[TD_PLAY_FORWARD_BACK] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, dance_cln_finished, NULL),
};

View File

@ -90,7 +90,7 @@ void dance_u_u(tap_dance_state_t *state, void *user_data)
}
/* Define the tap dance actions for the french characters */
tap_dance_action_t tap_dance_actions[] = {
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[A_Q] = ACTION_TAP_DANCE_FN(dance_a_q),
[E_Q] = ACTION_TAP_DANCE_FN(dance_e_q),
[E_U] = ACTION_TAP_DANCE_FN(dance_e_u),
@ -101,21 +101,21 @@ tap_dance_action_t tap_dance_actions[] = {
[O_C] = ACTION_TAP_DANCE_FN(dance_o_c),
[U_U] = ACTION_TAP_DANCE_FN(dance_u_u)
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[NORMAL_LAYER] = LAYOUT(TO(1), WIN_TAB, KC_HOME, KC_UP, KC_END,
[NORMAL_LAYER] = LAYOUT(TO(1), WIN_TAB, KC_HOME, KC_UP, KC_END,
WIN_LOCK, KC_MUTE, KC_LEFT, KC_DOWN, KC_RGHT),
[MEDIA_LAYER] = LAYOUT(TO(2), KC_CALC, KC_MPRV, KC_MNXT, KC_VOLU,
[MEDIA_LAYER] = LAYOUT(TO(2), KC_CALC, KC_MPRV, KC_MNXT, KC_VOLU,
KC_TRNS, KC_TRNS, KC_MSTP, KC_MPLY, KC_VOLD),
[TBD_LAYER2] = LAYOUT(TO(3), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
[TBD_LAYER2] = LAYOUT(TO(3), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
[FRENCH_LAYER] = LAYOUT(TO(0), TD(A_Q), TD(E_Q), TD(E_U), TD(E_E),
[FRENCH_LAYER] = LAYOUT(TO(0), TD(A_Q), TD(E_Q), TD(E_U), TD(E_E),
KC_TRNS, TD(A_Y), TD(I_I), TD(O_C), TD(U_U))
};

View File

@ -29,8 +29,16 @@ enum taps {
PNX, // Play/pause; next track.
};
tap_dance_action_t tap_dance_actions[] = {
[PNX] = ACTION_TAP_DANCE_DOUBLE(KC_MEDIA_PLAY_PAUSE, KC_MEDIA_NEXT_TRACK),
enum {
P_PNX,
};
const tap_dance_pair_t tap_dance_pairs[] PROGMEM = {
[P_PNX] = {KC_MEDIA_PLAY_PAUSE, KC_MEDIA_NEXT_TRACK},
};
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[PNX] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_PNX]),
};
// Shorthand:

View File

@ -53,9 +53,9 @@ void tilded(tap_dance_state_t *state, void *user_data) {
else
tap_code16(KC_AT);
}
}
tap_dance_action_t tap_dance_actions[] = {
}
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[OP_QT] = ACTION_TAP_DANCE_FN(tri_open),
[CL_QT] = ACTION_TAP_DANCE_FN(tri_close),
[TD_DQ] = ACTION_TAP_DANCE_FN(dquote),

View File

@ -30,7 +30,7 @@ void dance_cln_reset(tap_dance_state_t *state, void *user_data) {
}
}
tap_dance_action_t tap_dance_actions[] = {
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[TD_BL] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, dance_cln_finished, dance_cln_reset)
};

View File

@ -155,7 +155,7 @@ static void dance_oled_finished(tap_dance_state_t *state, void *user_data) {
}
}
tap_dance_action_t tap_dance_actions[] = {[TD_OLED] = ACTION_TAP_DANCE_FN(dance_oled_finished)};
const tap_dance_action_t tap_dance_actions[] PROGMEM = {[TD_OLED] = ACTION_TAP_DANCE_FN(dance_oled_finished)};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {LAYOUT_ortho_1x1(TD(TD_OLED))};

View File

@ -315,40 +315,110 @@ void lspace_reset (tap_dance_state_t *state, void *user_data) {
//TD_RSPACE
enum {
P_DEL_BSPC,
P_ESC_GRAVE,
P_TAB_TILDE,
P_9_LPRN,
P_0_RPRN,
P_MINS_UNDS,
P_EQL_PLUS,
P_LBRC_LCBR,
P_RBRC_RCBR,
P_SCLN_COLN,
P_QUOT_DQT,
P_COMM_LABK,
P_DOT_RABK,
P_SLSH_QUES,
P_BSLS_PIPE,
P_PGUP_HOME,
P_PGDN_END,
P_SPC_ENT,
P_SPC_BKSPC,
};
const tap_dance_pair_t tap_dance_pairs[] PROGMEM = {
[P_DEL_BSPC] = {KC_DEL, KC_BSPC},
[P_ESC_GRAVE] = {KC_ESC, KC_GRAVE},
[P_TAB_TILDE] = {KC_TAB, KC_TILDE},
[P_9_LPRN] = {KC_9, KC_LPRN},
[P_0_RPRN] = {KC_0, KC_RPRN},
[P_MINS_UNDS] = {KC_MINS, KC_UNDS},
[P_EQL_PLUS] = {KC_EQL, KC_PLUS},
[P_LBRC_LCBR] = {KC_LBRC, KC_LCBR},
[P_RBRC_RCBR] = {KC_RBRC, KC_RCBR},
[P_SCLN_COLN] = {KC_SCLN, KC_COLN},
[P_QUOT_DQT] = {KC_QUOT, KC_DQT},
[P_COMM_LABK] = {KC_COMM, KC_LABK},
[P_DOT_RABK] = {KC_DOT, KC_RABK},
[P_SLSH_QUES] = {KC_SLSH, KC_QUES},
[P_BSLS_PIPE] = {KC_BSLS, KC_PIPE},
[P_PGUP_HOME] = {KC_PGUP, KC_HOME},
[P_PGDN_END] = {KC_PGUP, KC_END},
[P_SPC_ENT] = {KC_SPACE, KC_ENT},
[P_SPC_BKSPC] = {KC_SPACE, KC_BSPC},
};
enum {
DR_Q_LrALT,
DR_R_LrKey,
DR_T_LrMS,
};
const tap_dance_dual_role_t tap_dance_dual_roles[] PROGMEM = {
[DR_Q_LrALT] = DUAL_ROLE_TAP_DANCE_LAYER_MOVE(KC_Q, _ALT),
[DR_R_LrKey] = DUAL_ROLE_TAP_DANCE_LAYER_MOVE(KC_R, _RAISE),
[DR_T_LrMS] = DUAL_ROLE_TAP_DANCE_LAYER_MOVE(KC_T, _MOUSE),
};
//Tap Dance Definitions
tap_dance_action_t tap_dance_actions[] = {
[TD_DEL_BSPC] = ACTION_TAP_DANCE_DOUBLE(KC_DEL, KC_BSPC),
[TD_ESC_GRAVE] = ACTION_TAP_DANCE_DOUBLE(KC_ESC, KC_GRAVE),
[TD_TAB_TILDE] = ACTION_TAP_DANCE_DOUBLE(KC_TAB, KC_TILDE),
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[TD_DEL_BSPC] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_DEL_BSPC]),
[TD_ESC_GRAVE] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_ESC_GRAVE]),
[TD_TAB_TILDE] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_TAB_TILDE]),
[TD_9_LPRN] = ACTION_TAP_DANCE_DOUBLE(KC_9, KC_LPRN),
[TD_0_RPRN] = ACTION_TAP_DANCE_DOUBLE(KC_0, KC_RPRN),
[TD_9_LPRN] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_9_LPRN]),
[TD_0_RPRN] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_0_RPRN]),
[TD_MINS_UNDS] = ACTION_TAP_DANCE_DOUBLE(KC_MINS, KC_UNDS),
[TD_EQL_PLUS] = ACTION_TAP_DANCE_DOUBLE(KC_EQL, KC_PLUS),
[TD_MINS_UNDS] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_MINS_UNDS]),
[TD_EQL_PLUS] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_EQL_PLUS]),
[TD_LBRC_LCBR] = ACTION_TAP_DANCE_DOUBLE(KC_LBRC, KC_LCBR),
[TD_RBRC_RCBR] = ACTION_TAP_DANCE_DOUBLE(KC_RBRC, KC_RCBR),
[TD_LBRC_LCBR] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_LBRC_LCBR]),
[TD_RBRC_RCBR] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_RBRC_RCBR]),
[TD_SCLN_COLN] = ACTION_TAP_DANCE_DOUBLE(KC_SCLN, KC_COLN),
[TD_QUOT_DQT] = ACTION_TAP_DANCE_DOUBLE(KC_QUOT, KC_DQT),
[TD_SCLN_COLN] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_SCLN_COLN]),
[TD_QUOT_DQT] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_QUOT_DQT]),
[TD_COMM_LABK] = ACTION_TAP_DANCE_DOUBLE(KC_COMM, KC_LABK),
[TD_DOT_RABK] = ACTION_TAP_DANCE_DOUBLE(KC_DOT, KC_RABK),
[TD_SLSH_QUES] = ACTION_TAP_DANCE_DOUBLE(KC_SLSH, KC_QUES),
[TD_BSLS_PIPE] = ACTION_TAP_DANCE_DOUBLE(KC_BSLS, KC_PIPE),
[TD_COMM_LABK] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_COMM_LABK]),
[TD_DOT_RABK] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_DOT_RABK]),
[TD_SLSH_QUES] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_SLSH_QUES]),
[TD_BSLS_PIPE] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_BSLS_PIPE]),
[TD_PGUP_HOME] = ACTION_TAP_DANCE_DOUBLE(KC_PGUP, KC_HOME),
[TD_PGDN_END] = ACTION_TAP_DANCE_DOUBLE(KC_PGDN, KC_END),
[TD_PGUP_HOME] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_PGUP_HOME]),
[TD_PGDN_END] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_PGDN_END]),
[TD_Q_LrALT] = ACTION_TAP_DANCE_LAYER_MOVE(KC_Q, _ALT),
[TD_R_LrKey] = ACTION_TAP_DANCE_LAYER_MOVE(KC_R, _RAISE),
[TD_T_LrMS] = ACTION_TAP_DANCE_LAYER_MOVE(KC_T, _MOUSE),
[TD_Q_LrALT] = ACTION_TAP_DANCE_DUAL_ROLE(tap_dance_dual_roles[DR_Q_LrALT]),
[TD_R_LrKey] = ACTION_TAP_DANCE_DUAL_ROLE(tap_dance_dual_roles[DR_R_LrKey]),
[TD_T_LrMS] = ACTION_TAP_DANCE_DUAL_ROLE(tap_dance_dual_roles[DR_T_LrMS]),
[TD_SHIFT_CAPS] = ACTION_TAP_DANCE_FN_ADVANCED(NULL,lshift_finished, lshift_reset),
[TD_SPC_ENT] = ACTION_TAP_DANCE_DOUBLE(KC_SPACE, KC_ENT),
[TD_SPC_BKSPC] = ACTION_TAP_DANCE_DOUBLE(KC_SPACE, KC_BSPC),
[TD_SPC_ENT] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_SPC_ENT]),
[TD_SPC_BKSPC] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_SPC_BKSPC]),
[TD_LSPACE] = ACTION_TAP_DANCE_FN_ADVANCED(NULL,lspace_finished,lspace_reset),
[ALT_OSL1] = ACTION_TAP_DANCE_FN_ADVANCED(NULL,alt_finished, alt_reset),

View File

@ -72,27 +72,71 @@ void dance_onshot_lsft(tap_dance_state_t *state, void *user_data) {
}
}
enum {
P_DEL_BSPC,
P_ESC_GRAVE,
P_TAB_TILDE,
P_MINS_UNDS,
P_EQL_PLUS,
P_LBRC_LCBR,
P_RBRC_RCBR,
P_SCLN_COLN,
P_QUOT_DQT,
P_COMM_LABK,
P_DOT_RABK,
P_SLSH_QUES,
P_BSLS_PIPE,
P_3_F3,
};
const tap_dance_pair_t tap_dance_pairs[] PROGMEM = {
[P_DEL_BSPC] = {KC_DEL, KC_BSPC},
[P_ESC_GRAVE] = {KC_ESC, KC_GRAVE},
[P_TAB_TILDE] = {KC_TAB, KC_TILDE},
[P_MINS_UNDS] = {KC_MINS, KC_UNDS},
[P_EQL_PLUS] = {KC_EQL, KC_PLUS},
[P_LBRC_LCBR] = {KC_LBRC, KC_LCBR},
[P_RBRC_RCBR] = {KC_RBRC, KC_RCBR},
[P_SCLN_COLN] = {KC_SCLN, KC_COLN},
[P_QUOT_DQT] = {KC_QUOT, KC_DQT},
[P_COMM_LABK] = {KC_COMM, KC_LABK},
[P_DOT_RABK] = {KC_DOT, KC_RABK},
[P_SLSH_QUES] = {KC_SLSH, KC_QUES},
[P_BSLS_PIPE] = {KC_BSLS, KC_PIPE},
[P_3_F3] = {KC_3, KC_F3},
};
//Tap Dance Definitions
tap_dance_action_t tap_dance_actions[] = {
[TD_DEL_BSPC] = ACTION_TAP_DANCE_DOUBLE(KC_DEL, KC_BSPC),
[TD_ESC_GRAVE] = ACTION_TAP_DANCE_DOUBLE(KC_ESC, KC_GRAVE),
[TD_TAB_TILDE] = ACTION_TAP_DANCE_DOUBLE(KC_TAB, KC_TILDE),
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[TD_DEL_BSPC] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_DEL_BSPC]),
[TD_ESC_GRAVE] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_ESC_GRAVE]),
[TD_TAB_TILDE] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_TAB_TILDE]),
[TD_MINS_UNDS] = ACTION_TAP_DANCE_DOUBLE(KC_MINS, KC_UNDS),
[TD_EQL_PLUS] = ACTION_TAP_DANCE_DOUBLE(KC_EQL, KC_PLUS),
[TD_MINS_UNDS] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_MINS_UNDS]),
[TD_EQL_PLUS] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_EQL_PLUS]),
[TD_LBRC_LCBR] = ACTION_TAP_DANCE_DOUBLE(KC_LBRC, KC_LCBR),
[TD_RBRC_RCBR] = ACTION_TAP_DANCE_DOUBLE(KC_RBRC, KC_RCBR),
[TD_LBRC_LCBR] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_LBRC_LCBR]),
[TD_RBRC_RCBR] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_RBRC_RCBR]),
[TD_SCLN_COLN] = ACTION_TAP_DANCE_DOUBLE(KC_SCLN, KC_COLN),
[TD_QUOT_DQT] = ACTION_TAP_DANCE_DOUBLE(KC_QUOT, KC_DQT),
[TD_SCLN_COLN] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_SCLN_COLN]),
[TD_QUOT_DQT] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_QUOT_DQT]),
[TD_COMM_LABK] = ACTION_TAP_DANCE_DOUBLE(KC_COMM, KC_LABK),
[TD_DOT_RABK] = ACTION_TAP_DANCE_DOUBLE(KC_DOT, KC_RABK),
[TD_SLSH_QUES] = ACTION_TAP_DANCE_DOUBLE(KC_SLSH, KC_QUES),
[TD_BSLS_PIPE] = ACTION_TAP_DANCE_DOUBLE(KC_BSLS, KC_PIPE),
[TD_COMM_LABK] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_COMM_LABK]),
[TD_DOT_RABK] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_DOT_RABK]),
[TD_SLSH_QUES] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_SLSH_QUES]),
[TD_BSLS_PIPE] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_BSLS_PIPE]),
[TD_3_F3] = ACTION_TAP_DANCE_DOUBLE(KC_3, KC_F3),
[TD_3_F3] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_3_F3]),
[TD_SHIFT_CAPS] = ACTION_TAP_DANCE_FN(dance_onshot_lsft)
};

View File

@ -250,45 +250,110 @@ void lshift_reset (tap_dance_state_t *state, void *user_data) {
lshifttap_state.state = 0;
}
enum {
P_DEL_BSPC,
P_ESC_GRAVE,
P_TAB_TILDE,
P_9_LPRN,
P_0_RPRN,
P_MINS_UNDS,
P_EQL_PLUS,
P_LBRC_LCBR,
P_RBRC_RCBR,
P_SCLN_COLN,
P_QUOT_DQT,
P_COMM_LABK,
P_DOT_RABK,
P_SLSH_QUES,
P_BSLS_PIPE,
P_PGUP_HOME,
P_PGDN_END,
P_SPC_ENT,
};
const tap_dance_pair_t tap_dance_pairs[] PROGMEM = {
[P_DEL_BSPC] = {KC_DEL, KC_BSPC},
[P_ESC_GRAVE] = {KC_ESC, KC_GRAVE},
[P_TAB_TILDE] = {KC_TAB, KC_TILDE},
[P_9_LPRN] = {KC_9, KC_LPRN},
[P_0_RPRN] = {KC_0, KC_RPRN},
[P_MINS_UNDS] = {KC_MINS, KC_UNDS},
[P_EQL_PLUS] = {KC_EQL, KC_PLUS},
[P_LBRC_LCBR] = {KC_LBRC, KC_LCBR},
[P_RBRC_RCBR] = {KC_RBRC, KC_RCBR},
[P_SCLN_COLN] = {KC_SCLN, KC_COLN},
[P_QUOT_DQT] = {KC_QUOT, KC_DQT},
[P_COMM_LABK] = {KC_COMM, KC_LABK},
[P_DOT_RABK] = {KC_DOT, KC_RABK},
[P_SLSH_QUES] = {KC_SLSH, KC_QUES},
[P_BSLS_PIPE] = {KC_BSLS, KC_PIPE},
[P_PGUP_HOME] = {KC_PGUP, KC_HOME},
[P_PGDN_END] = {KC_PGUP, KC_END},
[P_SPC_ENT] = {KC_SPACE, KC_ENT},
};
enum {
DR_Q_LrALT,
DR_R_LrKey,
DR_T_LrMS,
};
const tap_dance_dual_role_t tap_dance_dual_roles[] PROGMEM = {
[DR_Q_LrALT] = DUAL_ROLE_TAP_DANCE_LAYER_MOVE(KC_Q, _ALT),
[DR_R_LrKey] = DUAL_ROLE_TAP_DANCE_LAYER_MOVE(KC_R, _RAISE),
[DR_T_LrMS] = DUAL_ROLE_TAP_DANCE_LAYER_MOVE(KC_T, _MOUSE),
};
//Tap Dance Definitions
tap_dance_action_t tap_dance_actions[] = {
[TD_DEL_BSPC] = ACTION_TAP_DANCE_DOUBLE(KC_DEL, KC_BSPC),
[TD_ESC_GRAVE] = ACTION_TAP_DANCE_DOUBLE(KC_ESC, KC_GRAVE),
[TD_TAB_TILDE] = ACTION_TAP_DANCE_DOUBLE(KC_TAB, KC_TILDE),
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[TD_DEL_BSPC] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_DEL_BSPC]),
[TD_ESC_GRAVE] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_ESC_GRAVE]),
[TD_TAB_TILDE] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_TAB_TILDE]),
[TD_9_LPRN] = ACTION_TAP_DANCE_DOUBLE(KC_9, KC_LPRN),
[TD_0_RPRN] = ACTION_TAP_DANCE_DOUBLE(KC_0, KC_RPRN),
[TD_9_LPRN] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_9_LPRN]),
[TD_0_RPRN] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_0_RPRN]),
[TD_MINS_UNDS] = ACTION_TAP_DANCE_DOUBLE(KC_MINS, KC_UNDS),
[TD_EQL_PLUS] = ACTION_TAP_DANCE_DOUBLE(KC_EQL, KC_PLUS),
[TD_MINS_UNDS] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_MINS_UNDS]),
[TD_EQL_PLUS] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_EQL_PLUS]),
[TD_LBRC_LCBR] = ACTION_TAP_DANCE_DOUBLE(KC_LBRC, KC_LCBR),
[TD_RBRC_RCBR] = ACTION_TAP_DANCE_DOUBLE(KC_RBRC, KC_RCBR),
[TD_LBRC_LCBR] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_LBRC_LCBR]),
[TD_RBRC_RCBR] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_RBRC_RCBR]),
[TD_SCLN_COLN] = ACTION_TAP_DANCE_DOUBLE(KC_SCLN, KC_COLN),
[TD_QUOT_DQT] = ACTION_TAP_DANCE_DOUBLE(KC_QUOT, KC_DQT),
[TD_SCLN_COLN] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_SCLN_COLN]),
[TD_QUOT_DQT] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_QUOT_DQT]),
[TD_COMM_LABK] = ACTION_TAP_DANCE_DOUBLE(KC_COMM, KC_LABK),
[TD_DOT_RABK] = ACTION_TAP_DANCE_DOUBLE(KC_DOT, KC_RABK),
[TD_SLSH_QUES] = ACTION_TAP_DANCE_DOUBLE(KC_SLSH, KC_QUES),
[TD_BSLS_PIPE] = ACTION_TAP_DANCE_DOUBLE(KC_BSLS, KC_PIPE),
[TD_COMM_LABK] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_COMM_LABK]),
[TD_DOT_RABK] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_DOT_RABK]),
[TD_SLSH_QUES] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_SLSH_QUES]),
[TD_BSLS_PIPE] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_BSLS_PIPE]),
[TD_PGUP_HOME] = ACTION_TAP_DANCE_DOUBLE(KC_PGUP, KC_HOME),
[TD_PGDN_END] = ACTION_TAP_DANCE_DOUBLE(KC_PGUP, KC_END),
[TD_PGUP_HOME] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_PGUP_HOME]),
[TD_PGDN_END] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_PGDN_END]),
[TD_Q_LrALT] = ACTION_TAP_DANCE_LAYER_MOVE(KC_Q, _ALT),
[TD_R_LrKey] = ACTION_TAP_DANCE_LAYER_MOVE(KC_R, _RAISE),
[TD_T_LrMS] = ACTION_TAP_DANCE_LAYER_MOVE(KC_T, _MOUSE),
[TD_Q_LrALT] = ACTION_TAP_DANCE_DUAL_ROLE(tap_dance_dual_roles[DR_Q_LrALT]),
[TD_R_LrKey] = ACTION_TAP_DANCE_DUAL_ROLE(tap_dance_dual_roles[DR_R_LrKey]),
[TD_T_LrMS] = ACTION_TAP_DANCE_DUAL_ROLE(tap_dance_dual_roles[DR_T_LrMS]),
[TD_SHIFT_CAPS] = ACTION_TAP_DANCE_FN_ADVANCED(NULL,lshift_finished, lshift_reset),
[TD_SPC_ENT] = ACTION_TAP_DANCE_DOUBLE(KC_SPACE, KC_ENT),
[TD_SPC_ENT] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_SPC_ENT]),
[ALT_OSL1] = ACTION_TAP_DANCE_FN_ADVANCED(NULL,alt_finished, alt_reset),
[CTL_OSL1] = ACTION_TAP_DANCE_FN_ADVANCED(NULL,ctl_finished, ctl_reset),
[TD_LayerDn] = ACTION_TAP_DANCE_FN_ADVANCED(NULL,layerDown_finished, layerDown_reset)
};
// Fillers to make layering more clear

View File

@ -34,10 +34,16 @@ enum {
};
// Tap dance actions - double tap for Caps Lock.
tap_dance_action_t tap_dance_actions[] = {
const tap_dance_pair_t tap_dance_pairs[] PROGMEM = {
[SFT_CAPS] = ACTION_TAP_DANCE_DOUBLE(KC_LSFT, KC_CAPS),
[SFT_CAPS] = {KC_LSFT, KC_CAPS},
};
// Tap dance actions - double tap for Caps Lock.
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[SFT_CAPS] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[SFT_CAPS]),
};

View File

@ -48,9 +48,17 @@ uint8_t cur_dance(tap_dance_state_t *state);
void ql_finished(tap_dance_state_t *state, void *user_data);
void ql_reset(tap_dance_state_t *state, void *user_data);
enum {
P_LSFT_CAPS,
};
const tap_dance_pair_t tap_dance_pairs[] PROGMEM = {
[P_LSFT_CAPS] = {KC_LSFT, KC_CAPS},
};
// Tap Dance definitions
tap_dance_action_t tap_dance_actions[] = {
[TD_LSFT_CAPS] = ACTION_TAP_DANCE_DOUBLE(KC_LSFT, KC_CAPS),
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[TD_LSFT_CAPS] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_LSFT_CAPS]),
[TD_ESC_NUM] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, ql_finished, ql_reset),
};

View File

@ -47,9 +47,17 @@ uint8_t cur_dance(tap_dance_state_t *state);
void ql_finished(tap_dance_state_t *state, void *user_data);
void ql_reset(tap_dance_state_t *state, void *user_data);
enum {
P_LSFT_CAPS,
};
const tap_dance_pair_t tap_dance_pairs[] PROGMEM = {
[P_LSFT_CAPS] = {KC_LSFT, KC_CAPS},
};
// Tap Dance definitions
tap_dance_action_t tap_dance_actions[] = {
[TD_LSFT_CAPS] = ACTION_TAP_DANCE_DOUBLE(KC_LSFT, KC_CAPS),
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[TD_LSFT_CAPS] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_LSFT_CAPS]),
[TD_ESC_NUM] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, ql_finished, ql_reset),
};

View File

@ -48,9 +48,17 @@ uint8_t cur_dance(tap_dance_state_t *state);
void ql_finished(tap_dance_state_t *state, void *user_data);
void ql_reset(tap_dance_state_t *state, void *user_data);
enum {
P_LSFT_CAPS,
};
const tap_dance_pair_t tap_dance_pairs[] PROGMEM = {
[P_LSFT_CAPS] = {KC_LSFT, KC_CAPS},
};
// Tap Dance definitions
tap_dance_action_t tap_dance_actions[] = {
[TD_LSFT_CAPS] = ACTION_TAP_DANCE_DOUBLE(KC_LSFT, KC_CAPS),
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[TD_LSFT_CAPS] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_LSFT_CAPS]),
[TD_ESC_NUM] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, ql_finished, ql_reset),
};

View File

@ -9,11 +9,21 @@ enum {
TD_F2_F12,
};
enum {
P_F1_F11,
P_F2_F12,
};
const tap_dance_pair_t tap_dance_pairs[] PROGMEM = {
[P_F1_F11] = {KC_F1, KC_F11},
[P_F2_F12] = {KC_F2, KC_F12},
};
// Tap Dance definitions
tap_dance_action_t tap_dance_actions[] = {
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
// Tap once for F1, twice for F11
[TD_F1_F11] = ACTION_TAP_DANCE_DOUBLE(KC_F1, KC_F11),
[TD_F2_F12] = ACTION_TAP_DANCE_DOUBLE(KC_F2, KC_F12),
[TD_F1_F11] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_F1_F11]),
[TD_F2_F12] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_F2_F12]),
};
bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) {

View File

@ -48,19 +48,19 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT(/* Base */
TD(TAPPY_KEY),KC_HOME, KC_PGUP,
KC_DEL, KC_END, KC_PGDN,
KC_UP,
KC_LEFT, KC_DOWN, KC_RIGHT),
[_FN0] = LAYOUT(/* function layer */
KC_TRNS, KC_PAUS, KC_VOLU,
KC_ENTER, KC_SCRL, KC_VOLD,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS),
[_ML1] = LAYOUT(/* media function layer, toggled on a single tap */
KC_TRNS, KC_TRNS, KC_VOLU,
KC_TRNS, KC_TRNS, KC_VOLU,
KC_MUTE, KC_TRNS, KC_VOLD,
KC_SPC,
KC_MRWD, KC_MPLY, KC_MFFD),
};
@ -122,10 +122,10 @@ void tk_reset(tap_dance_state_t *state, void *user_data){
layer_off(_FN0);
}
//reset the state
tk_tap_state.state = 0;
tk_tap_state.state = 0;
}
//associate the tap dance key with its functionality
tap_dance_action_t tap_dance_actions[] = {
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[TAPPY_KEY] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, tk_finished, tk_reset)
};

View File

@ -39,10 +39,18 @@ void dance_rst_reset (tap_dance_state_t *state, void *user_data) { // *Line_Note
}
}
enum {
P_DBQT,
};
const tap_dance_pair_t tap_dance_pairs[] PROGMEM = {
[P_DBQT] = {KC_QUOTE, KC_DQT},
};
//Tap Dance Functions:
tap_dance_action_t tap_dance_actions[] = {
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[TD_RST] = ACTION_TAP_DANCE_FN_ADVANCED (NULL, NULL, dance_rst_reset), // References "dance_rst_reset" (*Line_Note.001)
[TD_DBQT] = ACTION_TAP_DANCE_DOUBLE (KC_QUOTE, KC_DQT)
[TD_DBQT] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_DBQT]),
};

View File

@ -39,10 +39,18 @@ void dance_rst_reset (tap_dance_state_t *state, void *user_data) { // *Line_Note
}
}
enum {
P_DBQT,
};
const tap_dance_pair_t tap_dance_pairs[] PROGMEM = {
[P_DBQT] = {KC_QUOTE, KC_DQT},
};
//Tap Dance Functions:
tap_dance_action_t tap_dance_actions[] = {
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[TD_RST] = ACTION_TAP_DANCE_FN_ADVANCED (NULL, NULL, dance_rst_reset), // References "dance_rst_reset" (*Line_Note.001)
[TD_DBQT] = ACTION_TAP_DANCE_DOUBLE (KC_QUOTE, KC_DQT)
[TD_DBQT] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_DBQT]),
};

View File

@ -55,9 +55,19 @@ enum custom_keycodes {
// #define KC_CODO TD(TD_CODO)
// #define KC_SLRO TD(TD_SLRO)
// tap_dance_action_t tap_dance_actions[] = {
// [TD_CODO] = ACTION_TAP_DANCE_DOUBLE(KC_COMM, KC_DOT),
// [TD_SLRO] = ACTION_TAP_DANCE_DOUBLE(KC_SLSH, JP_BSLS),
// enum {
// P_CODO,
// P_SLRO,
// };
// const tap_dance_pair_t tap_dance_pairs[] PROGMEM = {
// [P_CODO] = {KC_COMM, KC_DOT},
// [P_SLRO] = {KC_SLSH, JP_BSLS},
// };
// const tap_dance_action_t tap_dance_actions[] PROGMEM = {
// [TD_CODO] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_CODO]),
// [TD_SLRO] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_SLRO]),
// };
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {

View File

@ -32,9 +32,19 @@ enum{
DANCE_PGUP_TOP,
};
tap_dance_action_t tap_dance_actions[] = {
[DANCE_PGDN_BOTTOM] = ACTION_TAP_DANCE_DOUBLE(KC_PGDN, LGUI(KC_DOWN)),
[DANCE_PGUP_TOP] = ACTION_TAP_DANCE_DOUBLE(KC_PGUP, LGUI(KC_UP)),
enum {
P_DANCE_PGDN_BOTTOM,
P_DANCE_PGUP_TOP,
};
const tap_dance_pair_t tap_dance_pairs[] PROGMEM = {
[P_DANCE_PGDN_BOTTOM] = {KC_PGDN, LGUI(KC_DOWN)},
[P_DANCE_PGUP_TOP] = {KC_PGUP, LGUI(KC_UP)},
};
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[DANCE_PGDN_BOTTOM] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_DANCE_PGDN_BOTTOM]),
[DANCE_PGUP_TOP] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_DANCE_PGUP_TOP]),
};
#define KEY_DANCE(a) TD(a)

View File

@ -113,7 +113,7 @@ void left_enter_reset(tap_dance_state_t *state, void *user_data) {
left_enter_tap_state.state = 0;
}
tap_dance_action_t tap_dance_actions[] = {
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[left_enter] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, left_enter_finished, left_enter_reset)
};

View File

@ -56,9 +56,19 @@ enum tapdances{
#define KC_CODO TD(TD_CODO)
// #define KC_MNUB TD(TD_MNUB)
tap_dance_action_t tap_dance_actions[] = {
[TD_CODO] = ACTION_TAP_DANCE_DOUBLE(KC_COMM, KC_DOT),
// [TD_MNUB] = ACTION_TAP_DANCE_DOUBLE(KC_MINS, LSFT(JP_BSLS)),
enum {
P_CODO,
// P_MNUB,
};
const tap_dance_pair_t tap_dance_pairs[] PROGMEM = {
[P_CODO] = {KC_COMM, KC_DOT},
// [P_MNUB] = {KC_MINS, LSFT(JP_BSLS)},
};
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[TD_CODO] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_CODO]),
// [TD_MNUB] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_MNUB]),
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {

View File

@ -54,9 +54,17 @@ enum tapdances{
// Tap dance
#define KC_CODO TD(TD_CODO)
tap_dance_action_t tap_dance_actions[] = {
[TD_CODO] = ACTION_TAP_DANCE_DOUBLE(KC_COMM, KC_DOT),
};
enum {
P_CODO,
};
const tap_dance_pair_t tap_dance_pairs[] PROGMEM = {
[P_CODO] = {KC_COMM, KC_DOT},
};
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[TD_CODO] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_CODO]),
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_BASE] = LAYOUT(

View File

@ -30,8 +30,16 @@ enum tapdances{
TD_ENT = 0,
};
tap_dance_action_t tap_dance_actions[] = {
[TD_ENT] = ACTION_TAP_DANCE_DOUBLE(KC_ENT, KC_ENT),
enum {
P_ENT,
};
const tap_dance_pair_t tap_dance_pairs[] PROGMEM = {
[P_ENT] = {KC_ENT, KC_ENT},
};
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[TD_ENT] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_ENT]),
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
@ -59,7 +67,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
//|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------+--------+--------|
_______,_______,_______,_______,_______,_______, _______, _______, _______, _______, _______, _______, _______, _______, KC_END,
//|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------+--------+--------|
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
//|-----------------------------------------------------| |--------------------------------------------------------------------------------'
)
};

View File

@ -40,7 +40,7 @@ void dance_key_two (tap_dance_state_t *state, void *user_data) {
}
}
tap_dance_action_t tap_dance_actions[] = {
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[TD_KEY_1] = ACTION_TAP_DANCE_FN(dance_key_one),
[TD_KEY_2] = ACTION_TAP_DANCE_FN(dance_key_two),
};

View File

@ -21,10 +21,18 @@ void dance_rst_reset (tap_dance_state_t *state, void *user_data) {
}
}
enum {
P_DBQT,
};
const tap_dance_pair_t tap_dance_pairs[] PROGMEM = {
[P_DBQT] = {KC_QUOTE, KC_DQT},
};
//All tap dance functions would go here. Only showing this one.
tap_dance_action_t tap_dance_actions[] = {
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[TD_RST] = ACTION_TAP_DANCE_FN_ADVANCED (NULL, NULL, dance_rst_reset),
[TD_DBQT] = ACTION_TAP_DANCE_DOUBLE (KC_QUOTE, KC_DQT)
[TD_DBQT] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_DBQT]),
};
enum custom_keycodes {

View File

@ -21,10 +21,18 @@ void dance_rst_reset (tap_dance_state_t *state, void *user_data) {
}
}
enum {
P_DBQT,
};
const tap_dance_pair_t tap_dance_pairs[] PROGMEM = {
[P_DBQT] = {KC_QUOTE, KC_DQT},
};
//All tap dance functions would go here. Only showing this one.
tap_dance_action_t tap_dance_actions[] = {
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[TD_RST] = ACTION_TAP_DANCE_FN_ADVANCED (NULL, NULL, dance_rst_reset),
[TD_DBQT] = ACTION_TAP_DANCE_DOUBLE (KC_QUOTE, KC_DQT)
[TD_DBQT] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_DBQT]),
};
enum custom_keycodes {

View File

@ -26,7 +26,7 @@ void dance_rst_reset (tap_dance_state_t *state, void *user_data) {
}
//All tap dance functions would go here. Only showing this one.
tap_dance_action_t tap_dance_actions[] = {
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[TD_RST] = ACTION_TAP_DANCE_FN_ADVANCED (NULL, NULL, dance_rst_reset)
};

View File

@ -79,7 +79,7 @@ void se_reset (tap_dance_state_t *state, void *user_data) {
se_tap_state.state = 0;
}
tap_dance_action_t tap_dance_actions[] = {
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[SE_TAP_DANCE] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, se_finished, se_reset)
};

View File

@ -59,7 +59,7 @@ void dance_toggle (tap_dance_state_t *state, void *user_data) {
}
//Tap Dance Definitions
tap_dance_action_t tap_dance_actions[] = {
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[TD_TOGGLE] = ACTION_TAP_DANCE_FN(dance_toggle)
// Other declarations would go here, separated by commas, if you have them
};

View File

@ -79,6 +79,6 @@ void dance_enc_reset(tap_dance_state_t *state, void *user_data) {
}
// Tap Dance definitions
tap_dance_action_t tap_dance_actions[] = {
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[ENC_TAP] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, dance_enc_finished, dance_enc_reset),
};

View File

@ -50,8 +50,16 @@ layer_state_t layer_state_set_user(layer_state_t state)
return state;
}
// Tap Dance Definitions
tap_dance_action_t tap_dance_actions[] = {
// double tap for caps
[TD_SCAPS] = ACTION_TAP_DANCE_DOUBLE(KC_LSFT, KC_CAPS)
enum {
P_SCAPS,
};
const tap_dance_pair_t tap_dance_pairs[] PROGMEM = {
[P_SCAPS] = {KC_LSFT, KC_CAPS},
};
// Tap Dance Definitions
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
// double tap for caps
[TD_SCAPS] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_SCAPS]),
};

View File

@ -61,9 +61,16 @@ layer_state_t layer_state_set_user(layer_state_t state)
return state;
}
// Tap Dance Definitions
tap_dance_action_t tap_dance_actions[] = {
// Tap once for
[TD_SCAPS] = ACTION_TAP_DANCE_DOUBLE(KC_LSFT, KC_CAPS),
enum {
P_SCAPS,
};
const tap_dance_pair_t tap_dance_pairs[] PROGMEM = {
[P_SCAPS] = {KC_LSFT, KC_CAPS},
};
// Tap Dance Definition
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
// Tap once for
[TD_SCAPS] = ACTION_TAP_DANCE_DOUBLE(tap_dance_pairs[P_SCAPS]),
};

View File

@ -140,7 +140,7 @@ tap_dance_action_t* tap_dance_get_raw(uint16_t tap_dance_idx) {
if (tap_dance_idx >= tap_dance_count_raw()) {
return NULL;
}
return &tap_dance_actions[tap_dance_idx];
return (tap_dance_action_t*)&tap_dance_actions[tap_dance_idx];
}
__attribute__((weak)) tap_dance_action_t* tap_dance_get(uint16_t tap_dance_idx) {

View File

@ -25,10 +25,6 @@
static uint16_t active_td;
#ifndef TAP_DANCE_MAX_SIMULTANEOUS
# define TAP_DANCE_MAX_SIMULTANEOUS 3
#endif
static tap_dance_state_t tap_dance_states[TAP_DANCE_MAX_SIMULTANEOUS];
static uint16_t last_tap_time;
@ -40,14 +36,15 @@ tap_dance_state_t *tap_dance_get_state(uint8_t tap_dance_idx) {
}
// Search for a state already used for this keycode
for (i = 0; i < TAP_DANCE_MAX_SIMULTANEOUS; i++) {
if (tap_dance_states[i].in_use && tap_dance_states[i].index == tap_dance_idx) {
if (tap_dance_states[i].in_use && tap_dance_states[i].tap_dance_idx == tap_dance_idx) {
return &tap_dance_states[i];
}
}
// Search for the first available state
for (i = 0; i < TAP_DANCE_MAX_SIMULTANEOUS; i++) {
if (!tap_dance_states[i].in_use) {
tap_dance_states[i].index = tap_dance_idx;
tap_dance_states[i].tap_dance_idx = tap_dance_idx;
tap_dance_states[i].state_idx = i;
tap_dance_states[i].in_use = true;
return &tap_dance_states[i];
}
@ -57,56 +54,62 @@ tap_dance_state_t *tap_dance_get_state(uint8_t tap_dance_idx) {
}
void tap_dance_pair_on_each_tap(tap_dance_state_t *state, void *user_data) {
tap_dance_pair_t *pair = (tap_dance_pair_t *)user_data;
tap_dance_pair_t pair;
memcpy_P(&pair, user_data, sizeof(tap_dance_pair_t));
if (state->count == 2) {
register_code16(pair->kc2);
register_code16(pair.kc2);
state->finished = true;
}
}
void tap_dance_pair_finished(tap_dance_state_t *state, void *user_data) {
tap_dance_pair_t *pair = (tap_dance_pair_t *)user_data;
tap_dance_pair_t pair;
memcpy_P(&pair, user_data, sizeof(tap_dance_pair_t));
register_code16(pair->kc1);
register_code16(pair.kc1);
}
void tap_dance_pair_reset(tap_dance_state_t *state, void *user_data) {
tap_dance_pair_t *pair = (tap_dance_pair_t *)user_data;
tap_dance_pair_t pair;
memcpy_P(&pair, user_data, sizeof(tap_dance_pair_t));
if (state->count == 1) {
wait_ms(TAP_CODE_DELAY);
unregister_code16(pair->kc1);
unregister_code16(pair.kc1);
} else if (state->count == 2) {
unregister_code16(pair->kc2);
unregister_code16(pair.kc2);
}
}
void tap_dance_dual_role_on_each_tap(tap_dance_state_t *state, void *user_data) {
tap_dance_dual_role_t *pair = (tap_dance_dual_role_t *)user_data;
tap_dance_dual_role_t pair;
memcpy_P(&pair, user_data, sizeof(tap_dance_dual_role_t));
if (state->count == 2) {
layer_move(pair->layer);
layer_move(pair.layer);
state->finished = true;
}
}
void tap_dance_dual_role_finished(tap_dance_state_t *state, void *user_data) {
tap_dance_dual_role_t *pair = (tap_dance_dual_role_t *)user_data;
tap_dance_dual_role_t pair;
memcpy_P(&pair, user_data, sizeof(tap_dance_dual_role_t));
if (state->count == 1) {
register_code16(pair->kc);
register_code16(pair.kc);
} else if (state->count == 2) {
pair->layer_function(pair->layer);
pair.layer_function(pair.layer);
}
}
void tap_dance_dual_role_reset(tap_dance_state_t *state, void *user_data) {
tap_dance_dual_role_t *pair = (tap_dance_dual_role_t *)user_data;
tap_dance_dual_role_t pair;
memcpy_P(&pair, user_data, sizeof(tap_dance_dual_role_t));
if (state->count == 1) {
wait_ms(TAP_CODE_DELAY);
unregister_code16(pair->kc);
unregister_code16(pair.kc);
}
}
@ -159,21 +162,21 @@ static inline void process_tap_dance_action_on_dance_finished(tap_dance_action_t
}
bool preprocess_tap_dance(uint16_t keycode, keyrecord_t *record) {
tap_dance_action_t *action;
tap_dance_state_t * state;
tap_dance_action_t action;
tap_dance_state_t *state;
if (!record->event.pressed) return false;
if (!active_td || keycode == active_td) return false;
action = tap_dance_get(QK_TAP_DANCE_GET_INDEX(active_td));
state = tap_dance_get_state(QK_TAP_DANCE_GET_INDEX(active_td));
memcpy_P(&action, tap_dance_get(QK_TAP_DANCE_GET_INDEX(active_td)), sizeof(tap_dance_action_t));
state = tap_dance_get_state(QK_TAP_DANCE_GET_INDEX(active_td));
if (state == NULL) {
return false;
}
state->interrupted = true;
state->interrupting_keycode = keycode;
process_tap_dance_action_on_dance_finished(action, state);
process_tap_dance_action_on_dance_finished(&action, state);
// Tap dance actions can leave some weak mods active (e.g., if the tap dance is mapped to a keycode with
// modifiers), but these weak mods should not affect the keypress which interrupted the tap dance.
@ -187,9 +190,9 @@ bool preprocess_tap_dance(uint16_t keycode, keyrecord_t *record) {
}
bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
uint8_t td_index;
tap_dance_action_t *action;
tap_dance_state_t * state;
uint8_t td_index;
tap_dance_action_t action;
tap_dance_state_t *state;
switch (keycode) {
case QK_TAP_DANCE ... QK_TAP_DANCE_MAX:
@ -197,20 +200,20 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
if (td_index >= tap_dance_count()) {
return false;
}
action = tap_dance_get(td_index);
state = tap_dance_get_state(td_index);
memcpy_P(&action, tap_dance_get(td_index), sizeof(tap_dance_action_t));
state = tap_dance_get_state(td_index);
if (state == NULL) {
return false;
}
state->pressed = record->event.pressed;
if (record->event.pressed) {
last_tap_time = timer_read();
process_tap_dance_action_on_each_tap(action, state);
process_tap_dance_action_on_each_tap(&action, state);
active_td = state->finished ? 0 : keycode;
} else {
process_tap_dance_action_on_each_release(action, state);
process_tap_dance_action_on_each_release(&action, state);
if (state->finished) {
process_tap_dance_action_on_reset(action, state);
process_tap_dance_action_on_reset(&action, state);
if (active_td == keycode) {
active_td = 0;
}
@ -224,19 +227,19 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
}
void tap_dance_task(void) {
tap_dance_action_t *action;
tap_dance_state_t * state;
tap_dance_action_t action;
tap_dance_state_t *state;
if (!active_td || timer_elapsed(last_tap_time) <= GET_TAPPING_TERM(active_td, &(keyrecord_t){})) return;
action = tap_dance_get(QK_TAP_DANCE_GET_INDEX(active_td));
memcpy_P(&action, tap_dance_get(QK_TAP_DANCE_GET_INDEX(active_td)), sizeof(tap_dance_action_t));
state = tap_dance_get_state(QK_TAP_DANCE_GET_INDEX(active_td));
if (state != NULL && !state->interrupted) {
process_tap_dance_action_on_dance_finished(action, state);
process_tap_dance_action_on_dance_finished(&action, state);
}
}
void reset_tap_dance(tap_dance_state_t *state) {
active_td = 0;
process_tap_dance_action_on_reset(tap_dance_get(state->index), state);
process_tap_dance_action_on_reset(tap_dance_get(state->tap_dance_idx), state);
}

View File

@ -21,6 +21,10 @@
#include "action.h"
#include "quantum_keycodes.h"
#ifndef TAP_DANCE_MAX_SIMULTANEOUS
# define TAP_DANCE_MAX_SIMULTANEOUS 3
#endif
typedef struct {
uint16_t interrupting_keycode;
uint8_t count;
@ -32,7 +36,8 @@ typedef struct {
bool finished : 1;
bool interrupted : 1;
bool in_use : 1;
uint8_t index;
uint8_t tap_dance_idx;
uint8_t state_idx;
} tap_dance_state_t;
typedef void (*tap_dance_user_fn_t)(tap_dance_state_t *state, void *user_data);
@ -58,14 +63,17 @@ typedef struct {
void (*layer_function)(uint8_t);
} tap_dance_dual_role_t;
#define ACTION_TAP_DANCE_DOUBLE(kc1, kc2) \
{ .fn = {tap_dance_pair_on_each_tap, tap_dance_pair_finished, tap_dance_pair_reset, NULL}, .user_data = (void *)&((tap_dance_pair_t){kc1, kc2}), }
#define ACTION_TAP_DANCE_DOUBLE(pair) \
{ .fn = {tap_dance_pair_on_each_tap, tap_dance_pair_finished, tap_dance_pair_reset, NULL}, .user_data = (void *)&(pair), }
#define ACTION_TAP_DANCE_LAYER_MOVE(kc, layer) \
{ .fn = {tap_dance_dual_role_on_each_tap, tap_dance_dual_role_finished, tap_dance_dual_role_reset, NULL}, .user_data = (void *)&((tap_dance_dual_role_t){kc, layer, layer_move}), }
#define DUAL_ROLE_TAP_DANCE_LAYER_MOVE(kc, layer) \
{kc, layer, layer_move}
#define ACTION_TAP_DANCE_LAYER_TOGGLE(kc, layer) \
{ .fn = {NULL, tap_dance_dual_role_finished, tap_dance_dual_role_reset, NULL}, .user_data = (void *)&((tap_dance_dual_role_t){kc, layer, layer_invert}), }
#define DUAL_ROLE_TAP_DANCE_LAYER_TOGGLE(kc, layer) \
{kc, layer, layer_invert}
#define ACTION_TAP_DANCE_DUAL_ROLE(dual_role) \
{ .fn = {tap_dance_dual_role_on_each_tap, tap_dance_dual_role_finished, tap_dance_dual_role_reset, NULL}, .user_data = (void *)&(dual_role), }
#define ACTION_TAP_DANCE_FN(user_fn) \
{ .fn = {NULL, user_fn, NULL, NULL}, .user_data = NULL, }

View File

@ -76,27 +76,34 @@ void dance_flsh_reset(tap_dance_state_t *state, void *user_data) {
typedef struct {
uint16_t tap;
uint16_t hold;
uint16_t held;
} tap_dance_tap_hold_t;
typedef struct {
uint16_t held;
} tap_dance_tap_hold_state_t;
static tap_dance_tap_hold_state_t tap_dance_tap_hold_states[TAP_DANCE_MAX_SIMULTANEOUS];
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
tap_dance_action_t *action;
tap_dance_state_t* state;
tap_dance_tap_hold_t tap_hold;
switch (keycode) {
case TD(CT_CLN):
action = tap_dance_get(QK_TAP_DANCE_GET_INDEX(keycode));
state = tap_dance_get_state(QK_TAP_DANCE_GET_INDEX(keycode));
if (!record->event.pressed && state != NULL && state->count && !state->finished) {
tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)action->user_data;
tap_code16(tap_hold->tap);
memcpy_P(&tap_hold, (tap_dance_tap_hold_t *)action->user_data, sizeof(tap_dance_tap_hold_t));
tap_code16(tap_hold.tap);
}
}
return true;
}
void tap_dance_tap_hold_finished(tap_dance_state_t *state, void *user_data) {
tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)user_data;
tap_dance_tap_hold_t tap_hold;
memcpy_P(&tap_hold, user_data, sizeof(tap_dance_tap_hold_t));
if (state->pressed) {
if (state->count == 1
@ -104,27 +111,28 @@ void tap_dance_tap_hold_finished(tap_dance_state_t *state, void *user_data) {
&& !state->interrupted
#endif
) {
register_code16(tap_hold->hold);
tap_hold->held = tap_hold->hold;
register_code16(tap_hold.hold);
tap_dance_tap_hold_states[state->state_idx].held = tap_hold.hold;
} else {
register_code16(tap_hold->tap);
tap_hold->held = tap_hold->tap;
register_code16(tap_hold.tap);
tap_dance_tap_hold_states[state->state_idx].held = tap_hold.tap;
}
}
}
void tap_dance_tap_hold_reset(tap_dance_state_t *state, void *user_data) {
tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)user_data;
tap_dance_tap_hold_t tap_hold;
memcpy_P(&tap_hold, user_data, sizeof(tap_dance_tap_hold_t));
if (tap_hold->held) {
unregister_code16(tap_hold->held);
tap_hold->held = 0;
if (tap_dance_tap_hold_states[state->state_idx].held) {
unregister_code16(tap_dance_tap_hold_states[state->state_idx].held);
tap_dance_tap_hold_states[state->state_idx].held = 0;
}
}
#define ACTION_TAP_DANCE_TAP_HOLD(tap, hold) \
{ .fn = {NULL, tap_dance_tap_hold_finished, tap_dance_tap_hold_reset}, .user_data = (void *)&((tap_dance_tap_hold_t){tap, hold, 0}), }
#define ACTION_TAP_DANCE_TAP_HOLD(tap_hold) {{NULL, tap_dance_tap_hold_finished, tap_dance_tap_hold_reset}, (void *)&(tap_hold)}
const tap_dance_tap_hold_t d_ct_cln PROGMEM = {KC_COLN, KC_SCLN};
// Example 4
@ -211,11 +219,13 @@ static void release_reset(tap_dance_state_t *state, void *user_data) {
tap_code16(KC_R);
}
tap_dance_action_t tap_dance_actions[] = {
[TD_ESC_CAPS] = ACTION_TAP_DANCE_DOUBLE(KC_ESC, KC_CAPS),
const tap_dance_pair_t p_esc_caps PROGMEM = {KC_ESC, KC_CAPS};
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[TD_ESC_CAPS] = ACTION_TAP_DANCE_DOUBLE(p_esc_caps),
[CT_EGG] = ACTION_TAP_DANCE_FN(dance_egg),
[CT_FLSH] = ACTION_TAP_DANCE_FN_ADVANCED(dance_flsh_each, dance_flsh_finished, dance_flsh_reset),
[CT_CLN] = ACTION_TAP_DANCE_TAP_HOLD(KC_COLN, KC_SCLN),
[CT_CLN] = ACTION_TAP_DANCE_TAP_HOLD(d_ct_cln),
[X_CTL] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, x_finished, x_reset),
[TD_RELEASE] = ACTION_TAP_DANCE_FN_ADVANCED_WITH_RELEASE(release_press, release_unpress, release_finished, release_reset),
[TD_RELEASE_AND_FINISH] = ACTION_TAP_DANCE_FN_ADVANCED_WITH_RELEASE(release_press, release_unpress_mark_finished, release_finished, release_reset),

View File

@ -90,8 +90,13 @@ static void lt_app_reset(tap_dance_state_t *state, void *user_data) {
}
}
tap_dance_action_t tap_dance_actions[] = {
[TD_L_MOVE] = ACTION_TAP_DANCE_LAYER_MOVE(KC_APP, 1),
[TD_L_TOGG] = ACTION_TAP_DANCE_LAYER_TOGGLE(KC_APP, 1),
const tap_dance_dual_role_t dual_roles[] PROGMEM = {
[DR_L_MOVE] = DUAL_ROLE_TAP_DANCE_LAYER_MOVE(KC_APP, 1),
[DR_L_TOGG] = DUAL_ROLE_TAP_DANCE_LAYER_TOGGLE(KC_APP, 1),
};
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[TD_L_MOVE] = ACTION_TAP_DANCE_DUAL_ROLE(dual_roles[DR_L_MOVE]),
[TD_L_TOGG] = ACTION_TAP_DANCE_DUAL_ROLE(dual_roles[DR_L_TOGG]),
[TD_LT_APP] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, lt_app_finished, lt_app_reset),
};

View File

@ -18,9 +18,14 @@ enum custom_keycodes {
SLOW_CD,
};
enum tap_dance_dual_roles {
DR_L_MOVE, // move to layer one
DR_L_TOGG, // toggle layer one
};
enum tap_dance_ids {
TD_L_MOVE, // ACTION_TAP_DANCE_LAYER_MOVE(KC_APP, 1)
TD_L_TOGG, // ACTION_TAP_DANCE_LAYER_TOGGLE(KC_APP, 1)
TD_L_MOVE, // move to layer one
TD_L_TOGG, // toggle layer one
TD_LT_APP, // similar to LT(1, KC_APP) with KC_RCTL on tap+hold or double tap
};