Bug 1439809 - Add an index parameter to nsDisplayWrapList to prevent scrollbar frames from creating duplicates. r?mstange
MozReview-Commit-ID: 8somakqqA3P
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -3053,17 +3053,19 @@ AppendToTop(nsDisplayListBuilder* aBuild
scrollbarData.mTargetViewId = aBuilder->GetCurrentScrollbarTarget();
// The flags here should be exactly one scrollbar direction
MOZ_ASSERT(flags != nsDisplayOwnLayerFlags::eNone);
flags |= nsDisplayOwnLayerFlags::eScrollbarContainer;
}
newItem = MakeDisplayItem<nsDisplayOwnLayer>(aBuilder, aSourceFrame, aSource, asr, flags, scrollbarData);
} else {
- newItem = MakeDisplayItem<nsDisplayWrapList>(aBuilder, aSourceFrame, aSource, asr);
+ // Build the wrap list with an index of 1, since the scrollbar frame itself might have already
+ // built an nsDisplayWrapList.
+ newItem = MakeDisplayItem<nsDisplayWrapList>(aBuilder, aSourceFrame, aSource, asr, false, 1);
}
if (aFlags & APPEND_POSITIONED) {
// We want overlay scrollbars to always be on top of the scrolled content,
// but we don't want them to unnecessarily cover overlapping elements from
// outside our scroll frame.
Maybe<int32_t> zIndex = Nothing();
if (aFlags & APPEND_OVERLAY) {
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -6076,20 +6076,22 @@ nsDisplayWrapList::nsDisplayWrapList(nsD
nsIFrame* aFrame, nsDisplayList* aList)
: nsDisplayWrapList(aBuilder, aFrame, aList,
aBuilder->CurrentActiveScrolledRoot())
{}
nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, nsDisplayList* aList,
const ActiveScrolledRoot* aActiveScrolledRoot,
- bool aClearClipChain)
+ bool aClearClipChain,
+ uint32_t aIndex)
: nsDisplayItem(aBuilder, aFrame, aActiveScrolledRoot)
, mFrameActiveScrolledRoot(aBuilder->CurrentActiveScrolledRoot())
, mOverrideZIndex(0)
+ , mIndex(aIndex)
, mHasZIndexOverride(false)
, mClearingClipChain(aClearClipChain)
{
MOZ_COUNT_CTOR(nsDisplayWrapList);
mBaseVisibleRect = mVisibleRect;
mListPtr = &mList;
@@ -6122,16 +6124,17 @@ nsDisplayWrapList::nsDisplayWrapList(nsD
SetVisibleRect(visible, true);
}
nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, nsDisplayItem* aItem)
: nsDisplayItem(aBuilder, aFrame)
, mOverrideZIndex(0)
+ , mIndex(0)
, mHasZIndexOverride(false)
{
MOZ_COUNT_CTOR(nsDisplayWrapList);
mBaseVisibleRect = mVisibleRect;
mListPtr = &mList;
mListPtr->AppendToTop(aItem);
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -4997,23 +4997,25 @@ public:
/**
* Takes all the items from aList and puts them in our list.
*/
nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayList* aList);
nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayList* aList,
const ActiveScrolledRoot* aActiveScrolledRoot,
- bool aClearClipChain = false);
+ bool aClearClipChain = false,
+ uint32_t aIndex = 0);
nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayItem* aItem);
nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
: nsDisplayItem(aBuilder, aFrame)
, mFrameActiveScrolledRoot(aBuilder->CurrentActiveScrolledRoot())
, mOverrideZIndex(0)
+ , mIndex(0)
, mHasZIndexOverride(false)
{
MOZ_COUNT_CTOR(nsDisplayWrapList);
mBaseVisibleRect = mVisibleRect;
mListPtr = &mList;
}
/**
@@ -5024,16 +5026,17 @@ public:
nsDisplayWrapList(nsDisplayListBuilder* aBuilder, const nsDisplayWrapList& aOther)
: nsDisplayItem(aBuilder, aOther)
, mListPtr(&mList)
, mFrameActiveScrolledRoot(aOther.mFrameActiveScrolledRoot)
, mMergedFrames(aOther.mMergedFrames)
, mBounds(aOther.mBounds)
, mBaseVisibleRect(aOther.mBaseVisibleRect)
, mOverrideZIndex(aOther.mOverrideZIndex)
+ , mIndex(aOther.mIndex)
, mHasZIndexOverride(aOther.mHasZIndexOverride)
, mClearingClipChain(aOther.mClearingClipChain)
{
MOZ_COUNT_CTOR(nsDisplayWrapList);
}
virtual ~nsDisplayWrapList();
@@ -5093,16 +5096,21 @@ public:
bool* aSnap) const override;
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap) const override;
virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) const override;
virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) override;
+ virtual uint32_t GetPerFrameKey() const override
+ {
+ return (mIndex << TYPE_BITS) | nsDisplayItem::GetPerFrameKey();
+ }
+
virtual bool CanMerge(const nsDisplayItem* aItem) const override
{
return false;
}
virtual void Merge(const nsDisplayItem* aItem) override
{
MOZ_ASSERT(CanMerge(aItem));
@@ -5207,16 +5215,17 @@ protected:
// The frames from items that have been merged into this item, excluding
// this item's own frame.
nsTArray<nsIFrame*> mMergedFrames;
nsRect mBounds;
// Visible rect contributed by this display item itself.
// Our mVisibleRect may include the visible areas of children.
nsRect mBaseVisibleRect;
int32_t mOverrideZIndex;
+ uint32_t mIndex;
bool mHasZIndexOverride;
bool mClearingClipChain = false;
};
/**
* We call WrapDisplayList on the in-flow lists: BorderBackground(),
* BlockBorderBackgrounds() and Content().
* We call WrapDisplayItem on each item of Outlines(), PositionedDescendants(),