This commit is contained in:
Stephen Ostermiller 2025-07-15 18:16:12 +04:00 committed by GitHub
commit 21ac0d0290
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
48 changed files with 1889 additions and 278 deletions

View File

@ -0,0 +1,3 @@
# Tap dance state removed from `tap_dance_action_t`
Code that accessed the tap dance state as a field in the tap dance action should now call `tap_dance_get_state(int tap_dance_idx)` instead. That function may return `NULL` if many tap dance keys are held together. Add a `NULL` check before using the returned state.

View File

@ -0,0 +1,82 @@
# 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 from
```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. Change from
```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`
Change from
```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),
};
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[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

@ -0,0 +1,279 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="257.37842mm"
height="203.21901mm"
viewBox="0 0 257.37842 203.21901"
version="1.1"
id="svg5"
sodipodi:docname="tap-dance-doube-hold-interrupted.svg"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview10375"
pagecolor="#ffffff"
bordercolor="#111111"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.8884048"
inkscape:cx="505.18829"
inkscape:cy="379.68554"
inkscape:current-layer="svg5" />
<defs
id="defs2">
<rect
x="-469.16562"
y="-171.31531"
width="1119.4651"
height="787.95514"
id="rect13983" />
<marker
style="overflow:visible"
id="Arrow1L"
refX="0"
refY="0"
orient="auto-start-reverse"
markerWidth="8.75"
markerHeight="5"
viewBox="0 0 8.75 5"
preserveAspectRatio="xMidYMid">
<path
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
id="arrow1L"
transform="scale(-0.5)" />
</marker>
</defs>
<g
id="layer1"
transform="translate(20.27222,-104.88129)">
<path
style="fill:none;stroke:#000000;stroke-width:1.165;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1L)"
d="m 12.896004,136.56477 c 1.573387,-0.27013 174.985566,0.43796 174.985566,0.43796"
id="path344" />
<g
id="g3305"
transform="translate(0.73059446)">
<path
style="fill:#00a391;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 14.389388,137.10256 3.308959,5.51131 3.247063,-5.53223 z"
id="path2611" />
<path
style="fill:#00a391;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 25.508952,135.91803 -3.156917,-5.50799 -3.24706,5.53223 z"
id="path2611-3" />
</g>
<path
style="fill:#00a391;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 50.179315,137.10256 3.308959,5.51131 3.247063,-5.53223 z"
id="path2611-35" />
<path
style="fill:#00a391;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 160.33169,136.24301 -3.15691,-5.50799 -3.24706,5.53223 z"
id="path2611-3-6" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;stroke-width:0.264583"
x="190.14647"
y="134.80312"
id="text3393"><tspan
id="tspan3391"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;stroke-width:0.264583"
x="190.14647"
y="134.80312">Time</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;stroke-width:0.264583"
x="-14.746731"
y="130.41003"
id="text3447"><tspan
id="tspan3445"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;stroke-width:0.264583"
x="-14.746731"
y="130.41003" /></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;stroke-width:0.264583"
x="-11.466892"
y="132.08221"
id="text3451"><tspan
id="tspan3449"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;stroke-width:0.264583"
x="-11.466892"
y="132.08221">Key up</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:0.95;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="19.694458"
y="113.79429"
id="text3451-0"><tspan
id="tspan3449-63"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="19.694458"
y="113.79429">First</tspan><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="19.694458"
y="120.49707"
id="tspan3534">press</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:0.95;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="54.216129"
y="113.79429"
id="text3451-0-1"><tspan
id="tspan3449-63-5"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="54.216129"
y="113.79429">2nd</tspan><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="54.216129"
y="120.49707"
id="tspan3534-5">press</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:0.95;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="137.03003"
y="110.27879"
id="text3451-0-1-5"><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="137.03003"
y="110.27879"
id="tspan3534-5-7">End of</tspan><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="137.03003"
y="116.98158"
id="tspan3758">Tapping</tspan><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="137.03003"
y="123.68436"
id="tspan3760">Term</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;stroke-width:0.264583"
x="-20.95661"
y="144.95244"
id="text3451-3"><tspan
id="tspan3449-6"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;stroke-width:0.264583"
x="-20.95661"
y="144.95244">Key down</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:FreeMono;-inkscape-font-specification:FreeMono;font-variant-ligatures:none;stroke-width:0.264583"
x="134.78493"
y="55.269905"
id="text3451-4"
transform="rotate(61.3)"><tspan
id="tspan3449-7"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FreeMono;-inkscape-font-specification:FreeMono;stroke-width:0.264583"
x="134.78493"
y="55.269905">on_each_tap(count:1, pressed:true)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:FreeMono;-inkscape-font-specification:FreeMono;font-variant-ligatures:none;stroke-width:0.264583"
x="138.60913"
y="48.284851"
id="text3451-4-9"
transform="rotate(61.3)"><tspan
id="tspan3449-7-3"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FreeMono;-inkscape-font-specification:FreeMono;stroke-width:0.264583"
x="138.60913"
y="48.284851">on_each_release(count:1, pressed:false)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:FreeMono;-inkscape-font-specification:FreeMono;font-variant-ligatures:none;stroke-width:0.264583"
x="151.62125"
y="24.517748"
id="text3451-4-7"
transform="rotate(61.3)"><tspan
id="tspan3449-7-4"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FreeMono;-inkscape-font-specification:FreeMono;stroke-width:0.264583"
x="151.62125"
y="24.517748">on_each_tap(count:2, pressed:true)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:FreeMono;-inkscape-font-specification:FreeMono;font-variant-ligatures:none;stroke-width:0.264583"
x="200.44789"
y="-67.038536"
id="text3451-4-9-5"
transform="rotate(61.3)"><tspan
id="tspan3449-7-3-2"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FreeMono;-inkscape-font-specification:FreeMono;stroke-width:0.264583"
x="200.44789"
y="-67.038536">on_each_release(count:2, pressed:false)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:FreeMono;-inkscape-font-specification:FreeMono;font-variant-ligatures:none;stroke-width:0.264583"
x="203.71626"
y="-73.008339"
id="text3451-4-9-5-4-0"
transform="rotate(61.3)"><tspan
id="tspan3449-7-3-2-4-7"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FreeMono;-inkscape-font-specification:FreeMono;stroke-width:0.264583"
x="203.71626"
y="-73.008339">on_reset(count:2, pressed:false)</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:1.965;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 136.8083,127.93103 -0.0323,8.87583"
id="path3722" />
</g>
<path
style="fill:#ff7f2a;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 110.9994,32.409163 3.30895,5.51131 3.24707,-5.53223 z"
id="path2611-35-8"
sodipodi:nodetypes="cccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:0.95;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="113.14949"
y="8.1985655"
id="text3451-0-1-3"><tspan
sodipodi:role="line"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="113.14949"
y="8.1985655"
id="tspan6210">Other key</tspan><tspan
sodipodi:role="line"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="113.14949"
y="14.901347"
id="tspan6214">interrupting</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:FreeMono;-inkscape-font-specification:FreeMono;font-variant-ligatures:none;stroke-width:0.264583"
x="90.397614"
y="-79.312668"
id="text3451-4-9-5-4-9"
transform="rotate(61.3)"><tspan
sodipodi:role="line"
id="tspan3449-7-3-2-4-2"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FreeMono;-inkscape-font-specification:FreeMono;stroke-width:0.264583"
x="90.397614"
y="-79.312668">on_dance_finished(count:2, interrupted:true)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:FreeMono;-inkscape-font-specification:FreeMono;font-variant-ligatures:none;stroke-width:0.264583"
x="94.660332"
y="-87.032799"
id="text3451-4-9-5-4-9-3"
transform="rotate(61.3)"><tspan
sodipodi:role="line"
id="tspan3449-7-3-2-4-2-6"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FreeMono;-inkscape-font-specification:FreeMono;stroke-width:0.264583"
x="94.660332"
y="-87.032799">Interrupting key event processing</tspan></text>
<text
xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,113.12479,40.18937)"
id="text13981"
style="font-size:26.6667px;line-height:1.25;font-family:Impact;-inkscape-font-specification:'Impact, Normal';font-variant-ligatures:none;white-space:pre;shape-inside:url(#rect13983)" />
</svg>

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,215 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="257.37842mm"
height="187.04857mm"
viewBox="0 0 257.37842 187.04857"
version="1.1"
id="svg5"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs2">
<marker
style="overflow:visible"
id="Arrow1L"
refX="0"
refY="0"
orient="auto-start-reverse"
markerWidth="8.75"
markerHeight="5"
viewBox="0 0 8.75 5"
preserveAspectRatio="xMidYMid">
<path
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
id="arrow1L"
transform="scale(-0.5)" />
</marker>
</defs>
<g
id="layer1"
transform="translate(20.27222,-104.88129)">
<path
style="fill:none;stroke:#000000;stroke-width:1.165;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1L)"
d="m 12.896004,136.56477 c 1.573387,-0.27013 174.985566,0.43796 174.985566,0.43796"
id="path344" />
<g
id="g3305"
transform="translate(0.73059446)">
<path
style="fill:#00a391;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 14.389388,137.10256 3.308959,5.51131 3.247063,-5.53223 z"
id="path2611" />
<path
style="fill:#00a391;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 25.508952,135.91803 -3.156917,-5.50799 -3.24706,5.53223 z"
id="path2611-3" />
</g>
<path
style="fill:#00a391;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 50.179315,137.10256 3.308959,5.51131 3.247063,-5.53223 z"
id="path2611-35" />
<path
style="fill:#00a391;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 160.33169,136.24301 -3.15691,-5.50799 -3.24706,5.53223 z"
id="path2611-3-6" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;stroke-width:0.264583"
x="190.14647"
y="134.80312"
id="text3393"><tspan
id="tspan3391"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;stroke-width:0.264583"
x="190.14647"
y="134.80312">Time</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;stroke-width:0.264583"
x="-14.746731"
y="130.41003"
id="text3447"><tspan
id="tspan3445"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;stroke-width:0.264583"
x="-14.746731"
y="130.41003" /></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;stroke-width:0.264583"
x="-11.466892"
y="132.08221"
id="text3451"><tspan
id="tspan3449"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;stroke-width:0.264583"
x="-11.466892"
y="132.08221">Key up</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:0.95;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="19.694458"
y="113.79429"
id="text3451-0"><tspan
id="tspan3449-63"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="19.694458"
y="113.79429">First</tspan><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="19.694458"
y="120.49707"
id="tspan3534">press</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:0.95;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="54.216129"
y="113.79429"
id="text3451-0-1"><tspan
id="tspan3449-63-5"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="54.216129"
y="113.79429">2nd</tspan><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="54.216129"
y="120.49707"
id="tspan3534-5">press</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:0.95;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="137.03003"
y="110.27879"
id="text3451-0-1-5"><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="137.03003"
y="110.27879"
id="tspan3534-5-7">End of</tspan><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="137.03003"
y="116.98158"
id="tspan3758">Tapping</tspan><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="137.03003"
y="123.68436"
id="tspan3760">Term</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;stroke-width:0.264583"
x="-20.95661"
y="144.95244"
id="text3451-3"><tspan
id="tspan3449-6"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;stroke-width:0.264583"
x="-20.95661"
y="144.95244">Key down</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:FreeMono;-inkscape-font-specification:FreeMono;font-variant-ligatures:none;stroke-width:0.264583"
x="134.78493"
y="55.269905"
id="text3451-4"
transform="rotate(61.3)"><tspan
id="tspan3449-7"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FreeMono;-inkscape-font-specification:FreeMono;stroke-width:0.264583"
x="134.78493"
y="55.269905">on_each_tap(count:1, pressed:true)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:FreeMono;-inkscape-font-specification:FreeMono;font-variant-ligatures:none;stroke-width:0.264583"
x="138.60913"
y="48.284851"
id="text3451-4-9"
transform="rotate(61.3)"><tspan
id="tspan3449-7-3"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FreeMono;-inkscape-font-specification:FreeMono;stroke-width:0.264583"
x="138.60913"
y="48.284851">on_each_release(count:1, pressed:false)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:FreeMono;-inkscape-font-specification:FreeMono;font-variant-ligatures:none;stroke-width:0.264583"
x="151.62125"
y="24.517748"
id="text3451-4-7"
transform="rotate(61.3)"><tspan
id="tspan3449-7-4"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FreeMono;-inkscape-font-specification:FreeMono;stroke-width:0.264583"
x="151.62125"
y="24.517748">on_each_tap(count:2, pressed:true)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:FreeMono;-inkscape-font-specification:FreeMono;font-variant-ligatures:none;stroke-width:0.264583"
x="200.44789"
y="-67.038536"
id="text3451-4-9-5"
transform="rotate(61.3)"><tspan
id="tspan3449-7-3-2"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FreeMono;-inkscape-font-specification:FreeMono;stroke-width:0.264583"
x="200.44789"
y="-67.038536">on_each_release(count:2, pressed:false)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:FreeMono;-inkscape-font-specification:FreeMono;font-variant-ligatures:none;stroke-width:0.264583"
x="192.12431"
y="-49.462635"
id="text3451-4-9-5-4"
transform="rotate(61.3)"><tspan
id="tspan3449-7-3-2-4"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FreeMono;-inkscape-font-specification:FreeMono;stroke-width:0.264583"
x="192.12431"
y="-49.462635">on_dance_finished(count:2, pressed:true)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:FreeMono;-inkscape-font-specification:FreeMono;font-variant-ligatures:none;stroke-width:0.264583"
x="203.71626"
y="-73.008339"
id="text3451-4-9-5-4-0"
transform="rotate(61.3)"><tspan
id="tspan3449-7-3-2-4-7"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FreeMono;-inkscape-font-specification:FreeMono;stroke-width:0.264583"
x="203.71626"
y="-73.008339">on_reset(count:2, pressed:false)</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:1.965;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 136.8083,127.93103 -0.0323,8.87583"
id="path3722" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,298 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="226.37836mm"
height="202.94032mm"
viewBox="0 0 226.37835 202.94033"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="tap-dance-doube-tap-interrupted.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#111111"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.6819304"
inkscape:cx="387.05526"
inkscape:cy="465.5365"
inkscape:current-layer="layer1" />
<defs
id="defs2">
<marker
style="overflow:visible"
id="Arrow1L"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow1L"
markerWidth="8.75"
markerHeight="5"
viewBox="0 0 8.75 5"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
id="arrow1L"
transform="scale(-0.5)" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(20.27222,-104.88129)">
<path
style="fill:none;stroke:#000000;stroke-width:1.165;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1L)"
d="m 12.896004,136.56477 c 1.573387,-0.27013 174.985566,0.43796 174.985566,0.43796"
id="path344" />
<g
id="g3305"
transform="translate(0.73059446)">
<path
style="fill:#00a391;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 14.389388,137.10256 3.308959,5.51131 3.247063,-5.53223 z"
id="path2611"
sodipodi:nodetypes="cccc" />
<path
style="fill:#00a391;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 25.508952,135.91803 -3.156917,-5.50799 -3.24706,5.53223 z"
id="path2611-3"
sodipodi:nodetypes="cccc" />
</g>
<g
id="g3305-5"
transform="translate(35.789927)">
<path
style="fill:#00a391;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 14.389388,137.10256 3.308959,5.51131 3.247063,-5.53223 z"
id="path2611-35"
sodipodi:nodetypes="cccc" />
<path
style="fill:#00a391;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 25.508952,135.91803 -3.156917,-5.50799 -3.24706,5.53223 z"
id="path2611-3-6"
sodipodi:nodetypes="cccc" />
</g>
<path
style="fill:#ff7f2a;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 89.614624,137.01176 3.308959,5.51131 3.247063,-5.53223 z"
id="path2611-35-8"
sodipodi:nodetypes="cccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;stroke-width:0.264583"
x="190.14647"
y="134.80312"
id="text3393"><tspan
sodipodi:role="line"
id="tspan3391"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;stroke-width:0.264583"
x="190.14647"
y="134.80312">Time</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;stroke-width:0.264583"
x="-14.746731"
y="130.41003"
id="text3447"><tspan
sodipodi:role="line"
id="tspan3445"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;stroke-width:0.264583"
x="-14.746731"
y="130.41003" /></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;stroke-width:0.264583"
x="-11.466892"
y="132.08221"
id="text3451"><tspan
sodipodi:role="line"
id="tspan3449"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;stroke-width:0.264583"
x="-11.466892"
y="132.08221">Key up</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:0.95;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="19.694458"
y="113.79429"
id="text3451-0"><tspan
sodipodi:role="line"
id="tspan3449-63"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="19.694458"
y="113.79429">First</tspan><tspan
sodipodi:role="line"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="19.694458"
y="120.49707"
id="tspan3534">press</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:0.95;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="54.216129"
y="113.79429"
id="text3451-0-1"><tspan
sodipodi:role="line"
id="tspan3449-63-5"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="54.216129"
y="113.79429">2nd</tspan><tspan
sodipodi:role="line"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="54.216129"
y="120.49707"
id="tspan3534-5">press</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:0.95;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="91.764717"
y="112.80116"
id="text3451-0-1-3"><tspan
sodipodi:role="line"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="91.764717"
y="112.80116"
id="tspan6210">Other key</tspan><tspan
sodipodi:role="line"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="91.764717"
y="119.50394"
id="tspan6214">interrupting</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:0.95;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="137.03003"
y="110.27879"
id="text3451-0-1-5"><tspan
sodipodi:role="line"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="137.03003"
y="110.27879"
id="tspan3534-5-7">End of</tspan><tspan
sodipodi:role="line"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="137.03003"
y="116.98158"
id="tspan3758">Tapping</tspan><tspan
sodipodi:role="line"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="137.03003"
y="123.68436"
id="tspan3760">Term</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;stroke-width:0.264583"
x="-20.95661"
y="144.95244"
id="text3451-3"><tspan
sodipodi:role="line"
id="tspan3449-6"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;stroke-width:0.264583"
x="-20.95661"
y="144.95244">Key down</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:FreeMono;-inkscape-font-specification:FreeMono;font-variant-ligatures:none;stroke-width:0.264583"
x="134.78493"
y="55.269905"
id="text3451-4"
transform="rotate(61.3)"><tspan
sodipodi:role="line"
id="tspan3449-7"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FreeMono;-inkscape-font-specification:FreeMono;stroke-width:0.264583"
x="134.78493"
y="55.269905">on_each_tap(count:1, pressed:true)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:FreeMono;-inkscape-font-specification:FreeMono;font-variant-ligatures:none;stroke-width:0.264583"
x="138.60913"
y="48.284851"
id="text3451-4-9"
transform="rotate(61.3)"><tspan
sodipodi:role="line"
id="tspan3449-7-3"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FreeMono;-inkscape-font-specification:FreeMono;stroke-width:0.264583"
x="138.60913"
y="48.284851">on_each_release(count:1, pressed:false)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:FreeMono;-inkscape-font-specification:FreeMono;font-variant-ligatures:none;stroke-width:0.264583"
x="151.62125"
y="24.517748"
id="text3451-4-7"
transform="rotate(61.3)"><tspan
sodipodi:role="line"
id="tspan3449-7-4"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FreeMono;-inkscape-font-specification:FreeMono;stroke-width:0.264583"
x="151.62125"
y="24.517748">on_each_tap(count:2, pressed:true)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:FreeMono;-inkscape-font-specification:FreeMono;font-variant-ligatures:none;stroke-width:0.264583"
x="155.74803"
y="17.118372"
id="text3451-4-9-5"
transform="rotate(61.3)"><tspan
sodipodi:role="line"
id="tspan3449-7-3-2"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FreeMono;-inkscape-font-specification:FreeMono;stroke-width:0.264583"
x="155.74803"
y="17.118372">on_each_release(count:2, pressed:false)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:FreeMono;-inkscape-font-specification:FreeMono;font-variant-ligatures:none;stroke-width:0.264583"
x="171.87991"
y="-10.322473"
id="text3451-4-9-5-4"
transform="rotate(61.3)"><tspan
sodipodi:role="line"
id="tspan3449-7-3-2-4"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FreeMono;-inkscape-font-specification:FreeMono;stroke-width:0.264583"
x="171.87991"
y="-10.322473">on_dance_finished(count:2, interrupted:true)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:FreeMono;-inkscape-font-specification:FreeMono;font-variant-ligatures:none;stroke-width:0.264583"
x="176.01163"
y="-17.869198"
id="text3451-4-9-5-4-0"
transform="rotate(61.3)"><tspan
sodipodi:role="line"
id="tspan3449-7-3-2-4-7"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FreeMono;-inkscape-font-specification:FreeMono;stroke-width:0.264583"
x="176.01163"
y="-17.869198">on_reset(count:2, pressed:false)</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:1.965;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 136.8083,127.93103 -0.0323,8.87583"
id="path3722"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:FreeMono;-inkscape-font-specification:FreeMono;font-variant-ligatures:none;stroke-width:0.264583"
x="181.4807"
y="-26.056341"
id="text3451-4-9-5-4-9-3"
transform="rotate(61.3)"><tspan
sodipodi:role="line"
id="tspan3449-7-3-2-4-2-6"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FreeMono;-inkscape-font-specification:FreeMono;stroke-width:0.264583"
x="181.4807"
y="-26.056341">Interrupting key event processing</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -0,0 +1,219 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="242.0305mm"
height="190.76183mm"
viewBox="0 0 242.0305 190.76183"
version="1.1"
id="svg5"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs2">
<marker
style="overflow:visible"
id="Arrow1L"
refX="0"
refY="0"
orient="auto-start-reverse"
markerWidth="8.75"
markerHeight="5"
viewBox="0 0 8.75 5"
preserveAspectRatio="xMidYMid">
<path
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
id="arrow1L"
transform="scale(-0.5)" />
</marker>
</defs>
<g
id="layer1"
transform="translate(20.27222,-104.88129)">
<path
style="fill:none;stroke:#000000;stroke-width:1.165;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1L)"
d="m 12.896004,136.56477 c 1.573387,-0.27013 174.985566,0.43796 174.985566,0.43796"
id="path344" />
<g
id="g3305"
transform="translate(0.73059446)">
<path
style="fill:#00a391;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 14.389388,137.10256 3.308959,5.51131 3.247063,-5.53223 z"
id="path2611" />
<path
style="fill:#00a391;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 25.508952,135.91803 -3.156917,-5.50799 -3.24706,5.53223 z"
id="path2611-3" />
</g>
<g
id="g3305-5"
transform="translate(35.789927)">
<path
style="fill:#00a391;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 14.389388,137.10256 3.308959,5.51131 3.247063,-5.53223 z"
id="path2611-35" />
<path
style="fill:#00a391;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 25.508952,135.91803 -3.156917,-5.50799 -3.24706,5.53223 z"
id="path2611-3-6" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;stroke-width:0.264583"
x="190.14647"
y="134.80312"
id="text3393"><tspan
id="tspan3391"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;stroke-width:0.264583"
x="190.14647"
y="134.80312">Time</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;stroke-width:0.264583"
x="-14.746731"
y="130.41003"
id="text3447"><tspan
id="tspan3445"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;stroke-width:0.264583"
x="-14.746731"
y="130.41003" /></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;stroke-width:0.264583"
x="-11.466892"
y="132.08221"
id="text3451"><tspan
id="tspan3449"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;stroke-width:0.264583"
x="-11.466892"
y="132.08221">Key up</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:0.95;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="19.694458"
y="113.79429"
id="text3451-0"><tspan
id="tspan3449-63"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="19.694458"
y="113.79429">First</tspan><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="19.694458"
y="120.49707"
id="tspan3534">press</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:0.95;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="54.216129"
y="113.79429"
id="text3451-0-1"><tspan
id="tspan3449-63-5"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="54.216129"
y="113.79429">2nd</tspan><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="54.216129"
y="120.49707"
id="tspan3534-5">press</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:0.95;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="137.03003"
y="110.27879"
id="text3451-0-1-5"><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="137.03003"
y="110.27879"
id="tspan3534-5-7">End of</tspan><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="137.03003"
y="116.98158"
id="tspan3758">Tapping</tspan><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:0.264583"
x="137.03003"
y="123.68436"
id="tspan3760">Term</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;font-variant-ligatures:none;stroke-width:0.264583"
x="-20.95661"
y="144.95244"
id="text3451-3"><tspan
id="tspan3449-6"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:sans-serif;stroke-width:0.264583"
x="-20.95661"
y="144.95244">Key down</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:FreeMono;-inkscape-font-specification:FreeMono;font-variant-ligatures:none;stroke-width:0.264583"
x="134.78493"
y="55.269905"
id="text3451-4"
transform="rotate(61.3)"><tspan
id="tspan3449-7"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FreeMono;-inkscape-font-specification:FreeMono;stroke-width:0.264583"
x="134.78493"
y="55.269905">on_each_tap(count:1, pressed:true)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:FreeMono;-inkscape-font-specification:FreeMono;font-variant-ligatures:none;stroke-width:0.264583"
x="138.60913"
y="48.284851"
id="text3451-4-9"
transform="rotate(61.3)"><tspan
id="tspan3449-7-3"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FreeMono;-inkscape-font-specification:FreeMono;stroke-width:0.264583"
x="138.60913"
y="48.284851">on_each_release(count:1, pressed:false)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:FreeMono;-inkscape-font-specification:FreeMono;font-variant-ligatures:none;stroke-width:0.264583"
x="151.62125"
y="24.517748"
id="text3451-4-7"
transform="rotate(61.3)"><tspan
id="tspan3449-7-4"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FreeMono;-inkscape-font-specification:FreeMono;stroke-width:0.264583"
x="151.62125"
y="24.517748">on_each_tap(count:2, pressed:true)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:FreeMono;-inkscape-font-specification:FreeMono;font-variant-ligatures:none;stroke-width:0.264583"
x="155.43564"
y="17.550631"
id="text3451-4-9-5"
transform="rotate(61.3)"><tspan
id="tspan3449-7-3-2"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FreeMono;-inkscape-font-specification:FreeMono;stroke-width:0.264583"
x="155.43564"
y="17.550631">on_each_release(count:2, pressed:false)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:FreeMono;-inkscape-font-specification:FreeMono;font-variant-ligatures:none;stroke-width:0.264583"
x="192.12431"
y="-49.462635"
id="text3451-4-9-5-4"
transform="rotate(61.3)"><tspan
id="tspan3449-7-3-2-4"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FreeMono;-inkscape-font-specification:FreeMono;stroke-width:0.264583"
x="192.12431"
y="-49.462635">on_dance_finished(count:2, pressed:false)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;line-height:1.25;font-family:FreeMono;-inkscape-font-specification:FreeMono;font-variant-ligatures:none;stroke-width:0.264583"
x="196.15424"
y="-56.823414"
id="text3451-4-9-5-4-0"
transform="rotate(61.3)"><tspan
id="tspan3449-7-3-2-4-7"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FreeMono;-inkscape-font-specification:FreeMono;stroke-width:0.264583"
x="196.15424"
y="-56.823414">on_reset(count:2, pressed:false)</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:1.965;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 136.8083,127.93103 -0.0323,8.87583"
id="path3722" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -15,22 +15,26 @@ Optionally, you might want to set a custom `TAPPING_TERM` time by adding somethi
```c
#define TAPPING_TERM 175
#define TAPPING_TERM_PER_KEY
#define TAP_DANCE_MAX_SIMULTANEOUS 3
```
The `TAPPING_TERM` time is the maximum time allowed between taps of your Tap Dance key, and is measured in milliseconds. For example, if you used the above `#define` statement and set up a Tap Dance key that sends `Space` on single-tap and `Enter` on double-tap, then this key will send `ENT` only if you tap this key twice in less than 175ms. If you tap the key, wait more than 175ms, and tap the key again you'll end up sending `SPC SPC` instead. The `TAPPING_TERM_PER_KEY` definition is only needed if you control the tapping term through a [custom `get_tapping_term` function](../tap_hold#tapping_term), which may be needed because `TAPPING_TERM` affects not just tap-dance keys.
`TAP_DANCE_MAX_SIMULTANEOUS` controls how many tap dance keys can be held at the same time and register keycodes. Increasing this value will use more RAM because each active tap dance needs a significant amount of state in active memory.
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 keys that do something different when double tapped.
::: warning
Keep in mind that only [basic keycodes](../keycodes_basic) are supported here. Custom keycodes are not supported.
@ -40,12 +44,50 @@ Similar to the first option, the second and third option are good for simple lay
For more complicated cases, like blink the LEDs, fiddle with the backlighting, and so on, use the fourth or fifth option. Examples of each are listed below.
## Custom tap dances {#custom}
There are four callback functions that can be used when implementing custom tap dances:
- `on_each_tap(tap_dance_state_t *state, void *user_data)`;
- `on_dance_finished(tap_dance_state_t *state, void *user_data)`;
- `on_reset(tap_dance_state_t *state, void *user_data)`;
- `on_each_release(tap_dance_state_t *state, void *user_data)`;
Here are some illustrations of when those functions are called during tap dances:
### Double tap
![](tap-dance-doube-tap.svg)
### Interrupted double tap
![](tap-dance-doube-tap-interrupted.svg)
### Double hold
![](tap-dance-doube-hold.svg)
### Interrupted double hold
![](tap-dance-doube-hold-interrupted.svg)
### Skipping the finished callback
It is possible to end a tap dance immediately, skipping `on_dance_finished()`, but not `on_dance_reset_fn`, by calling `reset_tap_dance(state)`. Use this if your tap dance code has completely handled the tap dance in an earlier callback and the logic in the finished callback should not get executed.
### Configuration data
Your custom tap dance functions can accept `user_data` with configuration. This may consist of key codes, method pointers, or boolean flags used by your custom logic. So that it doesn't constantly take up RAM, it should be marked as PROGMEM. `memcpy_P()` should be used to read the `user_data` pointer into working memory in each of your callbacks. See [example 3](#example-3) below.
### Mutable state
Your custom tap dance may need to store data about the state of the current dance. Because `user_data` should be kept in immutable flash memory, it is not appropriate to use it for mutable state. Instead, define a static array of your state of size `TAP_DANCE_MAX_SIMULTANEOUS`. From the callback functions, use `state->state_idx` to get the index into this array which should be used. See [example 3](#example-3) below.
## Implementation Details {#implementation}
Well, that's the bulk of it! You should now be able to work through the examples below, and to develop your own Tap Dance functionality. But if you want a deeper understanding of what's going on behind the scenes, then read on for the explanation of how it all works!
Let's go over the three functions mentioned in `ACTION_TAP_DANCE_FN_ADVANCED` in a little more detail. They all receive the same two arguments: a pointer to a structure that holds all dance related state information, and a pointer to a use case specific state variable. The three functions differ in when they are called. The first, `on_each_tap_fn()`, is called every time the tap dance key is *pressed*. Before it is called, the counter is incremented and the timer is reset. The second function, `on_dance_finished_fn()`, is called when the tap dance is interrupted or ends because `TAPPING_TERM` milliseconds have passed since the last tap. When the `finished` field of the dance state structure is set to `true`, the `on_dance_finished_fn()` is skipped. After `on_dance_finished_fn()` was called or would have been called, but no sooner than when the tap dance key is *released*, `on_dance_reset_fn()` is called. It is possible to end a tap dance immediately, skipping `on_dance_finished_fn()`, but not `on_dance_reset_fn`, by calling `reset_tap_dance(state)`.
To accomplish this logic, the tap dance mechanics use three entry points. The main entry point is `process_tap_dance()`, called from `process_record_quantum()` *after* `process_record_kb()` and `process_record_user()`. This function is responsible for calling `on_each_tap_fn()` and `on_dance_reset_fn()`. In order to handle interruptions of a tap dance, another entry point, `preprocess_tap_dance()` is run right at the beginning of `process_record_quantum()`. This function checks whether the key pressed is a tap-dance key. If it is not, and a tap-dance was in action, we handle that first, and enqueue the newly pressed key. If it is a tap-dance key, then we check if it is the same as the already active one (if there's one active, that is). If it is not, we fire off the old one first, then register the new one. Finally, `tap_dance_task()` periodically checks whether `TAPPING_TERM` has passed since the last key press and finishes a tap dance if that is the case.
This means that you have `TAPPING_TERM` time to tap the key again; you do not have to input all the taps within a single `TAPPING_TERM` timeframe. This allows for longer tap counts, with minimal impact on responsiveness.
@ -60,15 +102,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
// Enumerate all tap dance pairs
enum {
P_ESC_CAPS,
};
// Tap dance pair definitions
const tap_dance_pair_t tap_dance_pairs[] PROGMEM = {
[P_ESC_CAPS] = {KC_ESC, KC_CAPS},
};
// Enumerate all tap dances
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 +157,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 +204,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 +219,34 @@ 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];
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) {
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
@ -179,43 +254,52 @@ 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),
enum {
TH_CT_CLN,
};
const tap_dance_tap_hold_t tap_dance_tap_holds[] PROGMEM = {
[TH_CT_CLN] = {KC_COLN, KC_SCLN},
};
const tap_dance_action_t tap_dance_actions[] PROGMEM = {
[CT_CLN] = ACTION_TAP_DANCE_TAP_HOLD(tap_dance_tap_holds[TH_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): // list all tap dance keycodes with tap-hold configurations
action = &tap_dance_actions[QK_TAP_DANCE_GET_INDEX(keycode)];
if (!record->event.pressed && action->state.count && !action->state.finished) {
tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)action->user_data;
tap_code16(tap_hold->tap);
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) {
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;
@ -354,7 +438,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)
};
```
@ -450,7 +534,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)
};
```
@ -544,7 +628,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), LSG(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

@ -24,59 +24,92 @@
#include "keymap_introspection.h"
static uint16_t active_td;
static tap_dance_state_t tap_dance_states[TAP_DANCE_MAX_SIMULTANEOUS];
static uint16_t last_tap_time;
tap_dance_state_t *tap_dance_get_state(uint8_t tap_dance_idx) {
uint8_t i;
if (tap_dance_idx >= tap_dance_count()) {
return NULL;
}
// 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].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].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];
}
}
// No states are available, tap dance won't happen
return NULL;
}
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);
}
}
@ -86,58 +119,64 @@ static inline void _process_tap_dance_action_fn(tap_dance_state_t *state, void *
}
}
static inline void process_tap_dance_action_on_each_tap(tap_dance_action_t *action) {
action->state.count++;
action->state.weak_mods = get_mods();
action->state.weak_mods |= get_weak_mods();
static inline void process_tap_dance_action_on_each_tap(tap_dance_action_t *action, tap_dance_state_t *state) {
state->count++;
state->weak_mods = get_mods();
state->weak_mods |= get_weak_mods();
#ifndef NO_ACTION_ONESHOT
action->state.oneshot_mods = get_oneshot_mods();
state->oneshot_mods = get_oneshot_mods();
#endif
_process_tap_dance_action_fn(&action->state, action->user_data, action->fn.on_each_tap);
_process_tap_dance_action_fn(state, action->user_data, action->fn.on_each_tap);
}
static inline void process_tap_dance_action_on_each_release(tap_dance_action_t *action) {
_process_tap_dance_action_fn(&action->state, action->user_data, action->fn.on_each_release);
static inline void process_tap_dance_action_on_each_release(tap_dance_action_t *action, tap_dance_state_t *state) {
_process_tap_dance_action_fn(state, action->user_data, action->fn.on_each_release);
}
static inline void process_tap_dance_action_on_reset(tap_dance_action_t *action) {
_process_tap_dance_action_fn(&action->state, action->user_data, action->fn.on_reset);
del_weak_mods(action->state.weak_mods);
static inline void process_tap_dance_action_on_reset(tap_dance_action_t *action, tap_dance_state_t *state) {
_process_tap_dance_action_fn(state, action->user_data, action->fn.on_reset);
del_weak_mods(state->weak_mods);
#ifndef NO_ACTION_ONESHOT
del_mods(action->state.oneshot_mods);
del_mods(state->oneshot_mods);
#endif
send_keyboard_report();
action->state = (const tap_dance_state_t){0};
// Clear the tap dance state and mark it as unused
memset(state, 0, sizeof(tap_dance_state_t));
}
static inline void process_tap_dance_action_on_dance_finished(tap_dance_action_t *action) {
if (!action->state.finished) {
action->state.finished = true;
add_weak_mods(action->state.weak_mods);
static inline void process_tap_dance_action_on_dance_finished(tap_dance_action_t *action, tap_dance_state_t *state) {
if (!state->finished) {
state->finished = true;
add_weak_mods(state->weak_mods);
#ifndef NO_ACTION_ONESHOT
add_mods(action->state.oneshot_mods);
add_mods(state->oneshot_mods);
#endif
send_keyboard_report();
_process_tap_dance_action_fn(&action->state, action->user_data, action->fn.on_dance_finished);
_process_tap_dance_action_fn(state, action->user_data, action->fn.on_dance_finished);
}
active_td = 0;
if (!action->state.pressed) {
if (!state->pressed) {
// There will not be a key release event, so reset now.
process_tap_dance_action_on_reset(action);
process_tap_dance_action_on_reset(action, state);
}
}
bool preprocess_tap_dance(uint16_t keycode, keyrecord_t *record) {
tap_dance_action_t *action;
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));
action->state.interrupted = true;
action->state.interrupting_keycode = keycode;
process_tap_dance_action_on_dance_finished(action);
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);
// 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.
@ -151,8 +190,9 @@ bool preprocess_tap_dance(uint16_t keycode, keyrecord_t *record) {
}
bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
int td_index;
tap_dance_action_t *action;
uint8_t td_index;
tap_dance_action_t action;
tap_dance_state_t *state;
switch (keycode) {
case QK_TAP_DANCE ... QK_TAP_DANCE_MAX:
@ -160,17 +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);
action->state.pressed = record->event.pressed;
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);
active_td = action->state.finished ? 0 : keycode;
process_tap_dance_action_on_each_tap(&action, state);
active_td = state->finished ? 0 : keycode;
} else {
process_tap_dance_action_on_each_release(action);
if (action->state.finished) {
process_tap_dance_action_on_reset(action);
process_tap_dance_action_on_each_release(&action, state);
if (state->finished) {
process_tap_dance_action_on_reset(&action, state);
if (active_td == keycode) {
active_td = 0;
}
@ -184,17 +227,19 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
}
void tap_dance_task(void) {
tap_dance_action_t *action;
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));
if (!action->state.interrupted) {
process_tap_dance_action_on_dance_finished(action);
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);
}
}
void reset_tap_dance(tap_dance_state_t *state) {
active_td = 0;
process_tap_dance_action_on_reset((tap_dance_action_t *)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;
@ -28,15 +32,17 @@ typedef struct {
#ifndef NO_ACTION_ONESHOT
uint8_t oneshot_mods;
#endif
bool pressed : 1;
bool finished : 1;
bool interrupted : 1;
bool pressed : 1;
bool finished : 1;
bool interrupted : 1;
bool in_use : 1;
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);
typedef struct tap_dance_action_t {
tap_dance_state_t state;
struct {
tap_dance_user_fn_t on_each_tap;
tap_dance_user_fn_t on_dance_finished;
@ -57,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, }
@ -80,6 +89,8 @@ typedef struct {
void reset_tap_dance(tap_dance_state_t *state);
tap_dance_state_t *tap_dance_get_state(uint8_t tap_dance_idx);
/* To be used internally */
bool preprocess_tap_dance(uint16_t keycode, keyrecord_t *record);

View File

@ -76,25 +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));
if (!record->event.pressed && action->state.count && !action->state.finished) {
tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)action->user_data;
tap_code16(tap_hold->tap);
state = tap_dance_get_state(QK_TAP_DANCE_GET_INDEX(keycode));
if (!record->event.pressed && state != NULL && state->count && !state->finished) {
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
@ -102,27 +111,34 @@ 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)}
enum {
TH_CT_CLN,
};
const tap_dance_tap_hold_t tap_dance_tap_holds[] PROGMEM = {
[TH_CT_CLN] = {KC_COLN, KC_SCLN},
};
// Example 4
@ -209,11 +225,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(tap_dance_tap_holds[TH_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
};