Bug 1087453. Don't put scroll info layers on top of content that is not scrolled by their associated scroll frame. r=roc
authorTimothy Nikkel <tnikkel@gmail.com>
Tue, 28 Oct 2014 00:23:52 -0500
changeset 212593 853cd62361614969284eaab48bdc1845d58efd43
parent 212592 b9c041b4c894c29c37e014c7632befba92995955
child 212594 8d4d7a689070e7b5a292b615107baf297b941ab6
push id27721
push usercbook@mozilla.com
push dateTue, 28 Oct 2014 14:55:05 +0000
treeherdermozilla-central@c0ddb1b098ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs1087453
milestone36.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1087453. Don't put scroll info layers on top of content that is not scrolled by their associated scroll frame. r=roc
layout/generic/nsGfxScrollFrame.cpp
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -2458,16 +2458,32 @@ MaxZIndexInList(nsDisplayList* aList, ns
 {
   int32_t maxZIndex = 0;
   for (nsDisplayItem* item = aList->GetBottom(); item; item = item->GetAbove()) {
     maxZIndex = std::max(maxZIndex, item->ZIndex());
   }
   return maxZIndex;
 }
 
+// Finds the max z-index of the items in aList that meet the following conditions
+//   1) have z-index auto or z-index >= 0.
+//   2) aFrame is a proper ancestor of the item's frame.
+// Returns -1 if there is no such item.
+static int32_t
+MaxZIndexInListOfItemsContainedInFrame(nsDisplayList* aList, nsIFrame* aFrame)
+{
+  int32_t maxZIndex = -1;
+  for (nsDisplayItem* item = aList->GetBottom(); item; item = item->GetAbove()) {
+    if (nsLayoutUtils::IsProperAncestorFrame(aFrame, item->Frame())) {
+      maxZIndex = std::max(maxZIndex, item->ZIndex());
+    }
+  }
+  return maxZIndex;
+}
+
 static void
 AppendToTop(nsDisplayListBuilder* aBuilder, const nsDisplayListSet& aLists,
             nsDisplayList* aSource, nsIFrame* aSourceFrame, bool aOwnLayer,
             bool aPositioned)
 {
   if (aSource->IsEmpty())
     return;
 
@@ -2992,28 +3008,35 @@ ScrollFrameHelper::BuildDisplayList(nsDi
       wrapper.WrapListsInPlace(aBuilder, mOuter, scrolledContent);
     }
 
     // In case we are not using displayport or the nsDisplayScrollLayers are
     // flattened during visibility computation, we still need to export the
     // metadata about this scroll box to the compositor process.
     nsDisplayScrollInfoLayer* layerItem = new (aBuilder) nsDisplayScrollInfoLayer(
       aBuilder, mScrolledFrame, mOuter);
+    nsDisplayList* positionedDescendants = scrolledContent.PositionedDescendants();
     if (BuildScrollContainerLayers()) {
       // We process display items from bottom to top, so if we need to flatten after
       // the scroll layer items have been processed we need to be on the top.
-      nsDisplayList* positionedDescendants = scrolledContent.PositionedDescendants();
       if (!positionedDescendants->IsEmpty()) {
         layerItem->SetOverrideZIndex(MaxZIndexInList(positionedDescendants, aBuilder));
         positionedDescendants->AppendNewToTop(layerItem);
       } else {
         aLists.Outlines()->AppendNewToTop(layerItem);
       }
     } else {
-      scrolledContent.BorderBackground()->AppendNewToBottom(layerItem);
+      int32_t zindex =
+        MaxZIndexInListOfItemsContainedInFrame(positionedDescendants, mOuter);
+      if (zindex >= 0) {
+        layerItem->SetOverrideZIndex(zindex);
+        positionedDescendants->AppendNewToTop(layerItem);
+      } else {
+        scrolledContent.Outlines()->AppendNewToTop(layerItem);
+      }
     }
   }
   // Now display overlay scrollbars and the resizer, if we have one.
   AppendScrollPartsTo(aBuilder, aDirtyRect, scrolledContent, usingDisplayport,
                       createLayersForScrollbars, true);
   scrolledContent.MoveTo(aLists);
 }