diff --git a/app/src/behaviors/behavior_sticky_key.c b/app/src/behaviors/behavior_sticky_key.c index 20af93a8..40ca3f89 100644 --- a/app/src/behaviors/behavior_sticky_key.c +++ b/app/src/behaviors/behavior_sticky_key.c @@ -177,6 +177,11 @@ static const struct behavior_driver_api behavior_sticky_key_driver_api = { .binding_released = on_sticky_key_binding_released, }; +static int sticky_key_keycode_state_changed_listener(const zmk_event_t *eh); + +ZMK_LISTENER(behavior_sticky_key, sticky_key_keycode_state_changed_listener); +ZMK_SUBSCRIPTION(behavior_sticky_key, zmk_keycode_state_changed); + static int sticky_key_keycode_state_changed_listener(const zmk_event_t *eh) { struct zmk_keycode_state_changed *ev = as_zmk_keycode_state_changed(eh); if (ev == NULL) { @@ -212,7 +217,10 @@ static int sticky_key_keycode_state_changed_listener(const zmk_event_t *eh) { if (sticky_key->timer_started) { stop_timer(sticky_key); if (sticky_key->config->quick_release) { + // continue processing the event. Release the sticky key afterwards. + ZMK_EVENT_RAISE_AFTER(eh, behavior_sticky_key); release_sticky_key_behavior(sticky_key, ev->timestamp); + return ZMK_EV_EVENT_CAPTURED; } } sticky_key->modified_key_usage_page = ev->usage_page; @@ -229,9 +237,6 @@ static int sticky_key_keycode_state_changed_listener(const zmk_event_t *eh) { return ZMK_EV_EVENT_BUBBLE; } -ZMK_LISTENER(behavior_sticky_key, sticky_key_keycode_state_changed_listener); -ZMK_SUBSCRIPTION(behavior_sticky_key, zmk_keycode_state_changed); - void behavior_sticky_key_timer_handler(struct k_work *item) { struct active_sticky_key *sticky_key = CONTAINER_OF(item, struct active_sticky_key, release_timer); diff --git a/app/tests/sticky-keys/2-os-dn-up-kcdn-kcup-quick-release/events.patterns b/app/tests/sticky-keys/2-os-dn-up-kcdn-kcup-quick-release/events.patterns new file mode 100644 index 00000000..833100f6 --- /dev/null +++ b/app/tests/sticky-keys/2-os-dn-up-kcdn-kcup-quick-release/events.patterns @@ -0,0 +1 @@ +s/.*hid_listener_keycode_//p \ No newline at end of file diff --git a/app/tests/sticky-keys/2-os-dn-up-kcdn-kcup-quick-release/keycode_events.snapshot b/app/tests/sticky-keys/2-os-dn-up-kcdn-kcup-quick-release/keycode_events.snapshot new file mode 100644 index 00000000..c85d8b49 --- /dev/null +++ b/app/tests/sticky-keys/2-os-dn-up-kcdn-kcup-quick-release/keycode_events.snapshot @@ -0,0 +1,10 @@ +pressed: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +pressed: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00 +pressed: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 diff --git a/app/tests/sticky-keys/2-os-dn-up-kcdn-kcup-quick-release/native_posix.keymap b/app/tests/sticky-keys/2-os-dn-up-kcdn-kcup-quick-release/native_posix.keymap new file mode 100644 index 00000000..33115453 --- /dev/null +++ b/app/tests/sticky-keys/2-os-dn-up-kcdn-kcup-quick-release/native_posix.keymap @@ -0,0 +1,26 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&sk { + quick-release; +}; + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_PRESS(1,0,10) + /* second key is pressed shortly after the first. It should not be capitalized. */ + ZMK_MOCK_PRESS(1,1,10) + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(1,1,10) + + /* repeat test to check if cleanup is done correctly */ + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_RELEASE(1,0,10) + >; +}; \ No newline at end of file