Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Duplicate activation of hotkey if another key event arrives before keyup #1013

Closed
isti115 opened this issue Apr 25, 2023 · 4 comments · Fixed by #1080
Closed

[BUG] Duplicate activation of hotkey if another key event arrives before keyup #1013

isti115 opened this issue Apr 25, 2023 · 4 comments · Fixed by #1080

Comments

@isti115
Copy link

isti115 commented Apr 25, 2023

Describe the bug
If I understand correctly, the current logic behind the activation of a hotkey is roughly as follows:

  • The library keeps track of the currently pressed keys by monitoring keydown and keyup events.
  • On each event the registered hotkeys are checked against the currently pressed keys, and if their modifiers match and all the required keys are currently pressed, the handler fires.

The problem I'm facing arises when multiple keys are pressed in rapid succession. In such situations, when the user's fingers sort of "roll" on the keyboard, it can happen, that the next key is already pressed, before the previous one has been released. In such situations the current matching logic fires the handler of the first key multiple times, as the required conditions are still met when the next keydown event arrives.

I'm not a hundred percent sure what the best approach would be to mitigate the issue, but at least making sure that the key that generated the event in the first place is part of the currently matched hotkey seems like a sensible starting point. If you agree with this, I'll prepare a PR with the required changes.

To Reproduce
Steps to reproduce the behavior:

  1. Go to the provided example
  2. Roll your fingers over the 'asdf' keys quickly
  3. See that some of them are repeated in the output
  4. Press ctrl+b and then the i key as well without lifting up the ctrl and b keys
  5. Observe, that the boldness of the text got toggled twice

Please try and add a codesandbox or stackblitz to reproduce the bug:
https://codesandbox.io/s/react-hotkeys-hook-issue-1013-9hgd71

Expected behavior
I would expect a single press of any given key to result in a single invocation of the assigned handler function, no matter what other keys are pressed before or after.

Desktop (please complete the following information):

  • OS: Linux
  • Browser: Firefox
  • Version: 102

Edit: I have by accident meanwhile stumbled upon #995, because it didn't occur to me to search the discussions as well as the issues before posting this, so this is in some sense a duplicate, but a much more detailed one.

@FelixMalfait
Copy link

Hey @isti115 we've observed the same issue. Did you get any luck trying to fix this?
This bug is pretty annoying so we might work on submitting a PR if you didn't. Appreciate if you have any guidance before we start digging into it :). Thanks a lot

@isti115
Copy link
Author

isti115 commented Sep 21, 2023

I didn't go too far, as we didn't end up using this library, but the following patch was usable as a quick and dirty workaround:

diff --git a/node_modules/react-hotkeys-hook/dist/react-hotkeys-hook.esm.js b/node_modules/react-hotkeys-hook/dist/react-hotkeys-hook.esm.js
index a3896d0..223765a 100644
--- a/node_modules/react-hotkeys-hook/dist/react-hotkeys-hook.esm.js
+++ b/node_modules/react-hotkeys-hook/dist/react-hotkeys-hook.esm.js
@@ -195,6 +195,11 @@ var isHotkeyMatchingKeyboardEvent = function isHotkeyMatchingKeyboardEvent(e, ho
     altKey = e.altKey;
   var keyCode = mapKey(code);
   var pressedKey = pressedKeyUppercase.toLowerCase();
+ 
+  if (!keys.includes(keyCode)) {
+    return
+  }
+
   if (!ignoreModifiers) {
     // We check the pressed keys for compatibility with the keyup event. In keyup events the modifier flags are not set.
     if (alt === !altKey && pressedKey !== 'alt') {

It essentially just prevents events from participating in the firing of callbacks that don't actually have the event's key among their triggers.

@FelixMalfait
Copy link

Thanks a lot @isti115

@JohannesKlauss is that something you would accept merging if I raise a PR? thanks!

@JohannesKlauss
Copy link
Owner

Absolutely. I sadly don't have a lot of time on my hand to contribute much currently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants