Bug 1673505 - Don't create inactive scrollframe hitinfos for hidden scrollframes. r=tnikkel

If there is a scrollframe that is inactive but also visibility:hidden, then
we shouldn't create a hit test info for it, because APZ will consider it as
being visible. In the non-fission case this doesn't matter much but in the
fission case the input event could end up getting sent to the wrong process if
the hidden inactive scrollframe is sitting on top of an OOP iframe.

Differential Revision: https://phabricator.services.mozilla.com/D95767
This commit is contained in:
Kartikaya Gupta 2020-11-03 19:43:07 +00:00
Родитель 726340ba67
Коммит 5d9cc0d0cf
3 изменённых файлов: 56 добавлений и 2 удалений

Просмотреть файл

@ -0,0 +1,52 @@
<!DOCTYPE HTML>
<html>
<head>
<title>APZ hit-testing with an inactive scrollframe that is visibility:hidden (bug 1673505)</title>
<script type="application/javascript" src="apz_test_utils.js"></script>
<script type="application/javascript" src="apz_test_native_event_utils.js"></script>
<script src="/tests/SimpleTest/paint_listener.js"></script>
<meta name="viewport" content="width=device-width"/>
</head>
<body style="height: 110vh">
<div style="position:fixed; top:0px; bottom:0px; left:0px; right:0px; visibility:hidden">
<div style="overflow-y: scroll; height: 100vh" id="nested">
<div style="height: 200vh; background-color: red">
The body of this document is scrollable and is the main scrollable
element. On top of that we have a hidden fixed-pos item containing another
scrollframe, but this nested scrollframe is inactive.
Since the fixed-pos item is hidden, the nested scrollframe is hidden
too and shouldn't be the target of hit-testing. However, because it is
an inactive scrollframe, code to generate the "this is an inactive
scrollframe" area was marking it as hit-testable. This bug led to hit-
tests being mis-targeted to the nested scrollframe's layers id instead
of whatever was underneath.
</div>
</div>
</div>
</body>
<script type="application/javascript">
function test(testDriver) {
var utils = getHitTestConfig().utils;
let hasViewId;
try {
utils.getViewId(document.getElementById("nested"));
hasViewId = true;
} catch (e) {
hasViewId = false;
}
ok(!hasViewId, "The nested scroller should be inactive and not have a view id");
checkHitResult(
hitTest(centerOf(document.body)),
APZHitResultFlags.VISIBLE,
utils.getViewId(document.scrollingElement),
utils.getLayersId(),
"hit went through the hidden scrollframe");
}
waitUntilApzStable().then(test).then(subtestDone, subtestFailed);
</script>
</html>

Просмотреть файл

@ -41,6 +41,7 @@ var subtests = [
{"file": "helper_hittest_clippath.html", "prefs": prefs},
{"file": "helper_hittest_hoisted_scrollinfo.html", "prefs": prefs},
{"file": "helper_hittest_spam.html", "prefs": prefs},
{"file": "helper_hittest_hidden_inactive_scrollframe.html", "prefs": prefs},
];
if (isApzEnabled()) {

Просмотреть файл

@ -3683,8 +3683,9 @@ void ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
if (mWillBuildScrollableLayer) {
couldBuildLayer = true;
} else {
couldBuildLayer =
nsLayoutUtils::AsyncPanZoomEnabled(mOuter) && WantAsyncScroll();
couldBuildLayer = mOuter->StyleVisibility()->IsVisible() &&
nsLayoutUtils::AsyncPanZoomEnabled(mOuter) &&
WantAsyncScroll();
}
}