PointerEvent.movementX inconsistency with touch input
Categories
(Core :: DOM: Events, defect)
Tracking
()
People
(Reporter: simontang, Unassigned)
References
Details
(Keywords: parity-chrome, parity-safari)
Attachments
(1 file)
1.07 KB,
text/html
|
Details |
User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Steps to reproduce:
- Using Firefox on desktop with touch input (haven't tested on Android),
- Apply
touch-action none;
style to disable things like swipe to go back, zoom, etc. - Subscribe to "pointermove" events and consume movementX/movementY fields
The attached HTML page shows the movementX/Y values for pointermove/mousemove/touchmove. The touchmove event doesn't have this value but it
Actual results:
In Firefox:
- With mouse, PointerEvent.movementX matches MouseEvent.movementX, where each event contains the delta since the previous event
- With touch, PointerEvent.movementX represents the absolute displacement from the start of the touch input (instead of the delta since previous event)
In Chromium 131, PointerEvent.movementX always represents the delta since the previous event, for both mouse and touch inputs.
Expected results:
I would expect PointerEvent.movementX to behave the same way for mouse and touch input, which would be matching MouseEvent.movementX.
However, apparently PointerEvent.movementX isn't in the W3C spec (https://w3c.github.io/pointerevents/). But this also isn't described in MDN web docs either so it would be good to resolve this inconsistency in case websites expect movementX to always represent the delta regardless of browser.
Accidentally deleted part of a sentence - meant to say "... but it helps to show that on a surface level, it doesn't seem like PointerEvent.movementX is intentionally reflecting touchmove either."
Comment 2•2 months ago
|
||
The Bugbug bot thinks this bug should belong to the 'Core::DOM: Events' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.
Comment 3•2 months ago
|
||
What's your opinion about the expected behavior in this case?
Comment 4•2 months ago
|
||
MouseEvent.movementX
and MouseEvent.movementY
are extensions of Pointer Lock 2.0.
https://w3c.github.io/pointerlock/#extensions-to-the-mouseevent-interface
It defines that:
The attributes movementX and movementY must provide the change in position of the pointer, as if the values of screenX, screenY, were stored between two subsequent mousemove events eNow and ePrevious and the difference taken movementX = eNow.screenX - ePrevious.screenX.
movementX and movementY must be zero for all mouse events except mousemove. All motion data must be delivered via mousemove events such that between any two mouse events earlierEvent and currentEvent the value of currentEvent.screenX - earlierEvent.screenX is equivalent to the sum of all movementX in the events after earlierEvent, with the exception of when screenX can not be updated because the pointer is clipped by the user agent screen boundaries.
According to the result on the attached testcase, it seems that we compute movementX
and movementY
values with the last mousemove
event which is dispatched only when you tap an element if you use only touch devices.
I think that this is wrong since pointermove
is not a mousemove
event. So I think that returning 0
for the both attributes must conform to the current definition. On the other hand, Chrome also returns non-zero values for the attributes of pointermove
, and it may be reasonable for web developers. So, perhaps, we should change the values of pointermove
is computed with the previous pointermove
of the pointer.
Anyway, we should file a spec issue about this. (And perhaps, movementX
and movementY
should be changed to double
in Pointer Events.)
Comment 5•2 months ago
|
||
Chromium initialize movementX
and movementY
of pointermove
and pointerrawupdate
here:
https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/events/pointer_event_factory.cc;l=87-103;drc=f39c57f31413abcb41d3068cfb2c7a1718003cc5
The last position is computed here:
https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/events/pointer_event_factory.cc;l=408-428;drc=f39c57f31413abcb41d3068cfb2c7a1718003cc5
So, the values are stored per pointer.
The last position is stored when dispatching any pointer events:
https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/input/pointer_event_manager.cc;l=916-918;drc=f39c57f31413abcb41d3068cfb2c7a1718003cc5
Updated•2 months ago
|
Updated•2 months ago
|
Description
•