Bug 1276107 - Ensure sorting display items by z-order doesn't cause event-regions items to end up below items they are supposed to cover. r=mattwoodrow
MozReview-Commit-ID: BxnshG9TgRb
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -3675,16 +3675,28 @@ nsDisplayLayerEventRegions::AddFrame(nsD
void
nsDisplayLayerEventRegions::AddInactiveScrollPort(const nsRect& aRect)
{
mHitRegion.Or(mHitRegion, aRect);
mDispatchToContentHitRegion.Or(mDispatchToContentHitRegion, aRect);
}
+int32_t
+nsDisplayLayerEventRegions::ZIndex() const
+{
+ return mOverrideZIndex ? *mOverrideZIndex : nsDisplayItem::ZIndex();
+}
+
+void
+nsDisplayLayerEventRegions::SetOverrideZIndex(int32_t aZIndex)
+{
+ mOverrideZIndex = Some(aZIndex);
+}
+
void
nsDisplayLayerEventRegions::WriteDebugInfo(std::stringstream& aStream)
{
if (!mHitRegion.IsEmpty()) {
AppendToString(aStream, mHitRegion, " (hitRegion ", ")");
}
if (!mMaybeHitRegion.IsEmpty()) {
AppendToString(aStream, mMaybeHitRegion, " (maybeHitRegion ", ")");
--- a/layout/base/nsDisplayList.h
+++ b/layout/base/nsDisplayList.h
@@ -11,16 +11,17 @@
*/
#ifndef NSDISPLAYLIST_H_
#define NSDISPLAYLIST_H_
#include "mozilla/Attributes.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/EnumSet.h"
+#include "mozilla/Maybe.h"
#include "nsCOMPtr.h"
#include "nsContainerFrame.h"
#include "nsPoint.h"
#include "nsRect.h"
#include "plarena.h"
#include "nsRegion.h"
#include "nsDisplayListInvalidation.h"
#include "nsRenderingContext.h"
@@ -3143,16 +3144,19 @@ public:
// this layer. aFrame must have the same reference frame as mFrame.
void AddFrame(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame);
// Indicate that an inactive scrollframe's scrollport should be added to the
// dispatch-to-content region, to ensure that APZ lets content create a
// displayport.
void AddInactiveScrollPort(const nsRect& aRect);
+ int32_t ZIndex() const override;
+ void SetOverrideZIndex(int32_t aZIndex);
+
const nsRegion& HitRegion() { return mHitRegion; }
const nsRegion& MaybeHitRegion() { return mMaybeHitRegion; }
const nsRegion& DispatchToContentHitRegion() { return mDispatchToContentHitRegion; }
const nsRegion& NoActionRegion() { return mNoActionRegion; }
const nsRegion& HorizontalPanRegion() { return mHorizontalPanRegion; }
const nsRegion& VerticalPanRegion() { return mVerticalPanRegion; }
virtual void WriteDebugInfo(std::stringstream& aStream) override;
@@ -3171,16 +3175,21 @@ private:
// property. Always contained in the union of mHitRegion and mMaybeHitRegion.
nsRegion mNoActionRegion;
// These are points where panning is horizontal, as determined by the touch-action
// property. Always contained in the union of mHitRegion and mMaybeHitRegion.
nsRegion mHorizontalPanRegion;
// These are points where panning is vertical, as determined by the touch-action
// property. Always contained in the union of mHitRegion and mMaybeHitRegion.
nsRegion mVerticalPanRegion;
+ // If these event regions are for an inactive scroll frame, the z-index of
+ // this display item is overridden to be the largest z-index of the content
+ // in the scroll frame. This ensures that the event regions item remains on
+ // top of the content after sorting items by z-index.
+ mozilla::Maybe<int32_t> mOverrideZIndex;
};
/**
* A class that lets you wrap a display list as a display item.
*
* GetUnderlyingFrame() is troublesome for wrapped lists because if the wrapped
* list has many items, it's not clear which one has the 'underlying frame'.
* Thus we force the creator to specify what the underlying frame is. The
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -3458,16 +3458,17 @@ ScrollFrameHelper::BuildDisplayList(nsDi
if (inactiveRegionItem) {
nsDisplayList* positionedDescendants = scrolledContent.PositionedDescendants();
nsDisplayList* destinationList = nullptr;
int32_t zindex =
MaxZIndexInListOfItemsContainedInFrame(positionedDescendants, mOuter);
if (zindex >= 0) {
destinationList = positionedDescendants;
+ inactiveRegionItem->SetOverrideZIndex(zindex);
} else {
destinationList = scrolledContent.Outlines();
}
destinationList->AppendNewToTop(inactiveRegionItem);
}
if (aBuilder->ShouldBuildScrollInfoItemsForHoisting()) {
aBuilder->AppendNewScrollInfoItemForHoisting(