W3C

System Keyboard Lock

W3C Working Draft,

This version:
https://www.w3.org/TR/2016/WD-systemkeylock-20161213/
Latest published version:
http://www.w3.org/TR/systemkeylock/
Editor's Draft:
https://github.com/w3c/systemkeylock/
Previous Versions:
<none>
Issue Tracking:
GitHub
Inline In Spec
Editors:
(Google)
(Google)

Abstract

This specification defines an API that allows websites to capture keys that are normally reserved by the underlying host operating system. It is intended to be used by web applications that provide a fullscreen immersive experience (like games or remote access apps).

Status of this document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

The management and production of this document follows a relatively complex setup. Details are provided as part of the introduction.

This document was published by the Web Platform Working Group as a Working Draft. Feedback and comments on this specification are welcome. Please use Github issues Historical discussions can be found in the public-webapps@w3.org archives.

Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

This document is governed by the 1 September 2015 W3C Process Document.

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:

  1. Reset reserved key codes to be an empty sequence.

  2. If the optional keyCodes argument is present, run the following substeps:

    1. Copy the values from keyCodes into reserved key codes, removing any entries which are not valid KeyboardEvent codes or duplicate.

  3. If enable keyboard lock is currently false, run the following substeps:

    1. Register a system key press handler.

    2. Set enable keyboard lock to be true.

2.2. cancelSystemKeyboardLock

When cancelSystemKeyboardLock() is called, the user agent must run the following steps:

  1. If enable keyboard lock is true, then run the following substeps:

    1. Unregister the system key press handler.

    2. Set enable keyboard lock to be false.

    3. 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:

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:

  1. 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.

  2. 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.

  3. If isJsFullscreen, hasFocus and enable keyboard lock are all set to true, then run the following substeps:

    1. Let keyEvent be the key event for the new key press.

    2. Let code be the value of the code attribute of keyEvent.

    3. If reserved key codes is empty or if code is listed in reserved key codes, then run the following substeps:

      1. If code is equal to "Escape", then run the following substeps:

        1. Optionally overlay a message on the screen telling the user that they can Hold the Escape key to exit from fullscreen.

        2. 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).

      2. Dispatch keyEvent to the fullsceen document or element.

    4. 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)

Index

Terms defined by this specification

Terms defined by reference

References

Normative References

[HTML]
Ian Hickson. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[UIEVENTS]
Gary Kacmarcik; Travis Leithead. UI Events. 4 August 2016. WD. URL: https://www.w3.org/TR/uievents/
[UIEvents-Code]
Gary Kacmarcik; Travis Leithead. UI Events KeyboardEvent code Values. 24 October 2016. WD. URL: https://www.w3.org/TR/uievents-code/
[WebIDL]
Cameron McCormack; Boris Zbarsky; Tobie Langel. Web IDL. 15 September 2016. WD. URL: https://www.w3.org/TR/WebIDL-1/

Informative References

[Fullscreen]
Anne van Kesteren. Fullscreen API Standard. Living Standard. URL: https://fullscreen.spec.whatwg.org/
[GrabKeyboard]
X11 GrabKeyboard API. URL: https://www.x.org/releases/X11R7.7/doc/xproto/x11protocol.html#requests:GrabKeyboard
[LowLevelKeyboardProc]
LowLevelKeyboardProc documentation on MSDN. URL: https://msdn.microsoft.com/en-us/library/windows/desktop/ms644985(v=vs.85).aspx
[QuartzEventServices]
Quartz Event Services. URL: https://developer.apple.com/reference/coregraphics/1658572-quartz_event_services

IDL Index

partial interface Navigator {
  [SecureContext] void requestSystemKeyboardLock(optional sequence<DOMString> keyCodes);
  [SecureContext] void cancelSystemKeyboardLock();
};

Issues Index

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.
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?