/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
CSSRect FrameMetrics::GetVisualViewportForLayoutViewportContainment(
ScreenCoord aFixedLayerBottomMargin) const { constbool hasDynamicToolbar = GetCompositionSizeWithoutDynamicToolbar() !=
GetCompositionBounds().Size(); // In the case where the toolbar is dynamic if `aFixedLayerBottomMargin` // is zero, it means the dynamic toolbar is fully visible. constbool isDynamicToolbarFullyVisible =
hasDynamicToolbar && aFixedLayerBottomMargin == 0;
return CSSRect(
GetVisualScrollOffset(), // Use `mCompositionSizeWithoutDynamicToolbar` in the case where the // dynamic toolbar is fully visible. // Theoretically we don't need to check `IsSoftwareKeyboardVisible()` or // `GetInteractiveWidget()` either, but for now we'd like to restrict this // behavior change in the scope of the visual scroll offset change // initiated by zoom-to-focused-input on resizes-visual with the software // keyboard. // TODO Bug 2003420: This restriction will be dropped in one of the bugs // blocking bug 2003420. As of now it's unclear what kind of test // cases need to drop this restction as user visible issues.
isDynamicToolbarFullyVisible && IsSoftwareKeyboardVisible() &&
GetInteractiveWidget() == dom::InteractiveWidget::ResizesVisual
? CalculateCompositedSizeInCssPixels(
ParentLayerRect(ParentLayerPoint(),
mCompositionSizeWithoutDynamicToolbar),
mZoom)
: CalculateCompositedSizeInCssPixels());
}
void FrameMetrics::RecalculateLayoutViewportOffset(
ScreenCoord aFixedLayerBottomMargin) { // For subframes, the visual and layout viewports coincide, so just // keep the layout viewport offset in sync with the visual one. if (!mIsRootContent) {
mLayoutViewport.MoveTo(GetVisualScrollOffset()); return;
}
// For the root, the two viewports can diverge, but the layout // viewport needs to keep enclosing the visual viewport.
KeepLayoutViewportEnclosingVisualViewport(
GetVisualViewportForLayoutViewportContainment(aFixedLayerBottomMargin),
mScrollableRect, mLayoutViewport);
}
/* static */ void FrameMetrics::KeepLayoutViewportEnclosingVisualViewport( const CSSRect& aVisualViewport, const CSSRect& aScrollableRect,
CSSRect& aLayoutViewport) { // If the visual viewport is contained within the layout viewport, we don't // need to make any adjustments, so we can exit early. // // Additionally, if the composition bounds changes (due to an orientation // change, window resize, etc.), it may take a few frames for aLayoutViewport // to update and during that time, the visual viewport may be larger than the // layout viewport. In such situations, we take an early exit if the visual // viewport contains the layout viewport. if (aLayoutViewport.Contains(aVisualViewport) ||
aVisualViewport.Contains(aLayoutViewport)) { return;
}
// If visual viewport size is greater than the layout viewport, move the // layout viewport such that it remains inside the visual viewport. Otherwise, // move the layout viewport such that the visual viewport is contained // inside the layout viewport. if ((aLayoutViewport.Width() < aVisualViewport.Width() &&
!FuzzyEqualsMultiplicative(aLayoutViewport.Width(),
aVisualViewport.Width())) ||
(aLayoutViewport.Height() < aVisualViewport.Height() &&
!FuzzyEqualsMultiplicative(aLayoutViewport.Height(),
aVisualViewport.Height()))) { if (aLayoutViewport.X() < aVisualViewport.X()) { // layout viewport moves right
aLayoutViewport.MoveToX(aVisualViewport.X());
} elseif (aVisualViewport.XMost() < aLayoutViewport.XMost()) { // layout viewport moves left
aLayoutViewport.MoveByX(aVisualViewport.XMost() -
aLayoutViewport.XMost());
} if (aLayoutViewport.Y() < aVisualViewport.Y()) { // layout viewport moves down
aLayoutViewport.MoveToY(aVisualViewport.Y());
} elseif (aVisualViewport.YMost() < aLayoutViewport.YMost()) { // layout viewport moves up
aLayoutViewport.MoveByY(aVisualViewport.YMost() -
aLayoutViewport.YMost());
}
} else { if (aVisualViewport.X() < aLayoutViewport.X()) {
aLayoutViewport.MoveToX(aVisualViewport.X());
} elseif (aLayoutViewport.XMost() < aVisualViewport.XMost()) {
aLayoutViewport.MoveByX(aVisualViewport.XMost() -
aLayoutViewport.XMost());
} if (aVisualViewport.Y() < aLayoutViewport.Y()) {
aLayoutViewport.MoveToY(aVisualViewport.Y());
} elseif (aLayoutViewport.YMost() < aVisualViewport.YMost()) {
aLayoutViewport.MoveByY(aVisualViewport.YMost() -
aLayoutViewport.YMost());
}
}
// Regardless of any adjustment above, the layout viewport is not allowed // to go outside the scrollable rect.
aLayoutViewport = aLayoutViewport.MoveInsideAndClamp(aScrollableRect);
}
bool FrameMetrics::ScrollLayoutViewportTo(const CSSPoint& aDestination) { // In applying a main-thread scroll update, try to preserve the relative // offset between the visual and layout viewports.
CSSPoint relativeOffset = GetVisualScrollOffset() - GetLayoutScrollOffset();
MOZ_ASSERT(IsRootContent() || relativeOffset == CSSPoint()); // We need to set the two offsets together, otherwise a subsequent // RecalculateLayoutViewportOffset() could see divergent layout and // visual offsets. bool offsetChanged = SetLayoutScrollOffset(aDestination);
offsetChanged |= ClampAndSetVisualScrollOffset(aDestination + relativeOffset); return offsetChanged;
}
// If the APZC is default, i.e. newly created one, any relative instant // scroll position update has been already reflected as the visual scroll // offset, so we use the mSource in this ScrollPositionUpdate, which is the // original scroll offset when this relative scroll update operation happened // on the content.
CSSPoint origin = bool(aIsDefaultApzc) ? aUpdate.GetSource() : GetVisualScrollOffset();
CSSPoint delta = (aUpdate.GetDestination() - aUpdate.GetSource());
SetVisualScrollOffset(origin + delta); return GetVisualScrollOffset() - origin;
}
void FrameMetrics::UpdatePendingScrollInfo(const ScrollPositionUpdate& aInfo) { // We only get this "pending scroll info" for paint-skip transactions, // but PureRelative position updates always trigger a full paint, so // we should never enter this code with a PureRelative update type. For // the other types, the destination field on the ScrollPositionUpdate will // tell us the final layout scroll position on the main thread.
MOZ_ASSERT(aInfo.GetType() != ScrollUpdateType::PureRelative);
// In applying a main-thread scroll update, try to preserve the relative // offset between the visual and layout viewports.
CSSPoint relativeOffset = GetVisualScrollOffset() - GetLayoutScrollOffset();
MOZ_ASSERT(IsRootContent() || relativeOffset == CSSPoint());
SetLayoutScrollOffset(aInfo.GetDestination());
ClampAndSetVisualScrollOffset(aInfo.GetDestination() + relativeOffset); // The layout offset was set to the raw destination while the visual offset // was clamped independently, so the two are no longer guaranteed to be in // their proper relationship: equal for non-root content, the layout viewport // enclosing the visual viewport for root content. (The independent clamps can // also disagree at sub-pixel precision, since the main thread clamps the // destination in app units while this clamps in CSS pixels.) Re-establish // that relationship the same way every other visual-offset mutator does, e.g. // AsyncPanZoomController::SetVisualScrollOffset.
RecalculateLayoutViewportOffset();
mScrollGeneration = aInfo.GetGeneration();
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.