1. Introduction
Richly interactive web sites, games and remote desktop/application streaming experiences want to provide an immersive, full screen experience. To accomplish this, sites need access to special keys and keyboard shortcuts while they are in full screen mode so that they can be used for navigation, menus or gaming functionality. Some examples of the keys that may be required are Escape, Alt+Tab, Cmd+`, and Ctrl+N.
By default, these keys are not available to the web application because they are captured by the browser or the underlying operating system. The System Keyboard Lock API enables websites to capture and use all available keys allowed by the OS.
2. Activating and Deactivating System Keyboard Lock
partial interface Navigator { [SecureContext] void requestSystemKeyboardLock(optional sequence<DOMString> keyCodes); [SecureContext] void cancelSystemKeyboardLock(); };
The navigator has enable keyboard lock, which is a boolean that is set to true when System Keyboard Lock is enabled. By default, this is set to false.
The navigator has reserved key codes, which is a sequence of DOMStrings, each of which is a valid KeyboardEvent code as defined in [UIEvents-Code]. By default this sequence is empty (which would capture all keys if enable keyboard lock was enabled).
2.1. requestSystemKeyboardLock
When requestSystemKeyboardLock()
is called, the user agent must
run the following steps:
-
Reset reserved key codes to be an empty sequence.
-
If the optional
keyCodes
argument is present, run the following substeps:-
Copy the values from
keyCodes
into reserved key codes, removing any entries which are not valid KeyboardEvent codes or duplicate.
-
-
If enable keyboard lock is currently false, run the following substeps:
-
Set enable keyboard lock to be true.
2.2. cancelSystemKeyboardLock
When cancelSystemKeyboardLock()
is called, the user agent must
run the following steps:
-
If enable keyboard lock is true, then run the following substeps:
-
Set enable keyboard lock to be false.
-
Reset reserved key codes to be an empty sequence.
3. Handling Keyboard Key Presses
3.1. System Key Press Handler
A system key press handler is an platform-specific handler that can be used to filter keys at the platform level. Since System Keyboard Lock feature is intended to provide access to key presses that are not normally made available to the browser (for example, Cmd/Alt-Tab), most platforms will require a special handler to be set up.The system key press handler must have the following properties:
-
It must process key presses before any user agent keyboard shortcuts are handled.
-
Wherever possible, it should process key presses before any system keyboard shortcuts are processed.
3.1.1. Registering
To register a system key press handler, the user agent will need to follow the platform-specific steps to add a low-level hook that will be called whenever the platform begins to process a new key press.
The exact process for adding a system key press handler varies from platform to platform. For examples of how to register a low-level hook to process key presses on common platforms, see [LowLevelKeyboardProc] for Windows, [QuartzEventServices] for Mac OS X and [GrabKeyboard] for X Windows.
Note: If the user agent already has a key press handler registered for another purpose, then it can optionally extend that handler to support the System Keyboard Lock feature (assuming it meets the requirements mentioned above).
3.1.2. Unregistering
To unregister the system key press handler, the user agent will need to follow the platform-specific steps to remove the (previously added) low-level hook for processing new key press.
As with registering system key press handlers, the process for unregistering system key press handlers is also platform-specific. See the references listed in §3.1.1 Registering for more details and examples.
3.2. Handling Keyboard Events
In response to the user pressing a key, if a system key press handler has been registered, it should run the following steps:
-
Let isJsFullscreen be set to true if the user agent is currently in fullscreen mode that was initiated by Element.requestFullscreen() (see [Fullscreen]).
Note: This can be determined by adding a tracking variable in the requestFullscreen() call or by checking to see if Document.fullscreenElement is non-null.
-
Let hasFocus be set to true if the current fullscreen document or element has input focus.
Note: The fullscreen element would not have focus, for example, if there was a system dialog being displayed with focus.
-
If isJsFullscreen, hasFocus and enable keyboard lock are all set to true, then run the following substeps:
-
Let keyEvent be the key event for the new key press.
-
Let code be the value of the
code
attribute of keyEvent. -
If reserved key codes is empty or if code is listed in reserved key codes, then run the following substeps:
-
If code is equal to "Escape", then run the following substeps:
-
Optionally overlay a message on the screen telling the user that they can Hold the Escape key to exit from fullscreen.
-
If the key is held for 2 seconds, then exit from the keyboard handler and pass the key on to the user agent for normal processing (which will exit fullscreen).
-
-
Dispatch keyEvent to the fullsceen document or element.
-
-
Else, handle the key event as it normally would be handled, either by dispatching a key event or performing the usual keyboard shortcut action.
-
Note: It is not required that a conforming implementation be able to override the OS default behaviour for every key combination. Specifically, most platforms have a “secure attention sequence” (e.g., Ctrl-Alt-Del on Windows) that applications cannot override; this specification does not supersede that.
4. Fullscreen Considerations
There are two different types of fullscreen available in modern user agents: JavaScript-initiated fullscreen (via the [Fullscreen] API) and user-initiated fullscreen (when the user enters fullscreen using a keyboard shortcut). The user-initiated fullscreen is often referred to as "F11" fullscreen since that is a common key shortcut used to enter and exit fullscreen mode.
F11 fullscreen and JavaScript (JS) fullscreen do not behave the same way. When a user enters F11 fullscreen, they can only exit it via the same keyboard shortcut that they used to enter it -- the exitFullscreen() function will not work in this case. In addition, fullscreen events that are normally fired for JS fullscreen are not sent for F11 fullscreen.
Because of these differences (and because there is no standard shortcut for F11 fullscreen), the System Keyboard Lock API is only valid when the a JavaScript-initiated fullscreen is active. During F11 fullscreen, no System Keyboard Lock processing of keyboard events will take place.
5. Mobile Device Considerations
What level of support do we need on mobile? Is it enough to say that it’s a keyboard-focused API and mobile devices typically don’t have keyboards? What does Chrome do if you activate full-screen on a mobile web site and hit Escape from an attached keyboard? It seems like that should also be supported.
6. Security Considerations
How does this proposal prevent malicious sites from taking all key events and preventing the user from escaping?
How could this be used (alone or in conjunction with other APIs) to give the user a bad experience?
7. Privacy Considerations
Not applicable. This API does not use or reveal any personal information about the current user.
8. Acknowledgements
Thanks to the following people for the discussions that lead to the creation of this proposal:
Jon Dahlke (Google)