Bug 220196 - [iOS] #setPointerCapture does not dispatch pointer events outside element boundary
Summary: [iOS] #setPointerCapture does not dispatch pointer events outside element bou...
Status: RESOLVED CONFIGURATION CHANGED
Alias: None
Product: WebKit
Classification: Unclassified
Component: UI Events (show other bugs)
Version: Other
Hardware: iPhone / iPad iOS 14
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2020-12-29 13:11 PST by Joy Zhong
Modified: 2022-05-25 22:07 PDT (History)
9 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Joy Zhong 2020-12-29 13:11:47 PST
See https://codepen.io/joyzhong/pen/ZEpvdEx. Note that the pointerup event is not dispatched to the red element after setting pointer capture on red, IF the pointerup occurred outside of the red element bounds.
Note that this only happens on iOS, not MacOS.

Context: This results in buggy sliders for MDC (Material Design Components) Web.
Original issue: https://github.com/material-components/material-components-web/issues/6715
Comment 1 Radar WebKit Bug Importer 2021-01-05 13:12:20 PST
<rdar://problem/72826221>
Comment 2 Mark Salsbery 2021-03-23 18:05:12 PDT
I have a similar, related issue...first discussed with the Pointer Events Working Group here (https://github.com/w3c/pointerevents/issues/327)

To reproduce: A parent and a child element, both with pointerdown event handlers. Depending on application's need, when a pointerdown occurs on the child, it should be ignored and the parent (when pointer down bubbles) will want to capture the pointer:

1. pointerdown on child
2. child calls hasPointerCapture and determines pointer is captured implicitly (touch)
3. child immediately calls releasePointerCapture
4. pointerdown bubbles to parent
5. Parent calls setPointerCapture
6. Parent processes pointermove events until pointerup, pointercancel, or lostpointercapture

Sample page here: https://openseadragon-imaging.github.io/old-demo/test.html

The grey box is the parent, green box is child (from my original description)

If the pointerdown is initiated on the child (green box) in a Webkit browser, the parent (grey box) doesn't truly get capture despite the gotpointercapture event indicating it does...this is shown by the inability to drag the parent if pointer moves outside of the container (black) element (and perhaps worst of all, if pointerup occurs outside of the parent element it's never dispatched to the parent).

The way the W3C Implicit Pointer Capture docs read to me, this should be a reasonable approach. The docs (https://www.w3.org/TR/pointerevents2/#implicit-pointer-capture) state:

Direct manipulation devices should behave exactly as if setPointerCapture was called on the target element just before the invocation of any pointerdown listeners. The hasPointerCapture API may be used (eg. within any pointerdown listener) to determine whether this has occurred. If releasePointerCapture is not called for the pointer before the next pointer event is fired, then a gotpointercapture event will be dispatched to the target (as normal) indicating that capture is active
Comment 3 Mark Salsbery 2021-05-05 08:18:41 PDT
Note: The issue I described occurs on "direct manipulation devices" (touch) devices only...mouse device on desktop works fine.
Comment 4 Westbrook 2021-11-11 16:55:56 PST
Would be cool to see some motion on this issue! We're experiencing this at Adobe with our Spectrum Web Components library (https://github.com/adobe/spectrum-web-components/pull/1929) and would love for these to be one less impediment for us doubling down on the investment into the web we've been making lately by continuing it into mobile web.

You'll see in that PR that we're going forward for now with a degraded experience in this context in the hopes that this is the sort of issue that could be resolved soon. If that's not so, can we at least hear about timeline so we can decide whether we need to ship a second code path to support iOS users with this feature?
Comment 5 Westbrook 2021-11-11 16:58:54 PST
For additional reference, we are continuing to see this in iOS 15.1.
Comment 6 thatcomputerguy0101 2022-04-12 18:04:30 PDT
This appears to be the same issue that I have documented and created a polyfill for on Stack Overflow: https://stackoverflow.com/questions/64017560/detect-ios-pointer-capture-bug-for-polyfilling. That polyfill has a basic user-agent detection mechanism, so currently will only work on Safari browsers and not other iOS browsers that share the same WebKit engine. Additionally, it will (harmlessly) over-trigger on MacOS Safari.

My demonstration of this problem is located at https://thatcomputerguy0101.github.io/iOS_pointerCapture_bug/index.html. The green and yellow divs will correctly track the pointer movement if the pointer starts on the respective element, but the orange div should act the same and the red div should never move. Both of the latter will still track the pointer as long as the pointer remains over the divs.
Comment 7 Devin Rousso 2022-04-13 12:07:20 PDT
this has been determined to be an issue outside WebKit, and will continue to be tracked by Apple internally
Comment 8 Sam Sneddon [:gsnedders] 2022-05-16 15:35:58 PDT
Just to let everyone know, the fix for this has shipped in Safari 15.5.
Comment 9 Westbrook 2022-05-16 17:49:58 PDT
Thanks Sam!

I can confirm that the demo in the OP is working as are the examples within the library of code we're shipping at https://opensource.adobe.com/spectrum-web-components/index.html Excited to share the news with my team. Cheers!
Comment 10 thatcomputerguy0101 2022-05-25 15:45:36 PDT
This appears to be mostly fixed in Safari 15.5, but I noticed that if the capture is obtained during pointerdown, the next pointer event (either pointermove or pointerup) will still be dispatched to the wrong element according to the old behavior. Any event following that behaves correctly. My demonstration for this problem (at https://thatcomputerguy0101.github.io/iOS_pointerCapture_bug/) readily shows this issue in its console logs, where for the orange and red divs, one incorrect event is logged directly following the pointer down event.
Comment 11 Mark Salsbery 2022-05-25 16:24:43 PDT
(In reply to Sam Sneddon [:gsnedders] from comment #8)
> Just to let everyone know, the fix for this has shipped in Safari 15.5.

I can confirm that my issue (commented above) is fixed in Safari 15.5. Thank you!
Comment 12 Sam Sneddon [:gsnedders] 2022-05-25 22:07:35 PDT
(In reply to thatcomputerguy0101 from comment #10)
> This appears to be mostly fixed in Safari 15.5, but I noticed that if the
> capture is obtained during pointerdown, the next pointer event (either
> pointermove or pointerup) will still be dispatched to the wrong element
> according to the old behavior. Any event following that behaves correctly.
> My demonstration for this problem (at
> https://thatcomputerguy0101.github.io/iOS_pointerCapture_bug/) readily shows
> this issue in its console logs, where for the orange and red divs, one
> incorrect event is logged directly following the pointer down event.

Can you file a new bug?