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, a=lizzard
authorBotond Ballo <botond@mozilla.com>
Mon, 30 May 2016 20:01:04 -0400
changeset 341648 19ce047a35799a211ed706d2085a174e21ebb6fe
parent 341647 b030558642527863f84ef96415a38b90e7234669
child 341649 9044530a959509248a485cffec7f679da20b434f
push id1183
push userraliiev@mozilla.com
push dateMon, 05 Sep 2016 20:01:49 +0000
treeherdermozilla-release@3148731bed45 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow, lizzard
bugs1276107
milestone49.0a2
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, a=lizzard 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
@@ -3690,16 +3690,28 @@ nsDisplayLayerEventRegions::IsEmpty() co
     MOZ_ASSERT(mNoActionRegion.IsEmpty());
     MOZ_ASSERT(mHorizontalPanRegion.IsEmpty());
     MOZ_ASSERT(mVerticalPanRegion.IsEmpty());
     return true;
   }
   return false;
 }
 
+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"
@@ -3136,16 +3137,20 @@ public:
   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);
 
   bool IsEmpty() const;
+
+  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;
@@ -3164,16 +3169,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(