Skip to content

Commit

Permalink
REGRESSION (iOS 17): Video bug z-index pointer-events doesn't work well
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=265520
rdar://118936715

Reviewed by Eric Carlson.

When a video is placed atop a scrolling element, the hit test machinery walks over the compositing
views that make up the compositing heirarchy, searching for views which are "hit test" targets.
For any view which is a subclass of WKCompositingView, collectDescendantViewsInRect() will query
that view's associated Node to tell if it's a hit test target. Any UIView that is _not_ a subclass
of WKCompositingView is assumed to be a hit-test target unless it specifically opts-out of hit
testing via -isUserInteractionEnabled. The subviews of WKVideoView (itself a subclass of
WKCompositingView) have not opted out of hit testing, so are selected as a hit testing view.

Opt out these utility views by setting their userInteractionEnabled property to NO.

* LayoutTests/fast/scrolling/ios/video-atop-overflow-scroll-expected.txt: Added.
* LayoutTests/fast/scrolling/ios/video-atop-overflow-scroll.html: Added.
* Source/WebKit/UIProcess/Cocoa/VideoPresentationManagerProxy.mm:
(WebKit::VideoPresentationManagerProxy::createLayerHostViewWithID):
(WebKit::VideoPresentationManagerProxy::createViewWithID):

Canonical link: https://commits.webkit.org/276807@main
  • Loading branch information
jernoble committed Mar 28, 2024
1 parent 82f7d3d commit 3ee555d
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

This tests the ability of a video element with pointer-events: none to be placed atop a div with overflow: none, and that scrolling div retaining the ability to scroll.
RUN(video.src = findMediaFile("video", "../../../media/content/test"))
RUN(video.play())
Promise resolved OK
Simulate drag on video element
EVENT(scroll)
END OF TEST

72 changes: 72 additions & 0 deletions LayoutTests/fast/scrolling/ios/video-atop-overflow-scroll.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>video-scrolling</title>
<script src=../../../media/video-test.js></script>
<script src=../../../media/media-file.js></script>
<script src=../../../resources/basic-gestures.js></script>
<script>
async function runTest() {
findMediaElement();
run('video.src = findMediaFile("video", "../../../media/content/test")');
await shouldResolve(run('video.play()'));

consoleWrite('Simulate drag on video element');

let middleX = video.offsetLeft + video.offsetWidth / 2;
let middleY = video.offsetTop + video.offsetHeight / 2;
let scrollPromise = waitFor(scroller, 'scroll');

// It may require multiple attempts to scroll the video to succeed
while (scroller.scrollTop === 0) {
await tapAtPoint(middleX, middleY);
await touchAndDragFromPointToPoint(middleX, middleY, middleX, 0);
await Promise.race([scrollPromise, sleepFor(100)]);
}
}

window.addEventListener('load', event => {
runTest().then(endTest).catch(failTest);
})
</script>
<style>
body {
overflow: hidden;
}
#container {
display: inline-block;
position: relative;
}
video {
pointer-events: none;
position: relative;
z-index: 2;
}
#scroller {
position:absolute;
top: 0;
height: 100%;
width: 100%;
overflow-x: hidden;
overflow-y: scroll;
z-index: 1;
}
.spacer {
width: 100%;
min-height: 100%;
}
</style>
</head>
<body>
<div id="container">
<video muted playsinline></video>
<div id="scroller">
<div class=spacer></div>
<div class=spacer></div>
</div>
</div>
<div>This tests the ability of a video element with <code>pointer-events: none</code> to be placed atop a div with <code>overflow: none</code>, and that scrolling div retaining the ability to scroll.</div>
</body>
</html>
3 changes: 2 additions & 1 deletion LayoutTests/platform/ios/TestExpectations
Original file line number Diff line number Diff line change
Expand Up @@ -4790,7 +4790,6 @@ webkit.org/b/271207 http/wpt/webauthn/public-key-credential-create-success-local
webkit.org/b/271207 http/wpt/webauthn/public-key-credential-get-success-local.https.html [ Failure ]
webkit.org/b/271207 http/wpt/webauthn/public-key-credential-get-failure-local.https.html [ Failure ]


# --- imported from ios-wk2 ---

# Animation tests with issues
Expand Down Expand Up @@ -7355,3 +7354,5 @@ tables/mozilla/bugs/bug2479-2.html [ Failure Pass ]
# webkit.org/b/271792 [ MacOS iOS ] 2x fast/url/* (layout-tests) are constant text failures
fast/url/idna2008.html [ Failure ]
fast/url/url-hostname-encoding.html [ Failure ]

webkit.org/b/271764 fast/scrolling/ios/video-atop-overflow-scroll.html [ Pass Failure ]
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,9 @@ - (BOOL)prefersStatusBarHidden
RetainPtr<WKLayerHostView> view = static_cast<WKLayerHostView*>(model->layerHostView());
if (!view) {
view = adoptNS([[WKLayerHostView alloc] init]);
#if PLATFORM(IOS_FAMILY)
[view setUserInteractionEnabled:NO];
#endif
#if PLATFORM(MAC)
[view setWantsLayer:YES];
#endif
Expand Down Expand Up @@ -822,6 +825,7 @@ - (BOOL)prefersStatusBarHidden
[playerLayer setVideoSublayer:[view layer]];

[playerView addSubview:view.get()];
[playerView setUserInteractionEnabled:NO];

// The videoView may already be reparented in fullscreen, so only parent the view
// if it has no existing parent:
Expand Down

0 comments on commit 3ee555d

Please sign in to comment.