You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -45,8 +43,8 @@ This proposal builds on earlier work by Chromium engineers, which explored event
45
43
### Input frame:
46
44
Each input frame refers to a single timestamped update of a gamepad’s state, typically derived from a HID (Human Interface Device) report, including all button and axis values at that moment in time.
47
45
48
-
### RawGamepadInputChange event:
49
-
An event that represents a snapshot of a gamepad’s state at the moment a new input frame is received from the gamepad device. Each event corresponds to a full input report (e.g., a HID report) and contains the complete state of all buttons, axes. This event enables applications to react to input in a timely, event-driven manner, as an alternative to polling via navigator.getGamepads().
46
+
### The `gamepadrawinputchanged` event:
47
+
An event that represents a snapshot of a gamepad’s state at the moment a new input frame is received from the gamepad device. Each event corresponds to a full input report (e.g., a HID report) and contains the complete state of all buttons and axes. This event enables applications to react to input in a timely, event-driven manner, as an alternative to polling via `navigator.getGamepads()`.
- navigator.getGamepads() returns a snapshot of all connected gamepads.
85
-
- The polling loop is driven by `requestAnimationFrame`, typically around 60Hz (matching display refresh rate), which is much lower than the internal OS poll rate (eg., 250Hz). This mismatch can result in missed input updates, making the 60Hz rate insufficient for latency-critical applications like cloud gaming.
82
+
-`navigator.getGamepads()` returns a snapshot of all connected gamepads.
83
+
- The polling loop is driven by `requestAnimationFrame()`, typically around 60Hz (matching display refresh rate), which is much lower than the internal OS poll rate (eg., 250Hz). This mismatch can result in missed input updates, making the 60Hz rate insufficient for latency-critical applications like cloud gaming.
86
84
87
85
## Goals
88
86
@@ -94,38 +92,42 @@ Reduce input latency by moving away from constant polling and introducing event-
94
92
95
93
- Additionally, this proposal does not currently address input alignment or event coalescing. Prior work on high-frequency input APIs, particularly the Pointer Events API has demonstrated the importance of these mechanisms for latency-sensitive use cases. For instance, the [`pointerrawupdate`](https://developer.mozilla.org/en-US/docs/Web/API/Element/pointerrawupdate_event) event was introduced to provide low-latency input delivery, and it is complemented by the [`getCoalescedEvents()`](https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/getCoalescedEvents) method, which exposes intermediate pointer updates that occur between animation frames. Together, these features help align input processing with rendering, improving visual smoothness and reducing jitter.
96
94
97
-
In contrast, this proposal for `rawgamepadinputchange` intentionally omits alignment and coalescing in its initial design. At this stage, we've intentionally scoped this proposal to deliver immediate, per-HID-report events without adding alignment or coalescing mechanisms. This is both to reduce complexity up front and to validate the value of the raw event model for latency-sensitive use cases.
95
+
In contrast, this proposal for `gamepadrawinputchanged` intentionally omits alignment and coalescing in its initial design. At this stage, we've intentionally scoped this proposal to deliver immediate, per-HID-report events without adding alignment or coalescing mechanisms. This is both to reduce complexity up front and to validate the value of the raw event model for latency-sensitive use cases.
98
96
99
97
That said, we recognize that high-frequency gamepad inputs could eventually require similar treatment to pointer events. This proposal is intended as a foundational step, and we explicitly leave room for future evolution. For further background, we recommend reviewing [prior discussions on event-driven gamepad APIs](https://github.com/w3c/gamepad/issues/4#issuecomment-894460031).
100
98
101
99
## Proposed approach
102
-
### `rawgamepadinputchange` event
103
-
To address the challenges of input latency, this proposal introduces a new event-driven mechanism: the `rawgamepadinputchange` event. This event fires directly on the [Gamepad](https://w3c.github.io/gamepad/#dom-gamepad) object and delivers real-time updates for each input frame, eliminating the need for high-frequency polling. The `rawgamepadinputchange` event includes detailed information about the state of the gamepad at the moment of change.
100
+
101
+
To address the challenges of input latency, this proposal introduces a new event-driven mechanism: the `gamepadrawinputchanged` event. This event fires directly on the window global object. The `gamepadrawinputchanged` event includes detailed information about the state of the gamepad at the moment of change.
104
102
105
103
### Event properties
104
+
-`gamepad`: A read-only [Gamepad](https://developer.mozilla.org/en-US/docs/Web/API/Gamepad) object that is a snapshot of the gamepad’s state at the moment the input was received. It includes all axes, buttons, ID, index, and timestamp.
105
+
106
106
-`axesChanged` and `buttonsValueChanged`: Arrays of indices indicating which axes or button values changed since the last event.
107
107
108
108
-`buttonsPressed` and `buttonsReleased`: Indices of buttons whose pressed state transitioned (from pressed to released or vice versa).
109
109
110
-
-`gamepadSnapshot`: A frozen (read-only) snapshot of the gamepad’s state at the moment the input was received. It includes all axes, buttons, ID, index, and timestamp, and does not update after the event is dispatched.
110
+
-`touchesChanged` : An array of indices indicating which touch-sensitive controls changed since the last input frame.
111
+
- Some modern controllers include capacitive or touch-sensitive surfaces (e.g., DualShock 4 touchpad, Steam Controller trackpads). Each index in `touchesChanged` corresponds to an entry in the `gamepad.touches` array and reports which touch points or surfaces changed state (position, or touch presence).
111
112
112
-
These properties, `axesChanged`, `buttonsPressed`, `buttonsReleased`, and `buttonsValueChanged` properties are arrays of indices and follow the same indentification model as the [Gamepad.axes](https://w3c.github.io/gamepad/#dom-gamepad-axes) and [Gamepad.buttons](https://w3c.github.io/gamepad/#dom-gamepad-buttons) arrays.
113
+
These properties, `axesChanged`, `buttonsPressed`, `buttonsReleased`, `buttonsValueChanged`and ` touchesChanged` properties are arrays of indices and follow the same identification model as the [Gamepad.axes](https://w3c.github.io/gamepad/#dom-gamepad-axes) and [Gamepad.buttons](https://w3c.github.io/gamepad/#dom-gamepad-buttons) arrays.
113
114
114
-
### Event behavior
115
-
Dispatched on the Gamepad Object: The rawgamepadinputchange event is dispatched on the Gamepad object that experienced the input change. This Gamepad instance is accessible via the event's [`target`](https://developer.mozilla.org/en-US/docs/Web/API/Event/target) property and represents a live object that reflects the current state of the device.
115
+
### Event timing
116
116
117
-
Real-Time Updates: A new rawgamepadinputchange event is dispatched for every gamepad input state change, without delay or coalescing. This enables latency-sensitive applications, such as rhythm games, cloud gaming, or real-time multiplayer scenarios, to respond immediately and accurately to input.
117
+
A new `gamepadrawinputchanged` event is dispatched for every gamepad input state change, without delay or coalescing. This enables latency-sensitive applications, such as rhythm games, cloud gaming, or real-time multiplayer scenarios, to respond immediately and accurately to input
118
118
119
-
Gamepad Snapshot: The event also provides a `gamepadSnapshot` property which captures the input state at the exact time the event was generated - corresponding to the moment indicated by the HID input report's timestamp. This ensures that applications can reliably determine the exact state that triggered the event, even if the live object (`event.target`) has changed by the time the event handler runs.
119
+
## Examples
120
120
121
-
## Example `rawgamepadinputchange` event
121
+
### `gamepadrawinputchanged` event data view
122
+
123
+
The example below shows the structure of a `gamepadrawinputchanged` event, including the gamepad state snapshot and the indices of changed inputs.
122
124
123
125
```js
124
-
rawgamepadinputchange {
125
-
type:"rawgamepadchange",
126
+
gamepadrawinputchangedEventObject {
127
+
type:"gamepadrawinputchanged",
126
128
127
129
// Snapshot of the gamepad's state at the moment the event was generated.
`gamepadinputchange` event: Similar to `rawgamepadinputchange` event but instead the `getCoalescedEvents()` method is used to return a sequence of events that have been coalesced (combined) together. While `gamepadinputchange` reduces the number of events by coalescing them, this approach introduces latency and may result in missed intermediate states, making it unsuitable for scenarios requiring immediate responsiveness. This event was proposed in the [Original Proposal](https://docs.google.com/document/d/1rnQ1gU0iwPXbO7OvKS6KO9gyfpSdSQvKhK9_OkzUuKE/edit?pli=1&tab=t.0).
209
+
`gamepadinputchange` event: Similar to `gamepadrawinputchanged` event but instead the `getCoalescedEvents()` method is used to return a sequence of events that have been coalesced (combined) together. While `gamepadinputchange` reduces the number of events by coalescing them, this approach introduces latency and may result in missed intermediate states, making it unsuitable for scenarios requiring immediate responsiveness. This event was proposed in the [Original Proposal](https://docs.google.com/document/d/1rnQ1gU0iwPXbO7OvKS6KO9gyfpSdSQvKhK9_OkzUuKE/edit?pli=1&tab=t.0).
208
210
209
211
## Accessibility, privacy, and security considerations
210
-
To prevent abuse and fingerprinting, a ["gamepad user gesture"](https://www.w3.org/TR/gamepad/#dfn-gamepad-user-gesture) will be required before `RawGamepadInputChange` events start firing (e.g., pressing a button).
211
-
212
-
Limit Persistent Tracking (fingerprinting): `rawgamepadinputchange` event will not expose any new state that is not already exposed by polling [Fingerprinting in Web](https://www.w3.org/TR/fingerprinting-guidance/).
212
+
To prevent abuse and [fingerprinting](https://www.w3.org/TR/fingerprinting-guidance/), a ["gamepad user gesture"](https://www.w3.org/TR/gamepad/#dfn-gamepad-user-gesture) will be required before `gamepadrawinputchanged` events start firing (e.g., pressing a button). Moreover, `gamepadrawinputchanged` event will not expose any new state that is not already exposed by polling.
213
213
214
214
## Stakeholder feedback / opposition
215
215
Firefox: No Signal
@@ -228,42 +228,32 @@ Thanks to the following contributors and prior work that influenced this proposa
228
228
229
229
Firefox’s experimental implementation: The [`GamepadAxisMoveEvent`](https://searchfox.org/mozilla-central/source/dom/webidl/GamepadAxisMoveEvent.webidl#9) and [`GamepadButtonEvent`](https://searchfox.org/mozilla-central/source/dom/webidl/GamepadButtonEvent.webidl) WebIDL files in Firefox defines an interface for axis movement and button press and release events, which were part of an experimental prototype implementation in Firefox for handling event-driven gamepad input.
0 commit comments