dmauro / Keypress

A keyboard input capturing utility in which any key can be a modifier key.
http://dmauro.github.io/Keypress/
Apache License 2.0
3.18k stars 313 forks source link

key_up not fired if focus changes #84

Open beauwest opened 9 years ago

beauwest commented 9 years ago

So I have a bit of a weird issue that took me forever to track down. The use case is this:

  1. I'm focused on an element that has hotkeys, in this case "enter" to select the item.
  2. When the item is selected, a new element is created that takes the focus. (newElement.focus())
  3. When complete with the new element, we close it with Escape.
  4. Focus comes back to the original element.

This works great, except in one circumstance. If the new element takes focus before the keyup event happens, the Keypress._keys_down array still shows that there is a key pressed! This causes issues for any other hotkeys that have is_solitary set to true.

Clear as mud?

The solution that I have implemented is, when the original element gets a regular blur event. I call listener.blur_event() which clears the array for when I come back to it.

If you need me to clarify further, or if there are any questions, please let me know!

beauwest commented 9 years ago

To clarify, I'm not sure that this is something that can, or should be fixed without radically changing the behavior of Keypress.js. Someone much smarter than me will have to think it through.

dmauro commented 9 years ago

If you take a look at the source file, you'll see I had something similar for handling the user alt+tabbing:

        @blur_event = attach_handler window, "blur", =>
            # Assume all keys are released when we can't catch key events
            # This prevents alt+tab conflicts
            for key in @_keys_down
                @_key_up key, {}
            @_keys_down = []

I wrote that back in the 1.0 version before you could bind to any object, so I think if I just change that 'window' to the element we are bound to, it should work. It's slightly buggy though since you could still have that key held down when coming back, but I think it will handle most use cases.

Thanks for catching this!

beauwest commented 9 years ago

Yeah, I did see that, and I'm manually calling that function blur_event() when the element gets blurred. However, would that work in every case? In the same web app, I have an instance where I do something similar to alt+tabbing inside the browser window. It cycles through elements. And when each element is cycled to, it gains focus.

If blur_event was added to the element your listener is bound to, bubbling wouldn't work as expected. At least I think it wouldn't.

I really think that this is a pretty obscure corner case, I mean, I'd love to see it fixed, but I think a lot of other scenarios would break if blur_event was called whenever the element we are bound to is blurred.

I could be crazy though.