Bug 1250550 - Ensure a scroll event posted during a refresh driver tick fires during that same tick. r=mats

MozReview-Commit-ID: 1ZvYjA6a5ay
This commit is contained in:
Botond Ballo 2016-02-24 18:20:40 -05:00
parent fb026f4d2a
commit 155a54cce0
2 changed files with 25 additions and 2 deletions

View File

@ -4387,7 +4387,7 @@ ScrollFrameHelper::ScrollEvent::ScrollEvent(ScrollFrameHelper* aHelper)
: mHelper(aHelper)
{
mDriver = mHelper->mOuter->PresContext()->RefreshDriver();
mDriver->AddRefreshObserver(this, Flush_Style);
mDriver->AddRefreshObserver(this, Flush_Layout);
}
ScrollFrameHelper::ScrollEvent::~ScrollEvent()
@ -4401,7 +4401,7 @@ ScrollFrameHelper::ScrollEvent::~ScrollEvent()
void
ScrollFrameHelper::ScrollEvent::WillRefresh(mozilla::TimeStamp aTime)
{
mDriver->RemoveRefreshObserver(this, Flush_Style);
mDriver->RemoveRefreshObserver(this, Flush_Layout);
mDriver = nullptr;
mHelper->FireScrollEvent();
}

View File

@ -101,6 +101,29 @@ public:
bool IsSmoothScrollingEnabled();
/**
* This class handles the dispatching of scroll events to content.
*
* nsRefreshDriver maintains three lists of refresh observers, one for each
* flush type: Flush_Style, Flush_Layout, and Flush_Display.
*
* During a tick, it runs through each list of observers, in order, and runs
* them. To iterate over each list, it uses an EndLimitedIterator, which is
* designed to iterate only over elements present when the iterator was
* created, not elements added afterwards. This means that, for a given flush
* type, a refresh observer added during the execution of another refresh
* observer of that flush type, will not run until the next tick.
*
* During main-thread animation-driven scrolling, ScrollEvents are *posted*
* by AsyncScroll::WillRefresh(). AsyncScroll registers itself as a Flush_Style
* refresh observer.
*
* Posting a scroll event, as of bug 1250550, registers a Flush_Layout
* refresh observer, which *fires* the event when run. This allows the event
* to be fired to content in the same refresh driver tick as it is posted.
* This is an important invariant to maintain to reduce scroll event latency
* for main-thread scrolling.
*/
class ScrollEvent : public nsARefreshObserver {
public:
NS_INLINE_DECL_REFCOUNTING(ScrollEvent, override)