Bug 636564 - Make scroll frames deal correctly with scrollbars that overlay content. r=roc

This commit is contained in:
Markus Stange 2011-12-20 13:30:14 +01:00
parent 29372046ab
commit 105bef8583
5 changed files with 43 additions and 69 deletions

View File

@ -1474,9 +1474,6 @@ nsGfxScrollFrameInner::nsGfxScrollFrameInner(nsContainerFrame* aOuter,
, mCollapsedResizer(false)
, mShouldBuildLayer(false)
{
// lookup if we're allowed to overlap the content from the look&feel object
mScrollbarsCanOverlapContent =
LookAndFeel::GetInt(LookAndFeel::eIntID_ScrollbarsCanOverlapContent) != 0;
mScrollingActive = IsAlwaysActive();
}
@ -1879,33 +1876,36 @@ AppendToTop(nsDisplayListBuilder* aBuilder, nsDisplayList* aDest,
}
}
nsresult
void
nsGfxScrollFrameInner::AppendScrollPartsTo(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists,
const nsDisplayListCollection& aDest,
bool& aCreateLayer)
bool& aCreateLayer,
bool aPositioned)
{
nsresult rv = NS_OK;
bool hasResizer = HasResizer();
for (nsIFrame* kid = mOuter->GetFirstPrincipalChild(); kid; kid = kid->GetNextSibling()) {
if (kid != mScrolledFrame) {
if (kid == mResizerBox && hasResizer) {
// skip the resizer as this will be drawn later on top of the scrolled content
if (kid == mScrolledFrame ||
(kid->GetStyleDisplay()->IsPositioned() != aPositioned))
continue;
}
rv = mOuter->BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aDest,
nsDisplayListCollection partList;
mOuter->BuildDisplayListForChild(aBuilder, kid, aDirtyRect, partList,
nsIFrame::DISPLAY_CHILD_FORCE_STACKING_CONTEXT);
NS_ENSURE_SUCCESS(rv, rv);
// DISPLAY_CHILD_FORCE_STACKING_CONTEXT put everything into the
// PositionedDescendants list.
::AppendToTop(aBuilder, aLists.BorderBackground(),
aDest.PositionedDescendants(), kid,
// Don't append textarea resizers to the positioned descendants because
// we don't want them to float on top of overlapping elements.
bool appendToPositioned = aPositioned && !(kid == mResizerBox && !mIsRoot);
nsDisplayList* dest = appendToPositioned ?
aLists.PositionedDescendants() : aLists.BorderBackground();
// DISPLAY_CHILD_FORCE_STACKING_CONTEXT put everything into
// partList.PositionedDescendants().
::AppendToTop(aBuilder, dest,
partList.PositionedDescendants(), kid,
aCreateLayer);
}
}
return rv;
}
bool
nsGfxScrollFrameInner::ShouldBuildLayer() const
@ -1984,15 +1984,15 @@ nsGfxScrollFrameInner::BuildDisplayList(nsDisplayListBuilder* aBuilder,
bool createLayersForScrollbars = mIsRoot &&
mOuter->PresContext()->IsRootContentDocument();
nsDisplayListCollection scrollParts;
if (!mScrollbarsCanOverlapContent) {
// Now display the scrollbars and scrollcorner. These parts are drawn
// in the border-background layer, on top of our own background and
// borders and underneath borders and backgrounds of later elements
// in the tree.
AppendScrollPartsTo(aBuilder, aDirtyRect, aLists,
scrollParts, createLayersForScrollbars);
}
// Note that this does not apply for overlay scrollbars; those are drawn
// in the positioned-elements layer on top of everything else by the call
// to AppendScrollPartsTo(..., true) further down.
AppendScrollPartsTo(aBuilder, aDirtyRect, aLists, createLayersForScrollbars,
false);
// Overflow clipping can never clip frames outside our subtree, so there
// is no need to worry about whether we are a moving frame that might clip
@ -2062,25 +2062,9 @@ nsGfxScrollFrameInner::BuildDisplayList(nsDisplayListBuilder* aBuilder,
true, mIsRoot);
NS_ENSURE_SUCCESS(rv, rv);
if (mScrollbarsCanOverlapContent) {
AppendScrollPartsTo(aBuilder, aDirtyRect, aLists,
scrollParts, createLayersForScrollbars);
}
if (HasResizer()) {
rv = mOuter->BuildDisplayListForChild(aBuilder, mResizerBox, aDirtyRect, scrollParts,
nsIFrame::DISPLAY_CHILD_FORCE_STACKING_CONTEXT);
NS_ENSURE_SUCCESS(rv, rv);
// DISPLAY_CHILD_FORCE_STACKING_CONTEXT puts everything into the
// PositionedDescendants list.
// The resizer is positioned and has maximum z-index; we put it in
// PositionedDescendants() for the root frame to ensure that it appears
// above all content, bug 631337.
::AppendToTop(aBuilder,
mIsRoot ? aLists.PositionedDescendants() : aLists.Content(),
scrollParts.PositionedDescendants(), mResizerBox,
createLayersForScrollbars);
}
// Now display overlay scrollbars and the resizer, if we have one.
AppendScrollPartsTo(aBuilder, aDirtyRect, aLists, createLayersForScrollbars,
true);
return NS_OK;
}

View File

@ -98,11 +98,11 @@ public:
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists);
nsresult AppendScrollPartsTo(nsDisplayListBuilder* aBuilder,
void AppendScrollPartsTo(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists,
const nsDisplayListCollection& aDest,
bool& aCreateLayer);
bool& aCreateLayer,
bool aPositioned);
bool GetBorderRadii(nscoord aRadii[8]) const;
@ -324,9 +324,6 @@ public:
// If true, we should be prepared to scroll using this scrollframe
// by placing descendant content into its own layer(s)
bool mScrollingActive:1;
// If true, scrollbars are stacked on the top of the display list and can
// float above the content as a result
bool mScrollbarsCanOverlapContent:1;
// If true, the resizer is collapsed and not displayed
bool mCollapsedResizer:1;

View File

@ -83,8 +83,6 @@ pref("layout.css.dpi", 160);
pref("layout.css.dpi", 240);
#endif
#endif
/* allow scrollbars to float above chrome ui */
pref("ui.scrollbarsCanOverlapContent", 1);
/* use long press to display a context menu */
pref("ui.click_hold_context_menus", true);

View File

@ -219,8 +219,6 @@ public:
eIntID_SubmenuDelay,
// can popups overlap menu/task bar?
eIntID_MenusCanOverlapOSBar,
// can scrollbars float above content?
eIntID_ScrollbarsCanOverlapContent,
// skip navigating to disabled menu item?
eIntID_SkipNavigatingDisabledMenuItem,
// begin a drag if the mouse is moved further than the threshold while the

View File

@ -77,9 +77,6 @@ nsLookAndFeelIntPref nsXPLookAndFeel::sIntPrefs[] =
{ "ui.useAccessibilityTheme",
eIntID_UseAccessibilityTheme,
false, 0 },
{ "ui.scrollbarsCanOverlapContent",
eIntID_ScrollbarsCanOverlapContent,
false, 0 },
{ "ui.menusCanOverlapOSBar",
eIntID_MenusCanOverlapOSBar,
false, 0 },