Bug 976370. Move overlay scrollbar display items above scroll layer items for the same scroll frame. r=roc

This has two desirable side effects. The first and more important is that it prevents a scrollbar item from sitting between scroll layer items and preventing them from merging into one and thus preventing the creation of an async scrollable layer. The second is that scrollbars should be on top of the content they are scrolling in general, and this will make that happen in more cases.
This commit is contained in:
Timothy Nikkel 2014-02-24 23:42:11 -06:00
parent 2ffff0072c
commit 26cf62ec1a
2 changed files with 37 additions and 0 deletions

View File

@ -1004,6 +1004,31 @@ TreatAsOpaque(nsDisplayItem* aItem, nsDisplayListBuilder* aBuilder)
return opaqueClipped;
}
/* Checks if aPotentialScrollItem is a scroll layer item and aPotentialScrollbarItem
* is an overlay scrollbar item for the same scroll frame.
*/
static bool
IsScrollLayerItemAndOverlayScrollbarForScrollFrame(
nsDisplayItem* aPotentialScrollItem, nsDisplayItem* aPotentialScrollbarItem)
{
if (aPotentialScrollItem->GetType() == nsDisplayItem::TYPE_SCROLL_LAYER &&
aPotentialScrollbarItem &&
aPotentialScrollbarItem->GetType() == nsDisplayItem::TYPE_OWN_LAYER &&
LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars)) {
nsDisplayScrollLayer* scrollItem =
static_cast<nsDisplayScrollLayer*>(aPotentialScrollItem);
nsDisplayOwnLayer* layerItem =
static_cast<nsDisplayOwnLayer*>(aPotentialScrollbarItem);
if ((layerItem->GetFlags() &
(nsDisplayOwnLayer::VERTICAL_SCROLLBAR |
nsDisplayOwnLayer::HORIZONTAL_SCROLLBAR)) &&
layerItem->Frame()->GetParent() == scrollItem->GetScrollFrame()) {
return true;
}
}
return false;
}
bool
nsDisplayList::ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
@ -1036,6 +1061,17 @@ nsDisplayList::ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder,
continue;
}
// If an overlay scrollbar item is between a scroll layer item and the
// other scroll layer items that we need to merge with just move the
// scrollbar item up, that way it will be on top of the scrolled content
// and we can try to merge all the scroll layer items.
if (IsScrollLayerItemAndOverlayScrollbarForScrollFrame(item, belowItem)) {
elements[i] = belowItem;
elements[i-1] = item;
i++;
continue;
}
if (list && item->ShouldFlattenAway(aBuilder)) {
// The elements on the list >= i no longer serve any use.
elements.SetLength(i);

View File

@ -2688,6 +2688,7 @@ public:
// Don't allow merging, each sublist must have its own layer
return false;
}
uint32_t GetFlags() { return mFlags; }
NS_DISPLAY_DECL_NAME("OwnLayer", TYPE_OWN_LAYER)
private:
uint32_t mFlags;