Bug 78206 - keydown event is fired once for every millisecond the Esc key is held down
Summary: keydown event is fired once for every millisecond the Esc key is held down
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: UI Events (show other bugs)
Version: 528+ (Nightly build)
Hardware: Mac (Intel) OS X 10.7
: P2 Normal
Assignee: Nobody
URL: http://jsfiddle.net/PLtjN/
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2012-02-08 23:40 PST by Tyson Tate
Modified: 2014-03-10 09:56 PDT (History)
6 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tyson Tate 2012-02-08 23:40:19 PST
Given the following JS:

    document.addEventListener("keydown", function(e) {
        console.log(e);
     });

All keys fire the "keydown" event once for every press, as expected. However, when you press the escape key, the event is fired once for every single millisecond that the escape key is held down. The "keyup" event is properly fired once.

The bug is evident in the latest nightly (r107164) as well as Safari 5.1.3.
Comment 1 Tyson Tate 2012-02-08 23:46:33 PST
Also worth noting, the events don't fire until the escape key is released. So if you press and hold the escape key for 1 second, 1,000 keydown events will fire at the end of that second, when you release the key.
Comment 2 Joseph Pecoraro 2012-03-10 02:09:49 PST
Yah, this is pretty bad!
Comment 3 Joseph Pecoraro 2012-03-10 21:07:54 PST
A workaround would be to call event.preventDefault() in the JavaScript handler.

The duplicate events seems to be caused by the default behavior of the Esc key for a window. WebCore sends a "cancelOperation" up to WebKit and the NSResponder chain to the NSWindow which sends a _cancelKey (Esc key) back down into the page. Here is a UIProcess snippet I took of Safari. Maybe this handling of _cancelKey can be made smarter?

    Breakpoint 1, WebKit::WebPageProxy::handleKeyboardEvent (this=0x7fd3f6804000, event=@0x7fff6fa56d88) Source/WebKit2/UIProcess/WebPageProxy.cpp:971
    971     if (!isValid())
    #0  WebKit::WebPageProxy::handleKeyboardEvent (this=0x7fd3f6804000, event=@0x7fff6fa56d88) Source/WebKit2/UIProcess/WebPageProxy.cpp:971
    #1  0x0000000112d57ea8 in -[WKView performKeyEquivalent:] (self=0x7fd3f5a07900, _cmd=0x7fff8110fac4, event=0x7fd3f44716e0) Source/WebKit2/UIProcess/API/mac/WKView.mm:1229
    #2  0x000000011004a7fd in -[BrowserWKView performKeyEquivalent:] (self=0x7fd3f5a07900, _cmd=0x7fff8110fac4, event=0x7fd3f44716e0)
    #3  0x00007fff809f91a0 in -[NSView _performKeyEquivalent:conditionally:] ()
    #4  0x00007fff809f92ce in -[NSView performKeyEquivalent:] ()
    #5  0x00007fff809f91a0 in -[NSView _performKeyEquivalent:conditionally:] ()
    #6  0x00007fff809f92ce in -[NSView performKeyEquivalent:] ()
    #7  0x00007fff809f91a0 in -[NSView _performKeyEquivalent:conditionally:] ()
    #8  0x00007fff809f92ce in -[NSView performKeyEquivalent:] ()
    #9  0x00007fff809f91a0 in -[NSView _performKeyEquivalent:conditionally:] ()
    #10 0x00007fff809f92ce in -[NSView performKeyEquivalent:] ()
    #11 0x00007fff809f91a0 in -[NSView _performKeyEquivalent:conditionally:] ()
    #12 0x00007fff809f9111 in -[NSWindow performKeyEquivalent:] ()
    #13 0x0000000110554116 in -[Window performKeyEquivalent:] (self=0x7fd3f5b92c60, _cmd=0x7fff8110fac4, event=0x7fd3f44716e0)
    #14 0x00000001100058d9 in -[BrowserWindow performKeyEquivalent:] (self=0x7fd3f5b92c60, _cmd=0x7fff8110fac4, event=0x7fd3f44716e0)
>   #15 0x00007fff80f19699 in -[NSWindow _cancelKey:] ()
    #16 0x00007fff8c6d275d in -[NSObject performSelector:withObject:] ()
    #17 0x00007fff80daf659 in -[NSResponder doCommandBySelector:] ()
    #18 0x00007fff80f1c826 in -[NSWindow doCommandBySelector:] ()
    #19 0x00007fff80daf72b in -[NSResponder doCommandBySelector:] ()
    #20 0x00007fff80daf72b in -[NSResponder doCommandBySelector:] ()
    #21 0x00007fff80daf72b in -[NSResponder doCommandBySelector:] ()
    #22 0x00007fff80daf72b in -[NSResponder doCommandBySelector:] ()
    #23 0x0000000112d60e02 in -[WKView(Internal) _executeSavedCommandBySelector:] (self=0x7fd3f5a07900, _cmd=0x7fff84fe874a, selector=0x7fff8114ca3c) Source/WebKit2/UIProcess/API/mac/WKView.mm:2673
    #24 0x0000000112b0eac0 in WebKit::PageClientImpl::executeSavedCommandBySelector (this=0x7fd3f5a0c510, selectorString=@0x7fff6fa57560) Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm:519
    #25 0x0000000112cb1502 in WebKit::WebPageProxy::executeSavedCommandBySelector (this=0x7fd3f6804000, selector=@0x7fff6fa57560, handled=@0x7fff6fa57558) Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm:375
    #26 0x0000000112cc086f in CoreIPC::callMemberFunction<WebKit::WebPageProxy, void (WebKit::WebPageProxy::*)(WTF::String const&, bool&), WTF::String, bool> (args=@0x7fff6fa57560, replyArgs=@0x7fff6fa57558, object=0x7fd3f6804000, function={ptr = 4610266304, ptr = 0}) at HandleMessage.h:93
    #27 0x0000000112cc02fa in CoreIPC::handleMessage<Messages::WebPageProxy::ExecuteSavedCommandBySelector, WebKit::WebPageProxy, void (WebKit::WebPageProxy::*)(WTF::String const&, bool&)> (argumentDecoder=0x7fd3f7910e50, replyEncoder=0x7fd3f4154770, object=0x7fd3f6804000, function={ptr = 4610266304, ptr = 0}) at HandleMessage.h:307
    ...
Comment 4 Tyson Tate 2012-10-22 11:56:00 PDT
This appears to be fixed in Safari 6.0.1 (8536.26.14). (I don't know if it was fixed earlier, though. Anyways: closing.
Comment 5 olivier.borowski 2012-10-23 00:07:26 PDT
This bug is still not fixed, please reopen it !

Tested on : 
- Safari 6.0.1 (8536.26.14) on 10.8.2
- Safari 5.1.7 (6534.57.2) on 10.6.8
Comment 6 Alexey Proskuryakov 2012-10-23 09:05:32 PDT
Yes, I'm also seeing this in Safari 6.0.1 on OS X 10.8.2.
Comment 7 David Kilzer (:ddkilzer) 2013-02-14 16:28:18 PST
<rdar://problem/10120677>
Comment 8 Alexey Proskuryakov 2013-02-16 10:17:00 PST
http://xkcd.com/1172/
Comment 9 Alexey Proskuryakov 2014-03-10 09:56:36 PDT
This was fixed by <http://trac.webkit.org/changeset/165356>.

Sorry if that broke someone's workflow :-)