Bug 1411050 Part 1: Change nsDisplayListBuilder to mark hitests either for visibility or for pointer events.
MozReview-Commit-ID: AbYcm2gwEES
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -3309,17 +3309,17 @@ nsLayoutUtils::GetFramesForArea(nsIFrame
if (rootScrollFrame) {
builder.SetIgnoreScrollFrame(rootScrollFrame);
}
}
if (aFlags & IGNORE_CROSS_DOC) {
builder.SetDescendIntoSubdocuments(false);
}
- builder.SetHitTestShouldStopAtFirstOpaque(aFlags & ONLY_VISIBLE);
+ builder.SetHitTestIsForVisibility(aFlags & ONLY_VISIBLE);
builder.EnterPresShell(aFrame);
builder.SetVisibleRect(aRect);
builder.SetDirtyRect(aRect);
aFrame->BuildDisplayListForStackingContext(&builder, &list);
builder.LeavePresShell(aFrame, nullptr);
--- a/layout/forms/nsHTMLButtonControlFrame.cpp
+++ b/layout/forms/nsHTMLButtonControlFrame.cpp
@@ -108,17 +108,17 @@ nsHTMLButtonControlFrame::BuildDisplayLi
nsDisplayList onTop(aBuilder);
if (IsVisibleForPainting(aBuilder)) {
mRenderer.DisplayButton(aBuilder, aLists.BorderBackground(), &onTop);
}
nsDisplayListCollection set(aBuilder);
// Do not allow the child subtree to receive events.
- if (!isForEventDelivery || aBuilder->HitTestShouldStopAtFirstOpaque()) {
+ if (!isForEventDelivery || aBuilder->HitTestIsForVisibility()) {
DisplayListClipState::AutoSaveRestore clipState(aBuilder);
if (ShouldClipPaintingToBorderBox()) {
nsMargin border = StyleBorder()->GetComputedBorder();
nsRect rect(aBuilder->ToReferenceFrame(this), GetSize());
rect.Deflate(border);
nscoord radii[8];
bool hasRadii = GetPaddingBoxBorderRadii(radii);
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -953,17 +953,17 @@ nsDisplayListBuilder::nsDisplayListBuild
mContainsPluginItem(false),
mAncestorHasApzAwareEventHandler(false),
mHaveScrollableDisplayPort(false),
mWindowDraggingAllowed(false),
mIsBuildingForPopup(nsLayoutUtils::IsPopup(aReferenceFrame)),
mForceLayerForScrollParent(false),
mAsyncPanZoomEnabled(nsLayoutUtils::AsyncPanZoomEnabled(aReferenceFrame)),
mBuildingInvisibleItems(false),
- mHitTestShouldStopAtFirstOpaque(false),
+ mHitTestIsForVisibility(false),
mIsBuilding(false),
mInInvalidSubtree(false)
{
MOZ_COUNT_CTOR(nsDisplayListBuilder);
nsPresContext* pc = aReferenceFrame->PresContext();
nsIPresShell *shell = pc->PresShell();
if (pc->IsRenderingOnlySelection()) {
@@ -2757,23 +2757,27 @@ void nsDisplayList::HitTest(nsDisplayLis
} else {
// We may have just finished a run of consecutive preserve-3d transforms,
// so flush these into the destination array before processing our frame list.
FlushFramesArray(temp, aOutFrames);
}
for (uint32_t j = 0; j < outFrames.Length(); j++) {
nsIFrame *f = outFrames.ElementAt(j);
- // Handle the XUL 'mousethrough' feature and 'pointer-events'.
- if (!GetMouseThrough(f) && IsFrameReceivingPointerEvents(f)) {
+ // Filter out some frames depending on the type of hittest
+ // we are doing. For visibility tests, pass through all frames.
+ // For pointer tests, only pass through frames that are styled
+ // to receive pointer events.
+ if (aBuilder->HitTestIsForVisibility() ||
+ (!GetMouseThrough(f) && IsFrameReceivingPointerEvents(f))) {
writeFrames->AppendElement(f);
}
}
- if (aBuilder->HitTestShouldStopAtFirstOpaque() &&
+ if (aBuilder->HitTestIsForVisibility() &&
item->GetOpaqueRegion(aBuilder, &snap).Contains(aRect)) {
// We're exiting early, so pop the remaining items off the buffer.
aState->mItemBuffer.SetLength(itemBufferStart);
break;
}
}
}
// Clear any remaining preserve-3d transforms.
@@ -6040,17 +6044,17 @@ nsRegion
nsDisplayWrapList::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap) const
{
*aSnap = false;
nsRegion result;
if (mListPtr->IsOpaque()) {
// Everything within GetBounds that's visible is opaque.
result = GetBounds(aBuilder, aSnap);
- } else if (aBuilder->HitTestShouldStopAtFirstOpaque()) {
+ } else if (aBuilder->HitTestIsForVisibility()) {
// If we care about an accurate opaque region, iterate the display list
// and build up a region of opaque bounds.
nsDisplayItem* item = mList.GetBottom();
while (item) {
result.OrWith(item->GetOpaqueRegion(aBuilder, aSnap));
item = item->GetAbove();
}
}
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -1608,21 +1608,21 @@ public:
}
/**
* This is a convenience function to ease the transition until AGRs and ASRs
* are unified.
*/
AnimatedGeometryRoot* AnimatedGeometryRootForASR(const ActiveScrolledRoot* aASR);
- bool HitTestShouldStopAtFirstOpaque() const {
- return mHitTestShouldStopAtFirstOpaque;
- }
- void SetHitTestShouldStopAtFirstOpaque(bool aHitTestShouldStopAtFirstOpaque) {
- mHitTestShouldStopAtFirstOpaque = aHitTestShouldStopAtFirstOpaque;
+ bool HitTestIsForVisibility() const {
+ return mHitTestIsForVisibility;
+ }
+ void SetHitTestIsForVisibility(bool aHitTestIsForVisibility) {
+ mHitTestIsForVisibility = aHitTestIsForVisibility;
}
private:
void MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, nsIFrame* aFrame);
/**
* Returns whether a frame acts as an animated geometry root, optionally
* returning the next ancestor to check.
@@ -1798,17 +1798,17 @@ private:
// display list has a display port. An async-scrollable scroll frame is one
// which WantsAsyncScroll().
bool mHaveScrollableDisplayPort;
bool mWindowDraggingAllowed;
bool mIsBuildingForPopup;
bool mForceLayerForScrollParent;
bool mAsyncPanZoomEnabled;
bool mBuildingInvisibleItems;
- bool mHitTestShouldStopAtFirstOpaque;
+ bool mHitTestIsForVisibility;
bool mIsBuilding;
bool mInInvalidSubtree;
};
class nsDisplayItem;
class nsDisplayList;
/**
* nsDisplayItems are put in singly-linked lists rooted in an nsDisplayList.