Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
QMK keyboard firmware - simulate MT with tap dance
#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;
}
}
#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