From 4e69a32103a2905b9a32c80c8d3d798fbb0d9a0f Mon Sep 17 00:00:00 2001 From: Jonathan Rascher Date: Tue, 8 Jun 2021 10:56:02 -0500 Subject: fix(combos): Check each combo key, not just last The current combo completion check only makes sure the last key in the combo is set. This works when the combo is typed correctly initially, or when reraising events in a combo of length two. However, it fails for longer combos since the last event in pressed_keys might be set, but the first (or subsequent) event in pressed_keys can be NULL thanks to release_pressed_keys. Also added a regression test. --- app/src/combo.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'app/src') 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 -- cgit v1.2.3