Bug 1421351 - Queue chrome-only scrollend event in refresh driver scroll event queue instead of firing immediately. r=kats

MozReview-Commit-ID: KVQ5kp1t7NW
This commit is contained in:
Mike Conley
2017-11-28 13:09:56 -05:00
parent 20a1c1db85
commit b43ed7f682
2 changed files with 47 additions and 2 deletions

View File

@@ -2107,6 +2107,9 @@ ScrollFrameHelper::~ScrollFrameHelper()
if (mScrollEvent) { if (mScrollEvent) {
mScrollEvent->Revoke(); mScrollEvent->Revoke();
} }
if (mScrollEndEvent) {
mScrollEndEvent->Revoke();
}
} }
/* /*
@@ -2186,7 +2189,7 @@ ScrollFrameHelper::CompleteAsyncScroll(const nsRect &aRange, nsAtom* aOrigin)
// We are done scrolling, set our destination to wherever we actually ended // We are done scrolling, set our destination to wherever we actually ended
// up scrolling to. // up scrolling to.
mDestination = GetScrollPosition(); mDestination = GetScrollPosition();
FireScrollEndEvent(); PostScrollEndEvent();
} }
bool bool
@@ -4422,10 +4425,25 @@ ScrollFrameHelper::FireScrollPortEvent()
mOuter->PresContext(), &event); mOuter->PresContext(), &event);
} }
void
ScrollFrameHelper::PostScrollEndEvent()
{
if (mScrollEndEvent) {
return;
}
// The ScrollEndEvent constructor registers itself with the refresh driver.
mScrollEndEvent = new ScrollEndEvent(this);
}
void void
ScrollFrameHelper::FireScrollEndEvent() ScrollFrameHelper::FireScrollEndEvent()
{ {
MOZ_ASSERT(mOuter->GetContent()); MOZ_ASSERT(mOuter->GetContent());
MOZ_ASSERT(mScrollEndEvent);
mScrollEndEvent->Revoke();
mScrollEndEvent = nullptr;
nsContentUtils::DispatchEventOnlyToChrome(mOuter->GetContent()->OwnerDoc(), nsContentUtils::DispatchEventOnlyToChrome(mOuter->GetContent()->OwnerDoc(),
mOuter->GetContent(), mOuter->GetContent(),
NS_LITERAL_STRING("scrollend"), NS_LITERAL_STRING("scrollend"),
@@ -4821,6 +4839,22 @@ ScrollFrameHelper::ScrollEvent::Run()
return NS_OK; return NS_OK;
} }
ScrollFrameHelper::ScrollEndEvent::ScrollEndEvent(ScrollFrameHelper* aHelper)
: Runnable("ScrollFrameHelper::ScrollEndEvent")
, mHelper(aHelper)
{
mHelper->mOuter->PresContext()->RefreshDriver()->PostScrollEvent(this);
}
NS_IMETHODIMP
ScrollFrameHelper::ScrollEndEvent::Run()
{
if (mHelper) {
mHelper->FireScrollEndEvent();
}
return NS_OK;
}
void void
ScrollFrameHelper::FireScrollEvent() ScrollFrameHelper::FireScrollEvent()
{ {

View File

@@ -69,6 +69,7 @@ public:
nsTArray<nsIAnonymousContentCreator::ContentInfo>& aElements); nsTArray<nsIAnonymousContentCreator::ContentInfo>& aElements);
void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements, uint32_t aFilter); void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements, uint32_t aFilter);
nsresult FireScrollPortEvent(); nsresult FireScrollPortEvent();
void PostScrollEndEvent();
void FireScrollEndEvent(); void FireScrollEndEvent();
void PostOverflowEvent(); void PostOverflowEvent();
using PostDestroyData = nsIFrame::PostDestroyData; using PostDestroyData = nsIFrame::PostDestroyData;
@@ -131,6 +132,15 @@ public:
ScrollFrameHelper* mHelper; ScrollFrameHelper* mHelper;
}; };
class ScrollEndEvent : public Runnable {
public:
NS_DECL_NSIRUNNABLE
explicit ScrollEndEvent(ScrollFrameHelper* aHelper);
void Revoke() { mHelper = nullptr; }
private:
ScrollFrameHelper* mHelper;
};
class AsyncScrollPortEvent : public Runnable { class AsyncScrollPortEvent : public Runnable {
public: public:
NS_DECL_NSIRUNNABLE NS_DECL_NSIRUNNABLE
@@ -402,7 +412,7 @@ public:
void SetTransformingByAPZ(bool aTransforming) { void SetTransformingByAPZ(bool aTransforming) {
if (mTransformingByAPZ && !aTransforming) { if (mTransformingByAPZ && !aTransforming) {
FireScrollEndEvent(); PostScrollEndEvent();
} }
mTransformingByAPZ = aTransforming; mTransformingByAPZ = aTransforming;
if (!mozilla::css::TextOverflow::HasClippedOverflow(mOuter)) { if (!mozilla::css::TextOverflow::HasClippedOverflow(mOuter)) {
@@ -495,6 +505,7 @@ public:
nsCOMPtr<nsIContent> mResizerContent; nsCOMPtr<nsIContent> mResizerContent;
RefPtr<ScrollEvent> mScrollEvent; RefPtr<ScrollEvent> mScrollEvent;
RefPtr<ScrollEndEvent> mScrollEndEvent;
nsRevocableEventPtr<AsyncScrollPortEvent> mAsyncScrollPortEvent; nsRevocableEventPtr<AsyncScrollPortEvent> mAsyncScrollPortEvent;
nsRevocableEventPtr<ScrolledAreaEvent> mScrolledAreaEvent; nsRevocableEventPtr<ScrolledAreaEvent> mScrolledAreaEvent;
nsIFrame* mHScrollbarBox; nsIFrame* mHScrollbarBox;