Pointer Lock

W3C Working Draft 29 May 2012

This version:
Latest published version:
Latest Editor's Draft:
Vincent Scheib, Google


This specification defines an API that provides scripted access to raw mouse movement data while locking the target of mouse events to a single element and removing the cursor from view. This is an essential input mode for certain classes of applications, especially first person perspective 3D applications and 3D modelling software.

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

A history of changes to this document can be found at http://dvcs.w3.org/hg/pointerlock/log/default/index.html

This document was published by the Web Applications Working Group as the 29 May 2012 First Public Working Draft. This document is intended to become a W3C Recommendation. If you wish to make comments regarding this document, please send them to public-webapps@w3.org (subscribe, archives) with [pointerlock] at the start of the subject header. All feedback is welcome.

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.

Table of Contents

1. Introduction

This section is non-normative.

The Pointer Lock API provides for input methods of applications based on the movement of the mouse, not just the absolute position of a cursor. A popular example is that of first person movement controls in three dimensional graphics applications such as games. Movement of the mouse is interpreted for rotation of the view-port, there is no limit to how far movement can go, and no mouse cursor is displayed.

Pointer Lock is related to Mouse Capture [MDN-SETCAPTURE]. Capture provides continued event delivery to a target element while a mouse is being dragged, but ceases when the mouse button is released. Pointer Lock differs by being persistent, not limited by screen boundaries, sending events regardless of mouse button state, hiding the cursor, and not releasing until an API call or specific release gesture by the user.

Pointer Lock deals with capturing a single resource and relating it to a single element. This is similar to the Fullscreen API [FULLSCREEN], which promotes a single element to be full screen. The Pointer Lock API chooses to pattern the resource capture, state change, and release API as closely as possible after the Fullscreen API.

The Pointer Lock interaction mode was previously referred to as mouse lock. The name was changed as many different controller types besides mice can manipulate the on screen pointing cursor, and they are all impacted.

2. Conformance

As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

The key words must, must not, required, should, should not, recommended, may, and optional in this specification are to be interpreted as described in [RFC2119].

This specification defines conformance criteria that apply to a single product: the user agent that implements the interfaces that it contains.

Implementations that use ECMAScript to implement the APIs defined in this specification must implement them in a manner consistent with the ECMAScript Bindings defined in the Web IDL specification [WEBIDL] as this specification uses that specification and terminology.

A conforming implementation is required to implement all fields defined in this specification.

3. pointerlockchange and pointerlockerror Events

Two events are used to communicate pointer lock state change or an error in changing state. They are named pointerlockchange and pointerlockerror.

User agents must deliver these events by queuing a task to fire an event of the appropriate name with its bubble attribute set to true to the pointer lock target element's node document.

4. Element Interface

The Element interface is extended to provide the ability to request the the pointer be locked.

