diff --git a/app/dts/behaviors/sticky_key.dtsi b/app/dts/behaviors/sticky_key.dtsi index 1e66a1ed..f1c1cdd5 100644 --- a/app/dts/behaviors/sticky_key.dtsi +++ b/app/dts/behaviors/sticky_key.dtsi @@ -19,6 +19,7 @@ #binding-cells = <1>; release-after-ms = <1000>; bindings = <&mo>; + quick-release; }; }; diff --git a/app/dts/bindings/behaviors/zmk,behavior-sticky-key.yaml b/app/dts/bindings/behaviors/zmk,behavior-sticky-key.yaml index df9c423c..1c2ab7f3 100644 --- a/app/dts/bindings/behaviors/zmk,behavior-sticky-key.yaml +++ b/app/dts/bindings/behaviors/zmk,behavior-sticky-key.yaml @@ -13,3 +13,5 @@ properties: required: true release-after-ms: type: int + quick-release: + type: boolean diff --git a/app/src/behaviors/behavior_sticky_key.c b/app/src/behaviors/behavior_sticky_key.c index fe05e067..aa9fe9ac 100644 --- a/app/src/behaviors/behavior_sticky_key.c +++ b/app/src/behaviors/behavior_sticky_key.c @@ -29,6 +29,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); struct behavior_sticky_key_config { uint32_t release_after_ms; + bool quick_release; struct zmk_behavior_binding behavior; }; @@ -209,10 +210,12 @@ 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) { + release_sticky_key_behavior(sticky_key, ev->timestamp); + } } sticky_key->modified_key_usage_page = ev->usage_page; sticky_key->modified_key_keycode = ev->keycode; - } else { // key up if (sticky_key->timer_started && sticky_key->modified_key_usage_page == ev->usage_page && @@ -269,6 +272,7 @@ static struct behavior_sticky_key_data behavior_sticky_key_data; #define KP_INST(n) \ static struct behavior_sticky_key_config behavior_sticky_key_config_##n = { \ .behavior = _TRANSFORM_ENTRY(0, n).release_after_ms = DT_INST_PROP(n, release_after_ms), \ + .quick_release = DT_INST_PROP(n, quick_release), \ }; \ DEVICE_AND_API_INIT(behavior_sticky_key_##n, DT_INST_LABEL(n), behavior_sticky_key_init, \ &behavior_sticky_key_data, &behavior_sticky_key_config_##n, APPLICATION, \ diff --git a/app/tests/sticky-keys/2-sl-dn-up-kcdn-kcup/events.patterns b/app/tests/sticky-keys/2-sl-dn-up-kcdn-kcup/events.patterns new file mode 100644 index 00000000..833100f6 --- /dev/null +++ b/app/tests/sticky-keys/2-sl-dn-up-kcdn-kcup/events.patterns @@ -0,0 +1 @@ +s/.*hid_listener_keycode_//p \ No newline at end of file diff --git a/app/tests/sticky-keys/2-sl-dn-up-kcdn-kcup/keycode_events.snapshot b/app/tests/sticky-keys/2-sl-dn-up-kcdn-kcup/keycode_events.snapshot new file mode 100644 index 00000000..7e745b51 --- /dev/null +++ b/app/tests/sticky-keys/2-sl-dn-up-kcdn-kcup/keycode_events.snapshot @@ -0,0 +1,8 @@ +pressed: usage_page 0x07 keycode 0x1b implicit_mods 0x00 explicit_mods 0x00 +pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0x1b implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +pressed: usage_page 0x07 keycode 0x1b implicit_mods 0x00 explicit_mods 0x00 +pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0x1b 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-sl-dn-up-kcdn-kcup/native_posix.keymap b/app/tests/sticky-keys/2-sl-dn-up-kcdn-kcup/native_posix.keymap new file mode 100644 index 00000000..4470fb21 --- /dev/null +++ b/app/tests/sticky-keys/2-sl-dn-up-kcdn-kcup/native_posix.keymap @@ -0,0 +1,52 @@ +#include +#include +#include + +/* + sticky layers should quick-release. + Thus, the second keypress should be on the default layer, not on the lower_layer. +*/ + +/ { + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &sk E &sl 1 + &kp A &kp B>; + }; + + lower_layer { + bindings = < + &sk LEFT_CONTROL &kp X + &kp Y &kp Z>; + }; + }; +}; + +&kscan { + events = < + /* press sl 1 */ + ZMK_MOCK_PRESS(0,1,10) + ZMK_MOCK_RELEASE(0,1,10) + /* press X */ + ZMK_MOCK_PRESS(0,1,10) + /* press A */ + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_RELEASE(0,1,10) + ZMK_MOCK_RELEASE(1,0,10) + + /* repeat test to check if cleanup is done correctly */ + /* press sl 1 */ + ZMK_MOCK_PRESS(0,1,10) + ZMK_MOCK_RELEASE(0,1,10) + /* press X */ + ZMK_MOCK_PRESS(0,1,10) + /* press Y */ + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_RELEASE(0,1,10) + ZMK_MOCK_RELEASE(1,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/sticky-keys/8-lsk-osk-combination/events.patterns b/app/tests/sticky-keys/8-lsk-osk-combination/events.patterns index 833100f6..b1342af4 100644 --- a/app/tests/sticky-keys/8-lsk-osk-combination/events.patterns +++ b/app/tests/sticky-keys/8-lsk-osk-combination/events.patterns @@ -1 +1 @@ -s/.*hid_listener_keycode_//p \ No newline at end of file +s/.*hid_listener_keycode_//p diff --git a/app/tests/sticky-keys/8-lsk-osk-combination/keycode_events.snapshot b/app/tests/sticky-keys/8-lsk-osk-combination/keycode_events.snapshot index 8eb8a352..374035fc 100644 --- a/app/tests/sticky-keys/8-lsk-osk-combination/keycode_events.snapshot +++ b/app/tests/sticky-keys/8-lsk-osk-combination/keycode_events.snapshot @@ -1,8 +1,8 @@ pressed: usage_page 0x07 keycode 0xe0 implicit_mods 0x00 explicit_mods 0x00 -pressed: usage_page 0x07 keycode 0x1c implicit_mods 0x00 explicit_mods 0x00 +pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 released: usage_page 0x07 keycode 0xe0 implicit_mods 0x00 explicit_mods 0x00 -released: usage_page 0x07 keycode 0x1c implicit_mods 0x00 explicit_mods 0x00 +released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 pressed: usage_page 0x07 keycode 0xe0 implicit_mods 0x00 explicit_mods 0x00 -pressed: usage_page 0x07 keycode 0x1c implicit_mods 0x00 explicit_mods 0x00 +pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 released: usage_page 0x07 keycode 0xe0 implicit_mods 0x00 explicit_mods 0x00 -released: usage_page 0x07 keycode 0x1c 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/8-lsk-osk-combination/native_posix.keymap b/app/tests/sticky-keys/8-lsk-osk-combination/native_posix.keymap index beedd44e..bdcccf33 100644 --- a/app/tests/sticky-keys/8-lsk-osk-combination/native_posix.keymap +++ b/app/tests/sticky-keys/8-lsk-osk-combination/native_posix.keymap @@ -29,7 +29,7 @@ /* tap sk LEFT_CONTROL */ ZMK_MOCK_PRESS(0,0,10) ZMK_MOCK_RELEASE(0,0,10) - /* tap Y */ + /* tap A */ ZMK_MOCK_PRESS(1,0,10) ZMK_MOCK_RELEASE(1,0,10) @@ -40,7 +40,7 @@ /* tap sk */ ZMK_MOCK_PRESS(0,0,10) ZMK_MOCK_RELEASE(0,0,10) - /* tap Y */ + /* tap A */ ZMK_MOCK_PRESS(1,0,10) ZMK_MOCK_RELEASE(1,0,10) >;