diff --git a/app/src/behaviors/behavior_hold_tap.c b/app/src/behaviors/behavior_hold_tap.c index c45ee803..44748fe2 100644 --- a/app/src/behaviors/behavior_hold_tap.c +++ b/app/src/behaviors/behavior_hold_tap.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -801,11 +802,37 @@ static int keycode_state_changed_listener(const zmk_event_t *eh) { return ZMK_EV_EVENT_CAPTURED; } +static int sensor_event_listener(const zmk_event_t *eh) { + struct zmk_sensor_event *ev = as_zmk_sensor_event(eh); + + update_hold_status_for_retro_tap(ev->sensor_number); + + if (undecided_hold_tap == NULL) { + LOG_DBG("bubble (no undecided hold_tap active)"); + return ZMK_EV_EVENT_BUBBLE; + } + + // 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); + } + + capture_event(eh); + decide_hold_tap(undecided_hold_tap, HT_OTHER_KEY_DOWN); + decide_hold_tap(undecided_hold_tap, HT_OTHER_KEY_UP); + return ZMK_EV_EVENT_CAPTURED; +} + int behavior_hold_tap_listener(const zmk_event_t *eh) { if (as_zmk_position_state_changed(eh) != NULL) { return position_state_changed_listener(eh); } else if (as_zmk_keycode_state_changed(eh) != NULL) { return keycode_state_changed_listener(eh); + } else if (as_zmk_sensor_event(eh) != NULL) { + return sensor_event_listener(eh); } return ZMK_EV_EVENT_BUBBLE; } @@ -814,6 +841,7 @@ ZMK_LISTENER(behavior_hold_tap, behavior_hold_tap_listener); ZMK_SUBSCRIPTION(behavior_hold_tap, zmk_position_state_changed); // this should be modifiers_state_changed, but unfrotunately that's not implemented yet. ZMK_SUBSCRIPTION(behavior_hold_tap, zmk_keycode_state_changed); +ZMK_SUBSCRIPTION(behavior_hold_tap, zmk_sensor_event); void behavior_hold_tap_timer_work_handler(struct k_work *item) { struct k_work_delayable *d_work = k_work_delayable_from_work(item);