partial interface Element {
    void requestPointerLock ();

4.1 Methods


Requests that the pointer be locked to a DOM element target. The user agent determines if pointer lock state will be entered and upon lock state change or error must send either a pointerlockchange or pointerlockerror event respectively.

Pointer lock must succeed only if the window is in focus and the user-agent is the active application of the operating system. The target element need not be in focus.

Pointer lock must succeed only if the target is in the DOM tree. If the target is removed from the DOM tree after pointer lock is entered then pointer lock will be lost and a pointerlockchange event sent.

If any element is already locked (including this one) the pointer lock target must be updated to this element and a pointerlockchange event sent.

Once in the locked state the user agent must fire all relevant user generated MouseEvent events (for example: mousemove, mousedown, mouseup, click, wheel)[DOM-LEVEL-3-CORE] to the target of pointer lock, and not fire mouse events to other elements. Events that require the concept of a mouse cursor must not be dispatched (for example: mouseover, mouseout, drag, drop).

In the locked state the system mouse cursor must be hidden. Movement and button presses of the mouse must not cause the window to lose focus.

Synthetic mouse events created by application script act the same regardless of lock state.

No parameters.
Return type: void

5. Extensions to the Document Interface

partial interface Document {
    readonly attribute Element pointerLockElement;
    void exitPointerLock ();

5.1 Attributes

pointerLockElement of type Element, readonly

Returns the element set as the target for mouse events while the pointer is locked. Null if unlocked.

5.2 Methods


Initiates an exit from pointer lock state if currently locked, and sends a pointerlockchange event when the lock state has bene exited.

The system mouse cursor must be displayed again and positioned at the same location that it was when pointer lock was entered (the same location that is reported in screenX/Y when the pointer is locked).

No parameters.
Return type: void

6. Extensions to the MouseEvent Interface

User agents must extend the MouseEvent interface [DOMMOUSE] with two members:

partial interface MouseEvent {
    readonly attribute long movementX;
    readonly attribute long movementY;

6.1 Attributes

movementX of type long, readonly
movementY of type long, readonly

The members movementX and movementY must provide the change in position of the pointer, as if the values of screenX/Y were stored between two subsequent mousemove events eNow and ePrevious and the difference taken movementX = eNow.screenX-ePrevious.screenX.

movementX/Y must be valid regardless of pointer lock state.

When unlocked, the system cursor can exit and re-enter the user agent window. If it does so and the user agent was not the target of operating system mouse move events then the most recent pointer position will be unknown to the user agent and movementX/Y can not be computed and must be set to zero.

When pointer lock is enabled clientX, clientY, screenX, and screenY must hold constant values as if the pointer did not move at all once pointer lock was entered. But movementX/Y must continue to provide the change in position of the pointer as when the pointer is unlocked. There will be no limit to movementX/Y values if the mouse is continuously moved in a single direction. The concept of the mouse cursor will have been removed, and it will not move off the window or be clamped by a screen edge.

7. Requirements

The Pointer Lock API must provide a default system action to unlock the pointer.

The Pointer Lock API must be agnostic to the underlying system-specific pointer locking mechanism.

The Pointer Lock API must exit the pointer lock state if the user agent, window, or tab loses focus.

8. Use Cases

This section is non-normative.

8.1 Relative view-port rotation of free moving virtual actors

A player on a first/third person game will need to control the view-port orientation. A widely used method is the use of mouse movements to control the viewing angle. This kind of application can use the Pointer Lock API to allow a complete freedom of control over the viewport's yaw and pitch even when the user is not pressing mouse buttons. Those buttons can be used for other actions while constantly providing navigation via mouse movement.

8.2 Free rotation of 3D models or panning of 2D layers

Users of a three dimensional modeling application will need to rotate models. A application can use the Pointer Lock API to enable the author to rotate the model freely in a drag operation without limiting motion. Without pointer lock a drag would stop providing motion data when the mouse cursor is limited by the edge of the screen.

Similarly, absolute motion panning of a large two dimensional image could be permitted in a single drag operation without cursor / screen limits.

8.3 Relative movement of actors

A player on a fast reflexes game controls a paddle to bounce back a ball to the opponent, while allowing the same paddle to execute actions based on different mouse buttons being pressed. The application can use the Pointer Lock API to allow the player to react quickly without being concerned about the mouse cursor leaving the game play area and clicking another system application, thus breaking the game flow.

8.4 Jog movement over spinner controls

When modifying numerically magnitudes in applications sometimes the user will prefer to "drag" a numeric control by its button handles to increment or decrement the numeric value. E.g. a spinner with a number entry text box and arrows pointing up and down that can be clicked or dragged on to change the value. An application could use the Pointer Lock API to allow modifying the numeric values beyond what the logical screen bounds allow. The same could apply for a control that fast forwards or rewinds a video or audio stream like a "jog".

8.5 Synthetic cursor interaction with HTML DOM UI

Some games use a classical cursor, however they want it to be limited or controlled in some manner. E.g. limited to the bounds of the game, or movable by the game. Locking the pointer enables this if the application creates their own cursor. However HTML and DOM should still be available to use for user interface. Synthetic mouse events should be permitted to allow an application defined cursor to interact with DOM. E.g. the following code should permit a custom cursor to send click events while the pointer is locked:

document.addEventListener("click", function (e) {
  if (e._isSynthetic)
  // send a synthetic click
  var ee = document.createEvent("MouseEvents");
  ee._isSynthetic = true;
  x = myCursor.x;
  y = myCursor.y;
  ee.initMouseEvent("click", true, true, null, 1,
                    x + e.screenX - e.clientX,
                    y + e.screenY - e.clientY,
  var target = document.elementFromPoint(x, y)
  if (target)

Note that synthetic clicks may not be permitted by a user agent to produce the same default action as a non-synthetic click. However, application handlers can still take action and provide user interface with existing HTML & DOM mechanisms.

8.6 View-port panning by moving a mouse cursor against the bounds of a view-port.

Real Time Strategy games often use this technique. When the player moves the pointer to the view-port borders, if they "push" the border with a mouse movement, the view-port is panned over the game area according to how much they move the mouse. When moving the mouse cursor within the bounds of the view port it acts at is typically would on a system. Applications may choose to implement this using pointer lock and the previous use case of "Synthetic cursor interaction with HTML DOM UI" to bring cursor behavior completely under their control.

8.7 Game Lobby, timer based pointer lock

Games that use pointer lock may desire a traditional UI and system cursor while players prepare in a game lobby. Games usually start after a short timer when all players are ready. Ideally the game could then switch to pointer lock mode without requiring a user gesture. Players should be able to seamlessly move from the game lobby into game navigation.

8.8 Game Portal

Game portals, and other sites such as Facebook and Google Plus, host games for users to play. These games may be hosted and served from a different origin from that of the portal site. Embedded games should be able to lock the pointer, even in non-full screen mode.

9. Security

This section is non-normative.

Security Concerns:



pointer lock is a required user interaction mode for certain application types, but carries a usability concern if maliciously used. An attacker could remove the ability for a user to control their mouse cursor on their system. User agents will prevent this by always providing a mechanism to exit pointer lock, by informing the user of how, and by limiting how pointer lock can be entered.

User agents will determine their own appropriate policies, which may be specialized per device or differ based on user options. The following discussion illustrates considerations and plausible implementations.

Escape from pointer lock must always be possible.
Based on device the mechanisms will vary, but obvious examples include the keyboard escape key "Esc" and any control that moves the system focus away from the web page (window management keystrokes that change windows, operating system buttons such as the Windows key).
Escape instructions may be communicated.
User agents can provide persistent on screen instructions, or transitory instructions when pointer lock is entered. If users are particularly dissatisfied with the distraction of instructions user agents may offer to hide instructions after sufficient intent is expressed, e.g. by permissions.
Escape can not be performed by mouse actions, including the use of the context menu.
The intent of the pointer lock feature is to enable rich applications not currently available in browsers. These applications have unbounded movement and button press consumption needs, including the use of the context menu.

Examples of user agent scenarios:

A conservative approach
May only permit pointer lock based on a user gesture such as a click event. The user agent would prompt the user with a confirmation dialog, with options to permit, dismiss, or block all repeated attempts. That dialog may be a passive display instead of modal. Instructions for escape would be provided. After acceptance, a succinct reminder notice of escape instructions may persist. In the extreme, a user agent may require the user to perform an uncommon gesture demonstrating that they understand the escape gesture, e.g. by pressing F10.
A full screen approach
May permit pointer lock at any time, and cancel pointer lock when full screen mode is exited. Instructions for exiting full screen mode may be shown, likely for a brief period of time to not detriment the full screen experience. Entry to pointer lock may be gated by a user explicitly confirming the action via a dialog.
A permissive approach
May permit pointer lock for the target or ancestor of a user gesture target without prompt. Escape instructions would likely be displayed persistently in a non full screen view.

Chrome / Chromium has a design document page for their implementation of pointer lock: http://www.chromium.org/developers/design-documents/mouse-lock

10. Frequently Asked Questions

This section is non-normative.

10.1 Why not merge with Mouse Capture: setCapture()?

Mouse Capture [MDN-SETCAPTURE] handles low security risk mouse event target lock for the duration of a mouse drag gesture. pointer lock removes the concept of the cursor and directs all events to a given target. They are related, but different.

If a browser implemented both, it would be reasonable to support a combination of traits: The security simplicity of "automatically release lock when mouse up" and the increased functionality of total control over mouse input and removal of the system cursor. The security trait would allow more permissive use of the feature for applications that only required a short burst of pointer lock during a drag event.

This functionality is omitted from the initial version of this spec because it helps the minor use cases in windowed mode but we still do not have an implementation solving the major ones. And, to implement this a browser must implement both, which none does yet. It is not clear if this feature should live on .lock or on .setCapture. If both were implemented, either API could be augmented fairly easily to offer the hybrid functionality.

10.2 Why not repurpose MouseEvent's .clientX/Y .screenX/Y?

Even in non locked state, the delta values of mouse movement are useful. Changing the meaning of .client or .screen based on lock state would also cause easy errors in code not carefully monitoring the lock state.

10.3 Why use .movementX/Y instead of .deltaX/Y?

When the pointer is locked 'wheel' events should be sent to the pointer lock target element just as 'mousemove' events are. There is a naming conflict with .deltaX/Y/Z as defined in DOM 3 'wheel' event.

10.4 Why bundle all functionality (hiding cursor, providing mouse deltas) instead of using CSS to hide the cursor, always providing delta values, and offering an API to restrict the cursor movement to a portion of the web page?

There are good motivations to provide a more fine grained approach. E.g. the use case "View-port panning by moving a mouse cursor against the bounds of a view-port" doesn't require hiding the mouse cursor, only bounding it and always having delta values available. Also, this specification defines the movement deltas to be taken from how the system mouse cursor moves, which incorporates operating system filtering and acceleration of the mouse movement data. Applications may desire access to a more raw form of movement data prior to adjustments appropriate for a mouse cursor. Also, raw data may provide better than pixel level accuracy for movement, as well as higher frequency updates. Providing the raw delta movement would also not require special permission or mode from a user, and for some set of applications that do not require bounding the cursor may reduce the security barriers and prompts needed.

There are two justifications for postponing this finer grained approach. The first is a concern of specifying what units mouse movement data are provided in. This specification defines .movementX/Y precisely as the same values that could be recorded when the mouse is not under lock by changes in .screenX/Y. Implementations across multiple user agents and operating systems will easily be able to meet that requirement and provide application developers and users with a consistent experience. Further, users are expected to have already configured the full system of hardware input and operating system options resulting in a comfortable control the system mouse cursor. By specifying .movementX/Y in the same units mouse lock API applications will be instantly usable to all users because they have already settled their preferences.

Secondly, the implementation of providing movement data and bounding the mouse cursor is more difficult in the fine grained approach. Bundling the features together gives implementations freedom to use a variety of techniques as appropriate on each operating system and is more practical to implement. Direct APIs do not exist on all platforms (Win, Mac, Linux) to bound the cursor to a specific rectangle, and prototypes have not yet been developed to demonstrate building that behavior by e.g. invisible windows with xlib or manual cursor movement on Mac. Unaccelerated Delta values have been proposed to be accessed by reading raw Human Interface Device (HID) data. E.g. WM_INPUT messages on windows, and USB device APIs on Mac / Linux. The challenge here is interpreting and normalizing the units to some consistent and specifiable scale. Also, most APIs considered to date are limited to USB devices.

It would be reasonable to consider adding these capabilities in the future, as the currently specified pointer lock API would be easy to continue to support if the finer grained delta and confinement features were implemented.

The bundled API is selected for implementation practicality, because the desired use cases are supported, and because it will not conflict with future improvements as discussed here.

10.5 High resolution deltas / High frequency updates?

Not yet, for the same reasons in the previous Q. See "Why bundle all functionality (hiding cursor, providing mouse deltas) instead of using CSS to hide the cursor, always providing delta values, and offering an API to restrict the cursor movement to a portion of the web page?" above.

10.6 Why modify MouseEvent and reuse existing mouse events instead of creating a mouse delta event?

When under pointer lock many mouse events remain relevant, e.g. click, mousedown, etc. These all share the same event data structure MouseEvent. If movement data were reported via a new data structure then a new event would be needed for reporting delta movement. The new data structure would have many parallels to MouseEvent to offer the same conveniences, e.g. button and modifier key states. When handling click, down, and up events would the existing mousedown, mouseup be used? If so, they would provide .clientX/Y and .screenX/Y with no useful data, but would lack the convenience of containing the current movement data. Or, new events would also be required for when the mouse is locked.

Also, movementX/Y are convenient even when the mouse is not locked. This spec requires movement members to always be valid, even when the mouse cursor exists. This reduces code required to track the last cursor state and mouseover/mouseout transitions if applications wish to make use of delta motion of the mouse.

The only negative of adding movementX/Y to MouseEvent appears to be the unused values in clientX/Y and screenX/Y when under pointer lock. This does not seem to be a significant problem.

Therefore the minimal change to add movementX/Y to MouseEvent is selected to reduce API and implementation complexity.

10.7 Why separate targets for mouse events under pointer lock and keyboard input focus?

Consider a game with a 3D view controlled by moving the mouse cursor, while the user may still chat with other users via a text console. It is reasonable for the application to accept text input to an element that is different than where mouse events are being dispatched. This is similar to pre-existing behavior of receiving mousemove events over any element while typing into a form on a page.

A. Acknowledgements

This section is non-normative.

Many have made contributions to the discussions of this specification:

Please let me know if I have inadvertently omitted your name.

B. References

B.1 Normative references

Gavin Nicol; et al. Document Object Model (DOM) Level 3 Core Specification. 7 April 2004. W3C Recommendation. URL: http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Internet RFC 2119. URL: http://www.ietf.org/rfc/rfc2119.txt
Cameron McCormack. Web IDL. 27 September 2011. W3C Working Draft. (Work in progress.) URL: http://www.w3.org/TR/2011/WD-WebIDL-20110927/

B.2 Informative references

Anne van Kesteren. The Fullscreen API. 4 January 2012. W3C Editor's Draft. (Work in progress.) URL: http://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
Shepherd, Eric; et. al. element.setCapture 12 Nov 2010. Mozilla Developer Network. URL: https://developer.mozilla.org/en/DOM/element.setCapture