Bug 1298218 - Create nsDisplayFixedPosition if the element has a scrolled clip. r?mattwoodrow
MozReview-Commit-ID: Kvqs6YkeGZ
--- 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.