Created
December 20, 2019 14:25
-
-
Save weilbith/2a69227dfc88723b2d4cc5c8143028df to your computer and use it in GitHub Desktop.
QMK keyboard firmware - simulate MT with tap dance
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include QMK_KEYBOARD_H | |
#include "tap_dance_simulations.h" | |
typedef enum { | |
SINGLE_TAP, | |
SINGLE_HOLD, | |
MULTI_TAP, | |
// TODO: Think about tap-hold case | |
} td_state_t; | |
static td_state_t td_state; | |
int cur_dance_state (qk_tap_dance_state_t *state); | |
int cur_dance_state (qk_tap_dance_state_t *state) { | |
if (state->count == 1) { | |
if (state->interrupted || !state->pressed) { return SINGLE_TAP; } | |
else { return SINGLE_HOLD; } | |
} else { | |
return MULTI_TAP; | |
} | |
}; | |
/* | |
* Clone the MT() functionality via simulation by tap dance. | |
* The advantage is that the PERMISSIVE_HOLD option does not apply to it. | |
* It is not possible to use MT() with and without permissive hold. Therefore, | |
* the basic MT() usage takes advantage of it, while all occurrences with tap | |
* dance will ignore it. | |
*/ | |
void tap_dance_mt_on_each_tap(qk_tap_dance_state_t *state, void *user_data) { | |
if (state->count >= 2) { | |
state->finished = true; | |
} | |
} | |
void tap_dance_mt_finished (qk_tap_dance_state_t *state, void *user_data) { | |
td_state = cur_dance_state(state); | |
tap_dance_mt_config_t *config = (tap_dance_mt_config_t *)user_data; | |
switch(td_state) { | |
case SINGLE_TAP: | |
register_code16(config->keycode); | |
break; | |
case SINGLE_HOLD: | |
register_mods(MOD_BIT(config->modifier)); | |
break; | |
case MULTI_TAP: | |
for (int i = 0; i < state->count; i = i+1) { | |
tap_code16(config->keycode); | |
} | |
break; | |
} | |
} | |
void tap_dance_mt_reset (qk_tap_dance_state_t *state, void *user_data) { | |
tap_dance_mt_config_t *config = (tap_dance_mt_config_t *)user_data; | |
switch(td_state) { | |
case SINGLE_TAP: | |
unregister_code16(config->keycode); | |
break; | |
case SINGLE_HOLD: | |
unregister_mods(MOD_BIT(config->modifier)); | |
break; | |
case MULTI_TAP: | |
break; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include "process_tap_dance.h" | |
typedef struct { | |
uint16_t keycode; | |
uint16_t modifier; | |
} tap_dance_mt_config_t; | |
# define ACTION_TAP_DANCE_MT(keycode, modifier) \ | |
{ .fn = {tap_dance_mt_on_each_tap, tap_dance_mt_finished, tap_dance_mt_reset}, .user_data = (void *)&((tap_dance_mt_config_t){keycode, modifier}), } | |
void tap_dance_mt_on_each_tap (qk_tap_dance_state_t *state, void *user_data); | |
void tap_dance_mt_finished (qk_tap_dance_state_t *state, void *user_data); | |
void tap_dance_mt_reset (qk_tap_dance_state_t *state, void *user_data); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment