зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1705622. When building the hit testing tree use async zoom containers to keep track of which zoom constraints to apply. r=botond
This also fixes a bug where root content xul docs had zoom constraints that allowed them to be zoomed. This would cause a crash because we would ask for a repaint request and it would get routed to APZCCallbackHelper::UpdateRootFrame (because it has the id of the document element), which assumes the existance of a root scroll frame. Differential Revision: https://phabricator.services.mozilla.com/D112486
This commit is contained in:
Родитель
4dca84b420
Коммит
aee276e715
|
@ -428,6 +428,10 @@ APZCTreeManager::UpdateHitTestingTreeImpl(const ScrollNode& aRoot,
|
|||
ancestorTransforms.push(AncestorTransform());
|
||||
state.mParentHasPerspective.push(false);
|
||||
state.mOverrideFlags.push(EventRegionsOverride::NoOverride);
|
||||
nsTArray<Maybe<ZoomConstraints>> zoomConstraintsStack;
|
||||
|
||||
// push a nothing to be used for anything outside an async zoom container
|
||||
zoomConstraintsStack.AppendElement(Nothing());
|
||||
|
||||
mApzcTreeLog << "[start]\n";
|
||||
mTreeLock.AssertCurrentThreadIn();
|
||||
|
@ -437,12 +441,21 @@ APZCTreeManager::UpdateHitTestingTreeImpl(const ScrollNode& aRoot,
|
|||
[&](ScrollNode aLayerMetrics) {
|
||||
mApzcTreeLog << aLayerMetrics.Name() << '\t';
|
||||
|
||||
if (aLayerMetrics.GetAsyncZoomContainerId()) {
|
||||
if (auto asyncZoomContainerId =
|
||||
aLayerMetrics.GetAsyncZoomContainerId()) {
|
||||
if (asyncZoomContainerNestingDepth > 0) {
|
||||
haveNestedAsyncZoomContainers = true;
|
||||
}
|
||||
mAsyncZoomContainerSubtree = Some(layersId);
|
||||
++asyncZoomContainerNestingDepth;
|
||||
|
||||
auto it = mZoomConstraints.find(
|
||||
ScrollableLayerGuid(layersId, 0, *asyncZoomContainerId));
|
||||
if (it != mZoomConstraints.end()) {
|
||||
zoomConstraintsStack.AppendElement(Some(it->second));
|
||||
} else {
|
||||
zoomConstraintsStack.AppendElement(Nothing());
|
||||
}
|
||||
}
|
||||
|
||||
if (aLayerMetrics.Metrics().IsRootContent()) {
|
||||
|
@ -466,7 +479,8 @@ APZCTreeManager::UpdateHitTestingTreeImpl(const ScrollNode& aRoot,
|
|||
|
||||
HitTestingTreeNode* node = PrepareNodeForLayer(
|
||||
lock, aLayerMetrics, aLayerMetrics.Metrics(), layersId,
|
||||
ancestorTransforms.top(), parent, next, state);
|
||||
zoomConstraintsStack.LastElement(), ancestorTransforms.top(),
|
||||
parent, next, state);
|
||||
MOZ_ASSERT(node);
|
||||
AsyncPanZoomController* apzc = node->GetApzc();
|
||||
aLayerMetrics.SetApzc(apzc);
|
||||
|
@ -553,6 +567,7 @@ APZCTreeManager::UpdateHitTestingTreeImpl(const ScrollNode& aRoot,
|
|||
[&](ScrollNode aLayerMetrics) {
|
||||
if (aLayerMetrics.GetAsyncZoomContainerId()) {
|
||||
--asyncZoomContainerNestingDepth;
|
||||
zoomConstraintsStack.RemoveLastElement();
|
||||
}
|
||||
if (aLayerMetrics.GetReferentId()) {
|
||||
state.mOverrideFlags.pop();
|
||||
|
@ -1137,6 +1152,7 @@ template <class ScrollNode>
|
|||
HitTestingTreeNode* APZCTreeManager::PrepareNodeForLayer(
|
||||
const RecursiveMutexAutoLock& aProofOfTreeLock, const ScrollNode& aLayer,
|
||||
const FrameMetrics& aMetrics, LayersId aLayersId,
|
||||
const Maybe<ZoomConstraints>& aZoomConstraints,
|
||||
const AncestorTransform& aAncestorTransform, HitTestingTreeNode* aParent,
|
||||
HitTestingTreeNode* aNextSibling, TreeBuildingState& aState) {
|
||||
bool needsApzc = true;
|
||||
|
@ -1340,18 +1356,28 @@ HitTestingTreeNode* APZCTreeManager::PrepareNodeForLayer(
|
|||
}
|
||||
|
||||
if (newApzc) {
|
||||
auto it = mZoomConstraints.find(guid);
|
||||
if (it != mZoomConstraints.end()) {
|
||||
// We have a zoomconstraints for this guid, apply it.
|
||||
apzc->UpdateZoomConstraints(it->second);
|
||||
} else if (!apzc->HasNoParentWithSameLayersId()) {
|
||||
// This is a sub-APZC, so inherit the zoom constraints from its parent.
|
||||
// This ensures that if e.g. user-scalable=no was specified, none of the
|
||||
// APZCs for that subtree allow double-tap to zoom.
|
||||
apzc->UpdateZoomConstraints(apzc->GetParent()->GetZoomConstraints());
|
||||
if (aZoomConstraints) {
|
||||
apzc->UpdateZoomConstraints(*aZoomConstraints);
|
||||
|
||||
#ifdef DEBUG
|
||||
auto it = mZoomConstraints.find(guid);
|
||||
if (it != mZoomConstraints.end()) {
|
||||
MOZ_ASSERT(it->second == *aZoomConstraints);
|
||||
}
|
||||
} else {
|
||||
// We'd like to assert these things (if the first doesn't hold then at
|
||||
// least the second) but neither are not true because xul root content
|
||||
// gets zoomable zoom constraints, but which is not zoomable because it
|
||||
// doesn't have a root scroll frame.
|
||||
// clang-format off
|
||||
// MOZ_ASSERT(mZoomConstraints.find(guid) == mZoomConstraints.end());
|
||||
// auto it = mZoomConstraints.find(guid);
|
||||
// if (it != mZoomConstraints.end()) {
|
||||
// MOZ_ASSERT(!it->second.mAllowZoom && !it->second.mAllowDoubleTapZoom);
|
||||
// }
|
||||
// clang-format on
|
||||
#endif
|
||||
}
|
||||
// Otherwise, this is the root of a layers id, but we didn't have a saved
|
||||
// zoom constraints. Leave it empty for now.
|
||||
}
|
||||
|
||||
// Add a guid -> APZC mapping for the newly created APZC.
|
||||
|
|
|
@ -750,6 +750,7 @@ class APZCTreeManager : public IAPZCTreeManager, public APZInputBridge {
|
|||
HitTestingTreeNode* PrepareNodeForLayer(
|
||||
const RecursiveMutexAutoLock& aProofOfTreeLock, const ScrollNode& aLayer,
|
||||
const FrameMetrics& aMetrics, LayersId aLayersId,
|
||||
const Maybe<ZoomConstraints>& aZoomConstraints,
|
||||
const AncestorTransform& aAncestorTransform, HitTestingTreeNode* aParent,
|
||||
HitTestingTreeNode* aNextSibling, TreeBuildingState& aState);
|
||||
template <class ScrollNode>
|
||||
|
|
Загрузка…
Ссылка в новой задаче