summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/src/combo.c13
-rw-r--r--app/tests/combo/press-release-long-combo-wrong-last-key/events.patterns1
-rw-r--r--app/tests/combo/press-release-long-combo-wrong-last-key/keycode_events.snapshot6
-rw-r--r--app/tests/combo/press-release-long-combo-wrong-last-key/native_posix.keymap37
4 files changed, 54 insertions, 3 deletions
diff --git a/app/src/combo.c b/app/src/combo.c
index 72535b2..16091cd 100644
--- a/app/src/combo.c
+++ b/app/src/combo.c
@@ -188,8 +188,15 @@ static int64_t first_candidate_timeout() {
static inline bool candidate_is_completely_pressed(struct combo_cfg *candidate) {
// this code assumes set(pressed_keys) <= set(candidate->key_positions)
// this invariant is enforced by filter_candidates
- // the only thing we need to do is check if len(pressed_keys) == len(combo->key_positions)
- return pressed_keys[candidate->key_position_len - 1] != NULL;
+ // since events may have been reraised after clearing one or more slots at
+ // the start of pressed_keys (see: release_pressed_keys), we have to check
+ // that each key needed to trigger the combo was pressed, not just the last.
+ for (int i = 0; i < candidate->key_position_len; i++) {
+ if (pressed_keys[i] == NULL) {
+ return false;
+ }
+ }
+ return true;
}
static int cleanup();
@@ -496,4 +503,4 @@ static int combo_init() {
SYS_INIT(combo_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
-#endif \ No newline at end of file
+#endif
diff --git a/app/tests/combo/press-release-long-combo-wrong-last-key/events.patterns b/app/tests/combo/press-release-long-combo-wrong-last-key/events.patterns
new file mode 100644
index 0000000..b1342af
--- /dev/null
+++ b/app/tests/combo/press-release-long-combo-wrong-last-key/events.patterns
@@ -0,0 +1 @@
+s/.*hid_listener_keycode_//p
diff --git a/app/tests/combo/press-release-long-combo-wrong-last-key/keycode_events.snapshot b/app/tests/combo/press-release-long-combo-wrong-last-key/keycode_events.snapshot
new file mode 100644
index 0000000..d1b9db9
--- /dev/null
+++ b/app/tests/combo/press-release-long-combo-wrong-last-key/keycode_events.snapshot
@@ -0,0 +1,6 @@
+pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
+pressed: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00
+pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
+released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
+released: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00
+released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
diff --git a/app/tests/combo/press-release-long-combo-wrong-last-key/native_posix.keymap b/app/tests/combo/press-release-long-combo-wrong-last-key/native_posix.keymap
new file mode 100644
index 0000000..b811718
--- /dev/null
+++ b/app/tests/combo/press-release-long-combo-wrong-last-key/native_posix.keymap
@@ -0,0 +1,37 @@
+#include <dt-bindings/zmk/keys.h>
+#include <behaviors.dtsi>
+#include <dt-bindings/zmk/kscan-mock.h>
+
+/ {
+ combos {
+ compatible = "zmk,combos";
+ combo_one {
+ timeout-ms = <80>;
+ key-positions = <0 1 2>;
+ bindings = <&kp Z>;
+ };
+ };
+
+ keymap {
+ compatible = "zmk,keymap";
+ label ="Default keymap";
+
+ default_layer {
+ bindings = <
+ &kp A &kp B
+ &kp C &kp D
+ >;
+ };
+ };
+};
+
+&kscan {
+ events = <
+ ZMK_MOCK_PRESS(0,0,10)
+ ZMK_MOCK_PRESS(0,1,10)
+ ZMK_MOCK_PRESS(1,1,10)
+ ZMK_MOCK_RELEASE(1,1,100)
+ ZMK_MOCK_RELEASE(0,1,100)
+ ZMK_MOCK_RELEASE(0,0,100)
+ >;
+};