diff --git a/mozilla/layout/generic/nsFrame.cpp b/mozilla/layout/generic/nsFrame.cpp index 72abc9c3b8c..61818eebef6 100644 --- a/mozilla/layout/generic/nsFrame.cpp +++ b/mozilla/layout/generic/nsFrame.cpp @@ -1368,7 +1368,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, PRBool isComposited = disp->mOpacity != 1.0f; PRBool isPositioned = disp->IsPositioned(); - if (isComposited || isPositioned) { + if (isComposited || isPositioned || (aFlags & DISPLAY_CHILD_FORCE_STACKING_CONTEXT)) { // If you change this, also change IsPseudoStackingContextFromStyle() pseudoStackingContext = PR_TRUE; } @@ -1405,7 +1405,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, nsDisplayList extraPositionedDescendants; const nsStylePosition* pos = aChild->GetStylePosition(); if ((isPositioned && pos->mZIndex.GetUnit() == eStyleUnit_Integer) || - isComposited) { + isComposited || (aFlags & DISPLAY_CHILD_FORCE_STACKING_CONTEXT)) { // True stacking context rv = aChild->BuildDisplayListForStackingContext(aBuilder, dirty, &list); if (NS_SUCCEEDED(rv)) { @@ -1453,7 +1453,8 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, } NS_ENSURE_SUCCESS(rv, rv); - if (isPositioned || isComposited) { + if (isPositioned || isComposited || + (aFlags & DISPLAY_CHILD_FORCE_STACKING_CONTEXT)) { // Genuine stacking contexts, and positioned pseudo-stacking-contexts, // go in this level. rv = aLists.PositionedDescendants()->AppendNewToTop(new (aBuilder) diff --git a/mozilla/layout/generic/nsIFrame.h b/mozilla/layout/generic/nsIFrame.h index f5cd8995655..a90b253b031 100644 --- a/mozilla/layout/generic/nsIFrame.h +++ b/mozilla/layout/generic/nsIFrame.h @@ -762,16 +762,17 @@ public: enum { DISPLAY_CHILD_FORCE_PSEUDO_STACKING_CONTEXT = 0x01, - DISPLAY_CHILD_INLINE = 0x02 - }; + DISPLAY_CHILD_FORCE_STACKING_CONTEXT = 0x02, + DISPLAY_CHILD_INLINE = 0x04 + }; /** * Adjusts aDirtyRect for the child's offset, checks that the dirty rect * actually intersects the child (or its descendants), calls BuildDisplayList * on the child if necessary, and puts things in the right lists if the child * is positioned. * - * @param aFlags combination of DISPLAY_CHILD_FORCE_PSEUDO_STACKING_CONTEXT - * and DISPLAY_CHILD_INLINE + * @param aFlags combination of DISPLAY_CHILD_FORCE_PSEUDO_STACKING_CONTEXT, + * DISPLAY_CHILD_FORCE_STACKING_CONTEXT and DISPLAY_CHILD_INLINE */ nsresult BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, nsIFrame* aChild, diff --git a/mozilla/layout/xul/base/src/nsStackFrame.cpp b/mozilla/layout/xul/base/src/nsStackFrame.cpp index 637c6af3143..313c2460445 100644 --- a/mozilla/layout/xul/base/src/nsStackFrame.cpp +++ b/mozilla/layout/xul/base/src/nsStackFrame.cpp @@ -57,6 +57,7 @@ #include "nsIViewManager.h" #include "nsBoxLayoutState.h" #include "nsStackLayout.h" +#include "nsDisplayList.h" nsIFrame* NS_NewStackFrame (nsIPresShell* aPresShell, nsStyleContext* aContext, nsIBoxLayout* aLayoutManager) @@ -88,12 +89,17 @@ nsStackFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { + // BuildDisplayListForChild puts stacking contexts into the PositionedDescendants + // list. So we need to map that list to aLists.Content(). This is an easy way to + // do that. + nsDisplayList* content = aLists.Content(); + nsDisplayListSet kidLists(content, content, content, content, content, content); nsIFrame* kid = mFrames.FirstChild(); while (kid) { - // Force each child into its own stacking context. + // Force each child into its own true stacking context. nsresult rv = - BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists, - DISPLAY_CHILD_FORCE_PSEUDO_STACKING_CONTEXT); + BuildDisplayListForChild(aBuilder, kid, aDirtyRect, kidLists, + DISPLAY_CHILD_FORCE_STACKING_CONTEXT); NS_ENSURE_SUCCESS(rv, rv); kid = kid->GetNextSibling(); }