Skip to content

Hold key sticking problem

Jemmin Chang edited this page Jul 22, 2017 · 6 revisions

Definition: the hold key sticks

We say that the hold key sticks when the user uses a built-in hotkey to switch to another tab and subsequently releases the hold key, but the current tab (and the rest of the tabs, generally) continues to act as if the hold key is pressed. The phenomenon was observed early on and its investigation was documented thoroughly in #15, but a lot of wrong hypotheses have been proposed and disproved, so we created this page to hold the most current hypotheses and conclusions, minimal tests, and history of this surprisingly complex and annoying behavior.

Status

Given the complexity of sticking behavior discovered so far, it is probably better to move towards the solution proposed by Roger on #15, as long as a reasonable default hold key choice for each OS can be found.

Important properties of the sticking problem

  1. Its behavior varies by choice of hold key
  2. Its behavior varies by OS/version of Chrome (at least between Ubuntu Chrome vs. Mac OS X Chrome, observed so far)
  3. Its behavior is sometimes affected not just by the use pattern of the hold key, but the use of other keys as well; for this reason, tests and investigation should minimize keyboard use (open new tabs with the mouse, select an address with the mouse, etc.) as much as possible

Current hypothesis

Before you consider updating this section, be sure to record your new findings/data and why previous hypotheses were wrong in the history section.

The hold key sticks when, after using a hotkey to switch to a different tab (either left-right navigation or tab close) and then releasing the hold key, the tab switched to fails to recognize a keyup event for the hold key due to browser rules applying to the particular history of previous key events on the tab. This general principle plays out in several different ways depending on the hold key and OS; see below for details about specific hold key/OS combinations. The minimal tests and results show the basic differences with simple examples, but don't reveal all the nuances -- more sophisticated test cases are needed for that.

Mac OS X (Chrome 59.0.3071.115 64-bit; JS V8 5.9.211.38)

Escape

Escape exhibits the strangest and most complex behavior of the hold key alternatives (only on Mac though). A keyup event for the escape key is only recognized if there has been a keydown event for escape previously (with no keyup of escape between them). Intuitively, the rationale for such behavior is understandable: you shouldn't be able to produce a keyup without a preceding keydown, and perhaps Chrome wants to prevent "splitting" the keydown and keyup between different pages (in case websites assume any key press will involve a keydown and keyup of the key on the page, maybe?). Note, however, that key presses in between the keydown of escape and the keyup we want to recognize do not interfere with the keyup being recognized. So, for example, if I press the hold key on tab A and navigate to tab B with the left-right navigation hotkey, then click to switch back to tab A, press 'a' three times, click to switch back to tab B, then use the left-right navigation hotkey to switch to tab A, we see that the escape keyup is recognized and the hold key does not get stuck on tab A, because of the preceding escape keydown, even though there were keydowns/keyups of 'a' in between.

Note that "extra" accumulated keydowns do not make a difference. You can accumulate as many unmatched keydowns on tab A as you want (whether by holding the key to get repeated keydown events or actually navigating away from the tab with left-right navigation several times), but when you switch to tab A with left-right navigation and release the hold key, that keyup will be recognized but succeeding ones will not (unless you get another keydown on tab A before the next keyup).

Also note that refreshing a tab does not erase its history of key events; if the tab had an unmatched keydown before the refresh, it will still have it "in the bank" to allow recognition of a keyup.

Control

Control exhibits similar behavior to escape, but less strict such that it generates less hold key sticking. Instead of requiring a control keydown after the last control keyup to recognize a control keyup, it only requires a control keydown at any point in the tab's history. As with escape, refresh does not erase the tab's key event history. In practice this makes control a pretty reasonable choice of hold key on Mac, as sticking can only occur when switching to very new tabs.

Cmd

The behavior here is very strange. It passes the basic test, but if the new tab is opened in step 3 using the Cmd+t shortcut instead of clicking, the hold key gets stuck. TODO: Further investigation needed to understand the behavior pattern here and why it occurs.

Ubuntu 16.04 (Chrome 59.0.3071.115 64-bit; JS V8 5.9.211.38)

Escape

