Bug 220194

Summary: `PointerEvent.movementX` always 0 (breaks https://noisecraft.app/)
Product: WebKit Reporter: 709922234
Component: UI EventsAssignee: Devin Rousso <hi>
Status: RESOLVED FIXED    
Severity: Normal CC: ap, cdumez, esprehn+autocc, ews-watchlist, graouts, hi, kangil.han, lgarron, simon.fraser, steveruizok, thorton, webkit-bug-importer, wenson_hsieh
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: Unspecified   
OS: Unspecified   
See Also: https://bugs.webkit.org/show_bug.cgi?id=167775
Attachments:
Description Flags
Patch
none
Patch
none
[fast-cq] Patch
none
[fast-cq] Patch
ews-feeder: commit-queue-
Patch
none
[fast-cq] Patch
none
[fast-cq] Patch none

Description 709922234 2020-12-29 08:51:07 PST
example: https://codepen.io/mantou132/pen/JjRMzMg

The `movementX` property of the `pointermove` event should be equal to `MouseEvent.movementX`
Comment 1 Alexey Proskuryakov 2020-12-30 12:38:11 PST
I can reproduce this in a recent WebKit build; works in Chrome.
Comment 2 Radar WebKit Bug Importer 2021-01-05 08:52:12 PST
<rdar://problem/72814440>
Comment 3 Steve Ruiz 2021-07-29 13:36:18 PDT
Came here to post this one.

https://codesandbox.io/s/muddy-thunder-3wesc
Comment 4 Lucas Garron 2021-12-26 01:04:07 PST
I'm also running into this issue: `movementX` and `movementY` are not populated on `pointermove` events, regardless of whether they are due to mouse, touch, or Apple Pencil.

When the source is a mouse (on macOS), the values are `0`, because the property access chains up to the `MouseEvent` prototype.

Here's a moderately useful repro:

Hosted: https://garron.net/temp/safari-movementX/
Source:
```html
<div id="log" style="background: #90B8DF; width: 90%; height: 90%">(Waiting for data.)</div>
<script>
  window.addEventListener("load", () => {
    document.body.addEventListener("pointermove", (e) => {
      console.log(e);
      document.querySelector("#log").textContent = `{movementX: ${e.movementX}, movementY: ${e.movementY}} at ${Math.round(performance.now()) / 1000}sec`
    })
  })
</script>
```

As far as I can tell, this is a bit tricky/expensive to polyfill:

- Select the correct X/Y coordinates to track per touch.
  - I believe `screenX/screenY` are best, except `screenY` is `undefined` on i[Pad]OS when the event is also used for vertical scrolling‽
- Track the last seen coordinates per `pointerId`.
  - Compensate for bugs like `undefined` values, like described above.
- Evict old cached coordinates so we don't end up with an unbounded growing cache and don't accidentally track a "movement" across mouse clicks (which seem to always have the same `pointerId`).
  - Attach listeners for `pointerup`, and `pointercancel` and hope that catches every cache eviction event‽ (Does that also need to include `pointerleave` and `pointerout`? That would cause issues for the app I'm currently working on.) Track timestamps and discard touches that are sufficiently old?

By contrast, `movementX` and `movementY` are much more ergonomic and I'd really appreciate being able to use them.
Comment 5 Lucas Garron 2021-12-26 01:22:45 PST
> except `screenY` is `undefined` on i[Pad]OS when the event is also used for vertical scrolling‽

Small correction: I think I had a typo while testing this. I'm now consistently getting both `screenX` and `screenY` values (although all the other issues I described are still relevant).
Comment 6 Lucas Garron 2021-12-26 01:53:37 PST
I'd also like to add that none of the following are effective for feature detection:

- `"movementX" in e`
- `e.movementX !== "undefined"`
- `e.hasOwnProperty("movementX")`

The fact that `movementX` can be an incorrect of `0` instead of `undefined` means that I can't trust a numerical value without something like UA sniffing, which should really be an anti-pattern at this point. :-/
Comment 7 Devin Rousso 2022-02-07 17:50:06 PST
Created attachment 451185 [details]
Patch
Comment 8 Devin Rousso 2022-02-08 13:12:07 PST
Created attachment 451298 [details]
Patch
Comment 9 Devin Rousso 2022-03-23 13:36:20 PDT
Created attachment 455544 [details]
[fast-cq] Patch
Comment 10 Devin Rousso 2022-03-23 16:21:45 PDT
Created attachment 455579 [details]
[fast-cq] Patch
Comment 11 Devin Rousso 2022-03-24 10:40:53 PDT
Created attachment 455652 [details]
Patch
Comment 12 Devin Rousso 2022-03-24 10:54:14 PDT
Created attachment 455654 [details]
[fast-cq] Patch
Comment 13 Devin Rousso 2022-03-24 17:08:54 PDT
Created attachment 455708 [details]
[fast-cq] Patch
Comment 14 EWS 2022-03-25 13:55:39 PDT
Committed r291886 (248885@main): <https://commits.webkit.org/248885@main>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 455708 [details].
Comment 15 Sam Sneddon [:gsnedders] 2022-05-16 15:35:19 PDT
Just to let everyone know, for those who care about Safari, this has shipped in Safari 15.5.