Bug 1465616 - Use the larger viewport to layout and size fixed position elements. r=mstange
Since fixed position elements are now scrollable, we need to ensure that
they're drawn into the viewport that they're attached to.
MozReview-Commit-ID: ADQXkLjwIzR
--- a/layout/generic/ViewportFrame.cpp
+++ b/layout/generic/ViewportFrame.cpp
@@ -276,24 +276,24 @@ ViewportFrame::AdjustReflowInputAsContai
#endif
AdjustReflowInputForScrollbars(aReflowInput);
NS_ASSERTION(GetAbsoluteContainingBlock()->GetChildList().IsEmpty() ||
(offset.x == 0 && offset.y == 0),
"We don't handle correct positioning of fixed frames with "
"scrollbars in odd positions");
- // If a scroll position clamping viewport size has been set, layout
- // fixed position elements to this size instead of the computed size.
+ // Layout fixed position elements to the visual viewport size if and only if
+ // it has been set and it is larger than the computed size, otherwise use the
+ // computed size.
nsRect rect(0, 0, aReflowInput->ComputedWidth(), aReflowInput->ComputedHeight());
nsIPresShell* ps = PresShell();
- if (ps->IsVisualViewportSizeSet()) {
+ if (ps->IsVisualViewportSizeSet() && rect.Size() < ps->GetVisualViewportSize()) {
rect.SizeTo(ps->GetVisualViewportSize());
}
-
return rect;
}
void
ViewportFrame::Reflow(nsPresContext* aPresContext,
ReflowOutput& aDesiredSize,
const ReflowInput& aReflowInput,
nsReflowStatus& aStatus)
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -1469,33 +1469,35 @@ public:
static nsRect ComputeVisibleRectForFrame(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
const nsRect& aVisibleRect,
const nsRect& aDirtyRect,
nsRect* aOutDirtyRect) {
nsRect visible = aVisibleRect;
nsRect dirtyRectRelativeToDirtyFrame = aDirtyRect;
- if (nsLayoutUtils::IsFixedPosFrameInDisplayPort(aFrame) &&
- aBuilder->IsPaintingToWindow()) {
- // position: fixed items are reflowed into and only drawn inside the
- // viewport, or the visual viewport size, if one is set.
- nsIPresShell* ps = aFrame->PresShell();
- if (ps->IsVisualViewportSizeSet()) {
- dirtyRectRelativeToDirtyFrame =
- nsRect(nsPoint(0, 0), ps->GetVisualViewportSize());
- visible = dirtyRectRelativeToDirtyFrame;
#ifdef MOZ_WIDGET_ANDROID
- } else {
- dirtyRectRelativeToDirtyFrame =
- nsRect(nsPoint(0, 0), aFrame->GetParent()->GetSize());
- visible = dirtyRectRelativeToDirtyFrame;
+ if (nsLayoutUtils::IsFixedPosFrameInDisplayPort(aFrame) &&
+ aBuilder->IsPaintingToWindow()) {
+ // We want to ensure that fixed position elements are visible when
+ // being async scrolled, so we paint them at the size of the larger
+ // viewport.
+ dirtyRectRelativeToDirtyFrame =
+ nsRect(nsPoint(0, 0), aFrame->GetParent()->GetSize());
+
+ nsIPresShell* ps = aFrame->PresShell();
+ if (ps->IsVisualViewportSizeSet() &&
+ dirtyRectRelativeToDirtyFrame.Size() < ps->GetVisualViewportSize()) {
+ dirtyRectRelativeToDirtyFrame.SizeTo(ps->GetVisualViewportSize());
+ }
+
+ visible = dirtyRectRelativeToDirtyFrame;
+ }
#endif
- }
- }
+
*aOutDirtyRect = dirtyRectRelativeToDirtyFrame - aFrame->GetPosition();
visible -= aFrame->GetPosition();
nsRect overflowRect = aFrame->GetVisualOverflowRect();
if (aFrame->IsTransformed() &&
mozilla::EffectCompositor::HasAnimationsForCompositor(aFrame,
eCSSProperty_transform)) {