Add timestamps to position events and behaviors.
- Take original event timestamps into consideration so nested tap-holds have proper timing. - Add position and timestamp to keycode state changed event so the one-shot behavior can properly identify other keypresses and timings. - Add timestamp to position events received from peripheral
This commit is contained in:
parent
00479e913f
commit
5dd3ed4009
19 changed files with 151 additions and 56 deletions
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
|
||||
typedef int (*behavior_keymap_binding_callback_t)(struct device *dev, u32_t position, u32_t param1,
|
||||
u32_t param2);
|
||||
u32_t param2, s64_t timestamp);
|
||||
typedef int (*behavior_sensor_keymap_binding_callback_t)(struct device *dev, struct device *sensor,
|
||||
u32_t param1, u32_t param2);
|
||||
|
||||
|
@ -43,17 +43,18 @@ __subsystem struct behavior_driver_api {
|
|||
* @retval Negative errno code if failure.
|
||||
*/
|
||||
__syscall int behavior_keymap_binding_pressed(struct device *dev, u32_t position, u32_t param1,
|
||||
u32_t param2);
|
||||
u32_t param2, s64_t timestamp);
|
||||
|
||||
static inline int z_impl_behavior_keymap_binding_pressed(struct device *dev, u32_t position,
|
||||
u32_t param1, u32_t param2) {
|
||||
u32_t param1, u32_t param2,
|
||||
s64_t timestamp) {
|
||||
const struct behavior_driver_api *api = (const struct behavior_driver_api *)dev->driver_api;
|
||||
|
||||
if (api->binding_pressed == NULL) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
return api->binding_pressed(dev, position, param1, param2);
|
||||
return api->binding_pressed(dev, position, param1, param2, timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -65,17 +66,18 @@ static inline int z_impl_behavior_keymap_binding_pressed(struct device *dev, u32
|
|||
* @retval Negative errno code if failure.
|
||||
*/
|
||||
__syscall int behavior_keymap_binding_released(struct device *dev, u32_t position, u32_t param1,
|
||||
u32_t param2);
|
||||
u32_t param2, s64_t timestamp);
|
||||
|
||||
static inline int z_impl_behavior_keymap_binding_released(struct device *dev, u32_t position,
|
||||
u32_t param1, u32_t param2) {
|
||||
u32_t param1, u32_t param2,
|
||||
s64_t timestamp) {
|
||||
const struct behavior_driver_api *api = (const struct behavior_driver_api *)dev->driver_api;
|
||||
|
||||
if (api->binding_released == NULL) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
return api->binding_released(dev, position, param1, param2);
|
||||
return api->binding_released(dev, position, param1, param2, timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -14,16 +14,20 @@ struct keycode_state_changed {
|
|||
u8_t usage_page;
|
||||
u32_t keycode;
|
||||
bool state;
|
||||
u32_t position;
|
||||
s32_t timestamp;
|
||||
};
|
||||
|
||||
ZMK_EVENT_DECLARE(keycode_state_changed);
|
||||
|
||||
inline struct keycode_state_changed *create_keycode_state_changed(u8_t usage_page, u32_t keycode,
|
||||
bool state) {
|
||||
bool state, s32_t position,
|
||||
s32_t timestamp) {
|
||||
struct keycode_state_changed *ev = new_keycode_state_changed();
|
||||
ev->usage_page = usage_page;
|
||||
ev->keycode = keycode;
|
||||
ev->state = state;
|
||||
|
||||
ev->position = position;
|
||||
ev->timestamp = timestamp;
|
||||
return ev;
|
||||
}
|
|
@ -13,6 +13,7 @@ struct position_state_changed {
|
|||
struct zmk_event_header header;
|
||||
u32_t position;
|
||||
bool state;
|
||||
s64_t timestamp;
|
||||
};
|
||||
|
||||
ZMK_EVENT_DECLARE(position_state_changed);
|
|
@ -11,4 +11,4 @@ int zmk_keymap_layer_activate(u8_t layer);
|
|||
int zmk_keymap_layer_deactivate(u8_t layer);
|
||||
int zmk_keymap_layer_toggle(u8_t layer);
|
||||
|
||||
int zmk_keymap_position_state_changed(u32_t position, bool pressed);
|
||||
int zmk_keymap_position_state_changed(u32_t position, bool pressed, s64_t timestamp);
|
||||
|
|
|
@ -18,7 +18,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
|||
|
||||
#include <zmk/ble.h>
|
||||
|
||||
static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t command, u32_t arg) {
|
||||
static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t command, u32_t arg, s64_t timestamp) {
|
||||
switch (command) {
|
||||
case BT_CLR_CMD:
|
||||
return zmk_ble_clear_bonds();
|
||||
|
@ -38,7 +38,7 @@ static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t c
|
|||
static int behavior_bt_init(struct device *dev) { return 0; };
|
||||
|
||||
static int on_keymap_binding_released(struct device *dev, u32_t position, u32_t command,
|
||||
u32_t arg) {
|
||||
u32_t arg, s64_t timestamp) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,10 +40,8 @@ struct behavior_hold_tap_behaviors {
|
|||
struct zmk_behavior_binding hold;
|
||||
};
|
||||
|
||||
typedef k_timeout_t (*timer_func)();
|
||||
|
||||
struct behavior_hold_tap_config {
|
||||
timer_func tapping_term_ms;
|
||||
int tapping_term_ms;
|
||||
struct behavior_hold_tap_behaviors *behaviors;
|
||||
enum flavor flavor;
|
||||
};
|
||||
|
@ -53,6 +51,7 @@ struct active_hold_tap {
|
|||
s32_t position;
|
||||
u32_t param_hold;
|
||||
u32_t param_tap;
|
||||
s64_t timestamp;
|
||||
bool is_decided;
|
||||
bool is_hold;
|
||||
const struct behavior_hold_tap_config *config;
|
||||
|
@ -164,6 +163,7 @@ static struct active_hold_tap *find_hold_tap(u32_t position) {
|
|||
}
|
||||
|
||||
static struct active_hold_tap *store_hold_tap(u32_t position, u32_t param_hold, u32_t param_tap,
|
||||
s64_t timestamp,
|
||||
const struct behavior_hold_tap_config *config) {
|
||||
for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_HELD; i++) {
|
||||
if (active_hold_taps[i].position != ZMK_BHV_HOLD_TAP_POSITION_NOT_USED) {
|
||||
|
@ -175,6 +175,7 @@ static struct active_hold_tap *store_hold_tap(u32_t position, u32_t param_hold,
|
|||
active_hold_taps[i].config = config;
|
||||
active_hold_taps[i].param_hold = param_hold;
|
||||
active_hold_taps[i].param_tap = param_tap;
|
||||
active_hold_taps[i].timestamp = timestamp;
|
||||
return &active_hold_taps[i];
|
||||
}
|
||||
return NULL;
|
||||
|
@ -285,18 +286,18 @@ static void decide_hold_tap(struct active_hold_tap *hold_tap, enum decision_mome
|
|||
behavior = &hold_tap->config->behaviors->hold;
|
||||
struct device *behavior_device = device_get_binding(behavior->behavior_dev);
|
||||
behavior_keymap_binding_pressed(behavior_device, hold_tap->position, hold_tap->param_hold,
|
||||
0);
|
||||
0, hold_tap->timestamp);
|
||||
} else {
|
||||
behavior = &hold_tap->config->behaviors->tap;
|
||||
struct device *behavior_device = device_get_binding(behavior->behavior_dev);
|
||||
behavior_keymap_binding_pressed(behavior_device, hold_tap->position, hold_tap->param_tap,
|
||||
0);
|
||||
behavior_keymap_binding_pressed(behavior_device, hold_tap->position, hold_tap->param_tap, 0,
|
||||
hold_tap->timestamp);
|
||||
}
|
||||
release_captured_events();
|
||||
}
|
||||
|
||||
static int on_hold_tap_binding_pressed(struct device *dev, u32_t position, u32_t param_hold,
|
||||
u32_t param_tap) {
|
||||
u32_t param_tap, s64_t timestamp) {
|
||||
const struct behavior_hold_tap_config *cfg = dev->config_info;
|
||||
|
||||
if (undecided_hold_tap != NULL) {
|
||||
|
@ -305,7 +306,8 @@ static int on_hold_tap_binding_pressed(struct device *dev, u32_t position, u32_t
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct active_hold_tap *hold_tap = store_hold_tap(position, param_hold, param_tap, cfg);
|
||||
struct active_hold_tap *hold_tap =
|
||||
store_hold_tap(position, param_hold, param_tap, timestamp, cfg);
|
||||
if (hold_tap == NULL) {
|
||||
LOG_ERR("unable to store hold-tap info, did you press more than %d hold-taps?",
|
||||
ZMK_BHV_HOLD_TAP_MAX_HELD);
|
||||
|
@ -314,23 +316,32 @@ static int on_hold_tap_binding_pressed(struct device *dev, u32_t position, u32_t
|
|||
|
||||
LOG_DBG("%d new undecided hold_tap", position);
|
||||
undecided_hold_tap = hold_tap;
|
||||
k_delayed_work_submit(&hold_tap->work, cfg->tapping_term_ms());
|
||||
|
||||
// todo: once we get timing info for keypresses, start the timer relative to the original
|
||||
// keypress don't forget to simulate a timer-event before the event after that time was handled.
|
||||
// if this behavior was queued we have to adjust the timer to only
|
||||
// wait for the remaining time.
|
||||
s32_t tapping_term_ms_left = (hold_tap->timestamp + cfg->tapping_term_ms) - k_uptime_get();
|
||||
if (tapping_term_ms_left > 0) {
|
||||
k_delayed_work_submit(&hold_tap->work, K_MSEC(tapping_term_ms_left));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int on_hold_tap_binding_released(struct device *dev, u32_t position, u32_t _, u32_t __) {
|
||||
static int on_hold_tap_binding_released(struct device *dev, u32_t position, u32_t _, u32_t __,
|
||||
s64_t timestamp) {
|
||||
struct active_hold_tap *hold_tap = find_hold_tap(position);
|
||||
|
||||
if (hold_tap == NULL) {
|
||||
LOG_ERR("ACTIVE_HOLD_TAP_CLEANED_UP_TOO_EARLY");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If these events were queued, the timer event may be queued too late or not at all.
|
||||
// We insert a timer event before the TH_KEY_UP event to verify.
|
||||
int work_cancel_result = k_delayed_work_cancel(&hold_tap->work);
|
||||
if (timestamp > (hold_tap->timestamp + hold_tap->config->tapping_term_ms)) {
|
||||
decide_hold_tap(hold_tap, HT_TIMER_EVENT);
|
||||
}
|
||||
|
||||
decide_hold_tap(hold_tap, HT_KEY_UP);
|
||||
|
||||
struct zmk_behavior_binding *behavior;
|
||||
|
@ -338,12 +349,12 @@ static int on_hold_tap_binding_released(struct device *dev, u32_t position, u32_
|
|||
behavior = &hold_tap->config->behaviors->hold;
|
||||
struct device *behavior_device = device_get_binding(behavior->behavior_dev);
|
||||
behavior_keymap_binding_released(behavior_device, hold_tap->position, hold_tap->param_hold,
|
||||
0);
|
||||
0, timestamp);
|
||||
} else {
|
||||
behavior = &hold_tap->config->behaviors->tap;
|
||||
struct device *behavior_device = device_get_binding(behavior->behavior_dev);
|
||||
behavior_keymap_binding_released(behavior_device, hold_tap->position, hold_tap->param_tap,
|
||||
0);
|
||||
0, timestamp);
|
||||
}
|
||||
|
||||
if (work_cancel_result == -EINPROGRESS) {
|
||||
|
@ -382,6 +393,14 @@ static int position_state_changed_listener(const struct zmk_event_header *eh) {
|
|||
}
|
||||
}
|
||||
|
||||
// If these events were queued, the timer event may be queued too late or not at all.
|
||||
// We make a timer decision before the other key events are handled if the timer would
|
||||
// have run out.
|
||||
if (ev->timestamp >
|
||||
(undecided_hold_tap->timestamp + undecided_hold_tap->config->tapping_term_ms)) {
|
||||
decide_hold_tap(undecided_hold_tap, HT_TIMER_EVENT);
|
||||
}
|
||||
|
||||
if (!ev->state && find_captured_keydown_event(ev->position) == NULL) {
|
||||
// no keydown event has been captured, let it bubble.
|
||||
// we'll catch modifiers later in modifier_state_changed_listener
|
||||
|
@ -473,14 +492,11 @@ static struct behavior_hold_tap_data behavior_hold_tap_data;
|
|||
},
|
||||
|
||||
#define KP_INST(n) \
|
||||
static k_timeout_t behavior_hold_tap_config_##n##_gettime() { \
|
||||
return K_MSEC(DT_INST_PROP(n, tapping_term_ms)); \
|
||||
} \
|
||||
static struct behavior_hold_tap_behaviors behavior_hold_tap_behaviors_##n = { \
|
||||
.hold = _TRANSFORM_ENTRY(0, n).tap = _TRANSFORM_ENTRY(1, n)}; \
|
||||
static struct behavior_hold_tap_config behavior_hold_tap_config_##n = { \
|
||||
.behaviors = &behavior_hold_tap_behaviors_##n, \
|
||||
.tapping_term_ms = &behavior_hold_tap_config_##n##_gettime, \
|
||||
.tapping_term_ms = DT_INST_PROP(n, tapping_term_ms), \
|
||||
.flavor = DT_ENUM_IDX(DT_DRV_INST(n), flavor), \
|
||||
}; \
|
||||
DEVICE_AND_API_INIT(behavior_hold_tap_##n, DT_INST_LABEL(n), behavior_hold_tap_init, \
|
||||
|
|
|
@ -22,18 +22,22 @@ struct behavior_key_press_data {};
|
|||
|
||||
static int behavior_key_press_init(struct device *dev) { return 0; };
|
||||
|
||||
static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t keycode, u32_t _) {
|
||||
static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t keycode, u32_t _,
|
||||
s64_t timestamp) {
|
||||
const struct behavior_key_press_config *cfg = dev->config_info;
|
||||
LOG_DBG("position %d usage_page 0x%02X keycode 0x%02X", position, cfg->usage_page, keycode);
|
||||
|
||||
return ZMK_EVENT_RAISE(create_keycode_state_changed(cfg->usage_page, keycode, true));
|
||||
return ZMK_EVENT_RAISE(
|
||||
create_keycode_state_changed(cfg->usage_page, keycode, true, position, timestamp));
|
||||
}
|
||||
|
||||
static int on_keymap_binding_released(struct device *dev, u32_t position, u32_t keycode, u32_t _) {
|
||||
static int on_keymap_binding_released(struct device *dev, u32_t position, u32_t keycode, u32_t _,
|
||||
s64_t timestamp) {
|
||||
const struct behavior_key_press_config *cfg = dev->config_info;
|
||||
LOG_DBG("position %d usage_page 0x%02X keycode 0x%02X", position, cfg->usage_page, keycode);
|
||||
|
||||
return ZMK_EVENT_RAISE(create_keycode_state_changed(cfg->usage_page, keycode, false));
|
||||
return ZMK_EVENT_RAISE(
|
||||
create_keycode_state_changed(cfg->usage_page, keycode, false, position, timestamp));
|
||||
}
|
||||
|
||||
static const struct behavior_driver_api behavior_key_press_driver_api = {
|
||||
|
|
|
@ -19,15 +19,15 @@ struct behavior_mo_data {};
|
|||
|
||||
static int behavior_mo_init(struct device *dev) { return 0; };
|
||||
|
||||
static int mo_keymap_binding_pressed(struct device *dev, u32_t position, u32_t layer, u32_t _) {
|
||||
static int mo_keymap_binding_pressed(struct device *dev, u32_t position, u32_t layer, u32_t _,
|
||||
s64_t _timestamp) {
|
||||
LOG_DBG("position %d layer %d", position, layer);
|
||||
|
||||
return zmk_keymap_layer_activate(layer);
|
||||
}
|
||||
|
||||
static int mo_keymap_binding_released(struct device *dev, u32_t position, u32_t layer, u32_t _) {
|
||||
static int mo_keymap_binding_released(struct device *dev, u32_t position, u32_t layer, u32_t _,
|
||||
s64_t _timestamp) {
|
||||
LOG_DBG("position %d layer %d", position, layer);
|
||||
|
||||
return zmk_keymap_layer_deactivate(layer);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,12 +19,12 @@ struct behavior_none_data {};
|
|||
static int behavior_none_init(struct device *dev) { return 0; };
|
||||
|
||||
static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t _param1,
|
||||
u32_t _param2) {
|
||||
u32_t _param2, s64_t _timestamp) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int on_keymap_binding_released(struct device *dev, u32_t position, u32_t _param1,
|
||||
u32_t _param2) {
|
||||
u32_t _param2, s64_t _timestamp) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ struct behavior_reset_config {
|
|||
static int behavior_reset_init(struct device *dev) { return 0; };
|
||||
|
||||
static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t _param1,
|
||||
u32_t _param2) {
|
||||
u32_t _param2, s64_t _timestamp) {
|
||||
const struct behavior_reset_config *cfg = dev->config_info;
|
||||
|
||||
// TODO: Correct magic code for going into DFU?
|
||||
|
|
|
@ -17,7 +17,8 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
|||
|
||||
static int behavior_rgb_underglow_init(struct device *dev) { return 0; }
|
||||
|
||||
static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t action, u32_t _) {
|
||||
static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t action, u32_t _,
|
||||
s64_t _timestamp) {
|
||||
switch (action) {
|
||||
case RGB_TOG:
|
||||
return zmk_rgb_underglow_toggle();
|
||||
|
|
|
@ -19,15 +19,15 @@ struct behavior_tog_data {};
|
|||
|
||||
static int behavior_tog_init(struct device *dev) { return 0; };
|
||||
|
||||
static int tog_keymap_binding_pressed(struct device *dev, u32_t position, u32_t layer, u32_t _) {
|
||||
static int tog_keymap_binding_pressed(struct device *dev, u32_t position, u32_t layer, u32_t _,
|
||||
s64_t _timestamp) {
|
||||
LOG_DBG("position %d layer %d", position, layer);
|
||||
|
||||
return zmk_keymap_layer_toggle(layer);
|
||||
}
|
||||
|
||||
static int tog_keymap_binding_released(struct device *dev, u32_t position, u32_t layer, u32_t _) {
|
||||
static int tog_keymap_binding_released(struct device *dev, u32_t position, u32_t layer, u32_t _,
|
||||
s64_t _timestamp) {
|
||||
LOG_DBG("position %d layer %d", position, layer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,12 +19,12 @@ struct behavior_transparent_data {};
|
|||
static int behavior_transparent_init(struct device *dev) { return 0; };
|
||||
|
||||
static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t _param1,
|
||||
u32_t _param2) {
|
||||
u32_t _param2, s64_t _timestamp) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int on_keymap_binding_released(struct device *dev, u32_t position, u32_t _param1,
|
||||
u32_t _param2) {
|
||||
u32_t _param2, s64_t _timestamp) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ bool is_active_layer(u8_t layer, u32_t layer_state) {
|
|||
return (layer_state & BIT(layer)) == BIT(layer) || layer == zmk_keymap_layer_default;
|
||||
}
|
||||
|
||||
int zmk_keymap_apply_position_state(int layer, u32_t position, bool pressed) {
|
||||
int zmk_keymap_apply_position_state(int layer, u32_t position, bool pressed, s64_t timestamp) {
|
||||
struct zmk_behavior_binding *binding = &zmk_keymap[layer][position];
|
||||
struct device *behavior;
|
||||
|
||||
|
@ -119,20 +119,20 @@ int zmk_keymap_apply_position_state(int layer, u32_t position, bool pressed) {
|
|||
}
|
||||
|
||||
if (pressed) {
|
||||
return behavior_keymap_binding_pressed(behavior, position, binding->param1,
|
||||
binding->param2);
|
||||
return behavior_keymap_binding_pressed(behavior, position, binding->param1, binding->param2,
|
||||
timestamp);
|
||||
} else {
|
||||
return behavior_keymap_binding_released(behavior, position, binding->param1,
|
||||
binding->param2);
|
||||
binding->param2, timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
int zmk_keymap_position_state_changed(u32_t position, bool pressed) {
|
||||
int zmk_keymap_position_state_changed(u32_t position, bool pressed, s64_t timestamp) {
|
||||
for (int layer = ZMK_KEYMAP_LAYERS_LEN - 1; layer >= zmk_keymap_layer_default; layer--) {
|
||||
u32_t layer_state =
|
||||
pressed ? zmk_keymap_layer_state : zmk_keymap_active_behavior_layer[position];
|
||||
if (is_active_layer(layer, layer_state)) {
|
||||
int ret = zmk_keymap_apply_position_state(layer, position, pressed);
|
||||
int ret = zmk_keymap_apply_position_state(layer, position, pressed, timestamp);
|
||||
|
||||
zmk_keymap_active_behavior_layer[position] = zmk_keymap_layer_state;
|
||||
|
||||
|
@ -194,7 +194,7 @@ int zmk_keymap_sensor_triggered(u8_t sensor_number, struct device *sensor) {
|
|||
int keymap_listener(const struct zmk_event_header *eh) {
|
||||
if (is_position_state_changed(eh)) {
|
||||
const struct position_state_changed *ev = cast_position_state_changed(eh);
|
||||
return zmk_keymap_position_state_changed(ev->position, ev->state);
|
||||
return zmk_keymap_position_state_changed(ev->position, ev->state, ev->timestamp);
|
||||
#if ZMK_KEYMAP_HAS_SENSORS
|
||||
} else if (is_sensor_event(eh)) {
|
||||
const struct sensor_event *ev = cast_sensor_event(eh);
|
||||
|
|
|
@ -52,6 +52,7 @@ void zmk_kscan_process_msgq(struct k_work *item) {
|
|||
pos_ev = new_position_state_changed();
|
||||
pos_ev->state = pressed;
|
||||
pos_ev->position = position;
|
||||
pos_ev->timestamp = k_uptime_get();
|
||||
ZMK_EVENT_RAISE(pos_ev);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@ static u8_t split_central_notify_func(struct bt_conn *conn, struct bt_gatt_subsc
|
|||
struct position_state_changed *pos_ev = new_position_state_changed();
|
||||
pos_ev->position = position;
|
||||
pos_ev->state = pressed;
|
||||
pos_ev->timestamp = k_uptime_get();
|
||||
|
||||
LOG_DBG("Trigger key position state change for %d", position);
|
||||
ZMK_EVENT_RAISE(pos_ev);
|
||||
|
|
4
app/tests/hold-tap/balanced/many-nested/events.patterns
Normal file
4
app/tests/hold-tap/balanced/many-nested/events.patterns
Normal file
|
@ -0,0 +1,4 @@
|
|||
s/.*hid_listener_keycode/kp/p
|
||||
s/.*mo_keymap_binding/mo/p
|
||||
s/.*on_hold_tap_binding/ht_binding/p
|
||||
s/.*decide_hold_tap/ht_decide/p
|
|
@ -0,0 +1,20 @@
|
|||
ht_binding_pressed: 0 new undecided hold_tap
|
||||
ht_decide: 0 decided hold (balanced event 3)
|
||||
kp_pressed: usage_page 0x07 keycode 0xe1
|
||||
ht_binding_pressed: 1 new undecided hold_tap
|
||||
ht_decide: 1 decided hold (balanced event 3)
|
||||
kp_pressed: usage_page 0x07 keycode 0xe0
|
||||
ht_binding_pressed: 2 new undecided hold_tap
|
||||
ht_binding_released: 0 cleaning up hold-tap
|
||||
ht_decide: 2 decided hold (balanced event 3)
|
||||
kp_pressed: usage_page 0x07 keycode 0xe3
|
||||
ht_binding_pressed: 3 new undecided hold_tap
|
||||
ht_binding_released: 1 cleaning up hold-tap
|
||||
ht_decide: 3 decided hold (balanced event 3)
|
||||
kp_pressed: usage_page 0x07 keycode 0xe2
|
||||
kp_released: usage_page 0x07 keycode 0xe1
|
||||
kp_released: usage_page 0x07 keycode 0xe0
|
||||
kp_released: usage_page 0x07 keycode 0xe3
|
||||
ht_binding_released: 2 cleaning up hold-tap
|
||||
kp_released: usage_page 0x07 keycode 0xe2
|
||||
ht_binding_released: 3 cleaning up hold-tap
|
41
app/tests/hold-tap/balanced/many-nested/native_posix.keymap
Normal file
41
app/tests/hold-tap/balanced/many-nested/native_posix.keymap
Normal file
|
@ -0,0 +1,41 @@
|
|||
#include <dt-bindings/zmk/keys.h>
|
||||
#include <behaviors.dtsi>
|
||||
#include <dt-bindings/zmk/kscan-mock.h>
|
||||
|
||||
/ {
|
||||
behaviors {
|
||||
ht_bal: behavior_hold_tap_balanced {
|
||||
compatible = "zmk,behavior-hold-tap";
|
||||
label = "HOLD_TAP_BALANCED";
|
||||
#binding-cells = <2>;
|
||||
flavor = "balanced";
|
||||
tapping_term_ms = <300>;
|
||||
bindings = <&kp>, <&kp>;
|
||||
};
|
||||
};
|
||||
|
||||
keymap {
|
||||
compatible = "zmk,keymap";
|
||||
label ="Default keymap";
|
||||
|
||||
default_layer {
|
||||
bindings = <
|
||||
&ht_bal LSFT F &ht_bal LCTL J
|
||||
&ht_bal LGUI H &ht_bal LALT L
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&kscan {
|
||||
events = <
|
||||
ZMK_MOCK_PRESS(0,0,100)
|
||||
ZMK_MOCK_PRESS(0,1,100)
|
||||
ZMK_MOCK_PRESS(1,0,100)
|
||||
ZMK_MOCK_PRESS(1,1,100)
|
||||
ZMK_MOCK_RELEASE(0,0,100)
|
||||
ZMK_MOCK_RELEASE(0,1,100)
|
||||
ZMK_MOCK_RELEASE(1,0,100)
|
||||
ZMK_MOCK_RELEASE(1,1,100)
|
||||
>;
|
||||
};
|
Loading…
Add table
Reference in a new issue