Bug 1298218 - Create nsDisplayFixedPosition if the element has a scrolled clip. r?mattwoodrow draft
authorMarkus Stange <mstange@themasta.com>
Wed, 24 Aug 2016 16:34:31 -0400
changeset 469207 8df89a7bc06b3cec0dc0668e1a2b40acd86019a5
parent 469206 a5e52ee4e4a2d6401dc98d958d40de9465f4b3ee
child 469208 1b0993c16133f2c60a3037fd01ff529efbe07adc
push id43652
push userbmo:mstange@themasta.com
push dateWed, 01 Feb 2017 21:18:30 +0000
reviewersmattwoodrow
bugs1298218
milestone54.0a1
Bug 1298218 - Create nsDisplayFixedPosition if the element has a scrolled clip. r?mattwoodrow MozReview-Commit-ID: Kvqs6YkeGZ
layout/generic/nsFrame.cpp
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -2053,16 +2053,35 @@ DisplayDebugBorders(nsDisplayListBuilder
 #endif
 
 static bool
 IsScrollFrameActive(nsDisplayListBuilder* aBuilder, nsIScrollableFrame* aScrollableFrame)
 {
   return aScrollableFrame && aScrollableFrame->IsScrollingActive(aBuilder);
 }
 
+/**
+ * Returns whether a display item that gets created with the builder's current
+ * state will have a scrolled clip, i.e. a clip that is scrolled by a scroll
+ * frame which does not move the item itself.
+ */
+static bool
+BuilderHasScrolledClip(nsDisplayListBuilder* aBuilder)
+{
+  const DisplayItemClipChain* currentClip =
+    aBuilder->ClipState().GetCurrentCombinedClipChain(aBuilder);
+  if (!currentClip) {
+    return false;
+  }
+
+  const ActiveScrolledRoot* currentClipASR = currentClip->mASR;
+  const ActiveScrolledRoot* currentASR = aBuilder->CurrentActiveScrolledRoot();
+  return ActiveScrolledRoot::PickDescendant(currentClipASR, currentASR) != currentASR;
+}
+
 class AutoSaveRestoreContainsBlendMode
 {
   nsDisplayListBuilder& mBuilder;
   bool mSavedContainsBlendMode;
 public:
   explicit AutoSaveRestoreContainsBlendMode(nsDisplayListBuilder& aBuilder)
     : mBuilder(aBuilder)
     , mSavedContainsBlendMode(aBuilder.ContainsBlendMode())
@@ -2256,17 +2275,18 @@ nsIFrame::BuildDisplayListForStackingCon
   bool useOpacity = HasVisualOpacity() && !nsSVGUtils::CanOptimizeOpacity(this) &&
                     (!usingSVGEffects || nsDisplayOpacity::NeedsActiveLayer(aBuilder, this));
   bool useBlendMode = effects->mMixBlendMode != NS_STYLE_BLEND_NORMAL;
   bool useStickyPosition = disp->mPosition == NS_STYLE_POSITION_STICKY &&
     IsScrollFrameActive(aBuilder,
                         nsLayoutUtils::GetNearestScrollableFrame(GetParent(),
                         nsLayoutUtils::SCROLLABLE_SAME_DOC |
                         nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN));
-  bool useFixedPosition = nsLayoutUtils::IsFixedPosFrameInDisplayPort(this);
+  bool useFixedPosition = disp->mPosition == NS_STYLE_POSITION_FIXED &&
+    (nsLayoutUtils::IsFixedPosFrameInDisplayPort(this) || BuilderHasScrolledClip(aBuilder));
 
   nsDisplayListBuilder::AutoBuildingDisplayList
     buildingDisplayList(aBuilder, this, dirtyRect, true);
 
   // Depending on the effects that are applied to this frame, we can create
   // multiple container display items and wrap them around our contents.
   // This enum lists all the potential container display items, in the order
   // outside to inside.