On Ubuntu, Escape does not exhibit the same requirement of a preceding keydown to recognize keyups. It therefore makes a pretty good hold key choice on Ubuntu. However, it does get stuck in at least one situation: when you've opened a new tab with the browser shortcuts ctrl+t or ctrl+shift+t (open last closed tab), then try to navigate to the previous tab using left-right navigation or tab close (this can be observed by performing the variant on the basic test mentioned in the Mac Cmd section above). The current hypothesis is that the use of the browser shortcut causes a ctrl keydown to be registered on the original tab, and the escape keyup isn't recognized when switching back to this tab because it is "expecting" a ctrl keyup. This is supported by performing the same variant test mentioned, but before navigating to the left tab with the hotkey, click to switch to the left tab, press and release ctrl once, then click to switch back to the right tab; we observe that the hold key doesn't get stuck with this extra step, presumably because the ctrl key press satisfies the "expected" ctrl keyup.

TODO: Complete investigation of sticking behavior for all hold key choices on all OS.

Minimal tests and results

Basic left-right navigation on two fresh tabs test

This is a useful minimal test to run which demonstrates the varying behavior of the problem with different hold keys and OS Chrome versions. Note carefully the warning in properties to avoid extraneous keyboard use as much as possible when executing the test. Also be sure to disable all other extensions for consistency.

  1. Quit Chrome completely.
  2. Open Chrome.
  3. Go to https://www.google.com.
  4. Click to open a new tab; go to https://www.google.com in it as well.
  5. Press and hold the hold key.
  6. While still holding the hold key down, press [ to navigate to the left tab.
  7. Wait a few seconds, then release the hold key.
  8. Results (tested at commit 77185):
Hold key Mac OS X (Chrome 59.0.3071.115 64-bit; JS V8 5.9.211.38) Ubuntu 16.04 (Chrome 59.0.3071.115 64-bit; JS V8 5.9.211.38) Windows 7 (Chrome 59.0.3071.115 64-bit; JS V8 5.9.211.38)
Escape Hold key gets stuck WAI (not stuck) WAI (not stuck)
Control Hold key gets stuck WAI (not stuck) WAI (not stuck)
Option/alt N/A because of bug WAI (not stuck) WAI (not stuck)
Cmd/Windows key WAI (not stuck) WAI (not stuck) WAI (not stuck)
Context menu key (non-Mac only) N/A WAI (not stuck) WAI (not stuck)
  1. (Optional additional step:) Press and hold the hold key; press ] to navigate to the right tab; wait a few seconds, then release the hold key. Results:
Hold key Mac OS X (Chrome 59.0.3071.115 64-bit; JS V8 5.9.211.38) Ubuntu 16.04 (Chrome 59.0.3071.115 64-bit; JS V8 5.9.211.38) Windows 7 (Chrome 59.0.3071.115 64-bit; JS V8 5.9.211.38)
Escape WAI (not stuck) WAI (not stuck) WAI (not stuck)
Control WAI (not stuck) WAI (not stuck) WAI (not stuck)
Option/alt N/A because of bug WAI (not stuck) WAI (not stuck)
Cmd/Windows key WAI (not stuck) WAI (not stuck) WAI (not stuck)
Context menu key (non-Mac only) N/A WAI (not stuck) WAI (not stuck)

Option bug on Mac

The original commit introducing hold key customization was only tested on Ubuntu before pushing, so we failed to realize that the option key as hold key on Mac actually doesn't work, because it causes the e.key value for any keys pressed with it to be different from their normal value (e.g. a becomes an accented character, etc.), including the built-in left-right nav hotkeys, so this test can't be performed with option as the hold key. This bug is documented in the discussion on #1.

History

The earliest recorded history of the problem and its investigation (before July 21, 2017) is on #15, but note that most of the early hypotheses were wrong and the tests performed/data gathered were incomplete and misleading. Of course, reading through the history is still useful for getting a better understanding of the problem and what has already been tested and tried.

If you update this wiki page, briefly describe any new findings and changes in hypotheses (particularly why the previous ones were wrong) in this section for the sake of having a complete history to aid in further investigation (in addition to updating the current hypothesis of course).

How to explore further

Further exploration is not recommended, as we will likely move towards a different implementation of hold key persistence that avoids this problem entirely; see status. But if you still want to look into it more for fun, see the tips below.

Note that since the hold key indicator visual overlay was introduced in 54c61, it's much easier to detect when the hold key has stuck, since the visual on any given tab indicates whether that tab currently considers the hold key to be pressed. (In fact, the hold key indicator was first conceived and implemented as a pseudo-solution to the sticking problem, when we had given up on finding a real solution.) Before you go plunging down the rabbit hole investigating this problem further, be sure you know its storied history well and have taken note of the properties that make its behavior so infuriatingly complex.