Bug 1425573 - Require target confirmation for events that hit unlayerized scroll frames with non-default overscroll-behavior. r=kats

MozReview-Commit-ID: K88tXahKg8H

--HG--
extra : rebase_source : 5edc6d20150feac46ce1dd70030c677520b41ace
This commit is contained in:
Botond Ballo 2018-02-16 20:16:41 -05:00
parent 711db76f9a
commit 513f03b0b3
5 changed files with 24 additions and 2 deletions

View File

@ -80,14 +80,17 @@ CompleteAsyncTransform(const AsyncTransformComponentMatrix& aMatrix)
struct TargetConfirmationFlags {
explicit TargetConfirmationFlags(bool aTargetConfirmed)
: mTargetConfirmed(aTargetConfirmed)
, mRequiresTargetConfirmation(false)
{}
explicit TargetConfirmationFlags(gfx::CompositorHitTestInfo aHitTestInfo)
: mTargetConfirmed(aHitTestInfo != gfx::CompositorHitTestInfo::eInvisibleToHitTest &&
!(aHitTestInfo & gfx::CompositorHitTestInfo::eDispatchToContent))
, mRequiresTargetConfirmation(aHitTestInfo & gfx::CompositorHitTestInfo::eRequiresTargetConfirmation)
{}
bool mTargetConfirmed : 1;
bool mRequiresTargetConfirmation : 1;
};
} // namespace layers

View File

@ -27,6 +27,7 @@ InputBlockState::InputBlockState(const RefPtr<AsyncPanZoomController>& aTargetAp
: mTargetApzc(aTargetApzc)
, mTargetConfirmed(aFlags.mTargetConfirmed ? TargetConfirmationState::eConfirmed
: TargetConfirmationState::eUnconfirmed)
, mRequiresTargetConfirmation(aFlags.mRequiresTargetConfirmation)
, mBlockId(sBlockCounter++)
, mTransformToApzc(aTargetApzc->GetTransformToThis())
{
@ -111,7 +112,7 @@ InputBlockState::HasReceivedRealConfirmedTarget() const
bool
InputBlockState::ShouldDropEvents() const
{
return false;
return mRequiresTargetConfirmation && (mTargetConfirmed != TargetConfirmationState::eConfirmed);
}
bool

View File

@ -112,6 +112,7 @@ private:
private:
RefPtr<AsyncPanZoomController> mTargetApzc;
TargetConfirmationState mTargetConfirmed;
bool mRequiresTargetConfirmation;
const uint64_t mBlockId;
// The APZC that was actually scrolled by events in this input block.

View File

@ -46,9 +46,15 @@ enum class CompositorHitTestInfo : uint16_t {
// one (if set) or a horizontal one (if not set)
eScrollbarVertical = 1 << 8,
// Events targeting this frame should only be processed if a target
// confirmation is received from the main thread. If no such confirmation
// is received within a timeout period, the event may be dropped.
// Only meaningful in combination with eDispatchToContent.
eRequiresTargetConfirmation = 1 << 9,
// Used for IPDL serialization. This bitmask should include all the bits
// that are defined in the enum.
ALL_BITS = (1 << 9) - 1,
ALL_BITS = (1 << 10) - 1,
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(CompositorHitTestInfo)

View File

@ -3683,6 +3683,17 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
if (aBuilder->BuildCompositorHitTestInfo()) {
CompositorHitTestInfo info = CompositorHitTestInfo::eVisibleToHitTest
| CompositorHitTestInfo::eDispatchToContent;
// If the scroll frame has non-default overscroll-behavior, instruct
// APZ to require a target confirmation before processing events that
// hit this scroll frame (that is, to drop the events if a confirmation
// does not arrive within the timeout period). Otherwise, APZ's
// fallback behaviour of scrolling the enclosing scroll frame would
// violate the specified overscroll-behavior.
ScrollbarStyles scrollbarStyles = GetScrollbarStylesFromFrame();
if (scrollbarStyles.mOverscrollBehaviorX != StyleOverscrollBehavior::Auto ||
scrollbarStyles.mOverscrollBehaviorY != StyleOverscrollBehavior::Auto) {
info |= CompositorHitTestInfo::eRequiresTargetConfirmation;
}
nsDisplayCompositorHitTestInfo* hitInfo =
MakeDisplayItem<nsDisplayCompositorHitTestInfo>(aBuilder, mScrolledFrame, info, 1,
Some(mScrollPort + aBuilder->ToReferenceFrame(mOuter)));