Only fire the longest matching sequence when combos overlap#72
Open
MichaelBuessemeyer wants to merge 1 commit into
Open
Only fire the longest matching sequence when combos overlap#72MichaelBuessemeyer wants to merge 1 commit into
MichaelBuessemeyer wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hej! Thanks for the great library — Up until now, we've been using keyboardjs, but now we're migrating to Keystrokes in our project WEBKNOSSOS. Keystrokes is more feature-rich, but we still ran into a behavior issue we'd love to contribute a fix for.
The problem
When a multi-stroke combo and a single-key combo share the same final key, both handlers fire simultaneously. For example, if you have:
bindKeyCombo('ctrl > k, m', () => console.log('long sequence activated'))
bindKeyCombo('m', () => console.log('short sequence activated))
Pressing Ctrl+K then M triggers both handlers. From our point of view, in almost every real-world use case, if the user consciously pressed a prefix chord first, they clearly intend the longer sequence — the shorter one firing is more of an unintended side effect in our opinion.
The fix
After _updateKeyComboStates() resolves which combos are now pressed, we find the maximum sequence length among all currently-pressed combos and only call executePressed on those with the longest sequence. Shorter overlapping combos are silently skipped for that key event.
To make sure release events stay consistent, we track which combos were actually activated per key in a _keyCombosPressedByKey map, and only fire executeReleased on those same combos when the key is lifted.
Changes
If only one combo matches (the common case), pressedCombos has a single entry, and everything flows exactly as before.
If you believe the behavior change introduced by this update should be optional, I’d be happy to adjust the PR accordingly. For example, it could become an option passable to Keystrokes instances.
Of course, other suggestions are welcome as well :)