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 draft
authorBotond Ballo <botond@mozilla.com>
Mon, 30 May 2016 20:01:04 -0400
changeset 374209 4c1ca58448e3513691f92c1f9f0a92329ccc17c5
parent 374208 605e81003024844d1c7a34022e5c9bc7956f92c9
child 374210 94099476c51283ca8953127d09aa9ebfec01866d
child 375328 f492d508146b30a84c6e197d383fb587735382ff
push id19949
push userbballo@mozilla.com
push dateThu, 02 Jun 2016 00:03:00 +0000
reviewersmattwoodrow
bugs1276107
milestone49.0a1
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
layout/base/nsDisplayList.cpp
layout/base/nsDisplayList.h
layout/generic/nsGfxScrollFrame.cpp
--- 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(