From 9f81e46a3452b90435de64f7c9d5960c7feccf03 Mon Sep 17 00:00:00 2001 From: Mihai Alexandru Michis Date: Wed, 26 Jun 2019 21:04:20 +0300 Subject: [PATCH] Backed out 2 changesets (bug 1559690) for causing failures in browser_tabCloseSpacer.js CLOSED TREE Backed out changeset 9f45982e7800 (bug 1559690) Backed out changeset fdb96c16d976 (bug 1559690) --- layout/generic/nsGfxScrollFrame.cpp | 115 ++++++++++++++++------------ layout/generic/nsGfxScrollFrame.h | 8 +- 2 files changed, 68 insertions(+), 55 deletions(-) diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 4e90851be9eb..070a5162dc34 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -126,50 +126,32 @@ static uint32_t GetOverflowChange(const nsRect& aCurScrolledRect, * ScrollEvents are one-shot runnables; the refresh driver drops them after * running them. */ -class GenericScrollEvent : public Runnable { +class ScrollFrameHelper::ScrollEvent : public Runnable { public: + NS_DECL_NSIRUNNABLE + explicit ScrollEvent(ScrollFrameHelper* aHelper, bool aDelayed); void Revoke() { mHelper = nullptr; } - protected: - GenericScrollEvent(const char* aTag, ScrollFrameHelper* aHelper, - bool aDelayed = false) - : Runnable(aTag), mHelper(aHelper) { - mHelper->mOuter->PresContext()->RefreshDriver()->PostScrollEvent(this, - aDelayed); - } - + private: ScrollFrameHelper* mHelper; }; -#define DEFINE_SCROLL_EVENT(name_) \ - class ScrollFrameHelper::name_ final : public GenericScrollEvent { \ - public: \ - explicit name_(ScrollFrameHelper* aHelper, bool aDelayed = false) \ - : GenericScrollEvent("ScrollFrameHelper::" #name_, aHelper, \ - aDelayed) {} \ - NS_IMETHODIMP Run() final { \ - if (mHelper) { \ - mHelper->Fire##name_(); \ - } \ - return NS_OK; \ - } \ - }; - -DEFINE_SCROLL_EVENT(ScrollEvent); -DEFINE_SCROLL_EVENT(ScrollEndEvent); - -class ScrollFrameHelper::ScrollPortEvent final : public Runnable { +class ScrollFrameHelper::ScrollEndEvent : public Runnable { public: - explicit ScrollPortEvent(ScrollFrameHelper* aHelper) : - Runnable("ScrollFrameHelper::ScrollPortEvent"), mHelper(aHelper) {} + NS_DECL_NSIRUNNABLE + explicit ScrollEndEvent(ScrollFrameHelper* aHelper); + void Revoke() { mHelper = nullptr; } - NS_IMETHODIMP Run() final { - if (mHelper) { - mHelper->FireScrollPortEvent(); - } - return NS_OK; - } + private: + ScrollFrameHelper* mHelper; +}; +class ScrollFrameHelper::AsyncScrollPortEvent : public Runnable { + public: + NS_DECL_NSIRUNNABLE + explicit AsyncScrollPortEvent(ScrollFrameHelper* helper) + : Runnable("ScrollFrameHelper::AsyncScrollPortEvent"), + mHelper(helper) {} void Revoke() { mHelper = nullptr; } private: @@ -181,7 +163,6 @@ class ScrollFrameHelper::ScrolledAreaEvent : public Runnable { NS_DECL_NSIRUNNABLE explicit ScrolledAreaEvent(ScrollFrameHelper* helper) : Runnable("ScrollFrameHelper::ScrolledAreaEvent"), mHelper(helper) {} - void Revoke() { mHelper = nullptr; } private: @@ -2137,9 +2118,6 @@ ScrollFrameHelper::~ScrollFrameHelper() { if (mScrollEndEvent) { mScrollEndEvent->Revoke(); } - if (mScrollPortEvent) { - mScrollPortEvent->Revoke(); - } } /* @@ -4660,14 +4638,19 @@ auto ScrollFrameHelper::GetPageLoadingState() -> LoadingState { : LoadingState::Loading; } -void ScrollFrameHelper::FireScrollPortEvent() { - mScrollPortEvent->Revoke(); - mScrollPortEvent = nullptr; +nsresult ScrollFrameHelper::FireScrollPortEvent() { + mAsyncScrollPortEvent.Forget(); // Keep this in sync with PostOverflowEvent(). nsSize scrollportSize = mScrollPort.Size(); nsSize childSize = GetScrolledRect().Size(); + // TODO(emilio): why do we need the whole WillPaintObserver infrastructure and + // can't use AddScriptRunner & co? I guess it made sense when we used + // WillPaintObserver for scroll events too, or when this used to flush. + // + // Should we remove this? + bool newVerticalOverflow = childSize.height > scrollportSize.height; bool vertChanged = mVerticalOverflow != newVerticalOverflow; @@ -4675,7 +4658,7 @@ void ScrollFrameHelper::FireScrollPortEvent() { bool horizChanged = mHorizontalOverflow != newHorizontalOverflow; if (!vertChanged && !horizChanged) { - return; + return NS_OK; } // If both either overflowed or underflowed then we dispatch only one @@ -4709,8 +4692,8 @@ void ScrollFrameHelper::FireScrollPortEvent() { : eScrollPortUnderflow, nullptr); event.mOrient = orient; - EventDispatcher::Dispatch(mOuter->GetContent(), mOuter->PresContext(), - &event); + return EventDispatcher::Dispatch(mOuter->GetContent(), mOuter->PresContext(), + &event); } void ScrollFrameHelper::PostScrollEndEvent() { @@ -5145,6 +5128,34 @@ void ScrollFrameHelper::CurPosAttributeChanged(nsIContent* aContent, /* ============= Scroll events ========== */ +ScrollFrameHelper::ScrollEvent::ScrollEvent(ScrollFrameHelper* aHelper, + bool aDelayed) + : Runnable("ScrollFrameHelper::ScrollEvent"), mHelper(aHelper) { + mHelper->mOuter->PresContext()->RefreshDriver()->PostScrollEvent(this, + aDelayed); +} + +NS_IMETHODIMP +ScrollFrameHelper::ScrollEvent::Run() { + if (mHelper) { + mHelper->FireScrollEvent(); + } + 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 ScrollFrameHelper::FireScrollEvent() { nsIContent* content = mOuter->GetContent(); nsPresContext* prescontext = mOuter->PresContext(); @@ -5198,6 +5209,11 @@ void ScrollFrameHelper::PostScrollEvent(bool aDelayed) { mScrollEvent = new ScrollEvent(this, aDelayed); } +NS_IMETHODIMP +ScrollFrameHelper::AsyncScrollPortEvent::Run() { + return mHelper ? mHelper->FireScrollPortEvent() : NS_OK; +} + bool nsXULScrollFrame::AddHorizontalScrollbar(nsBoxLayoutState& aState, bool aOnBottom) { if (!mHelper.mHScrollbarBox) { @@ -5342,7 +5358,7 @@ void nsXULScrollFrame::LayoutScrollArea(nsBoxLayoutState& aState, } void ScrollFrameHelper::PostOverflowEvent() { - if (mScrollPortEvent) { + if (mAsyncScrollPortEvent.IsPending()) { return; } @@ -5360,11 +5376,8 @@ void ScrollFrameHelper::PostOverflowEvent() { return; } - RefPtr event = new ScrollPortEvent(this); - if (NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(event.get())))) { - return; - } - mScrollPortEvent = event.forget(); + mAsyncScrollPortEvent = new AsyncScrollPortEvent(this); + nsContentUtils::AddScriptRunner(mAsyncScrollPortEvent.get()); } nsIFrame* ScrollFrameHelper::GetFrameForDir() const { diff --git a/layout/generic/nsGfxScrollFrame.h b/layout/generic/nsGfxScrollFrame.h index cd6e9113918b..86cde06293e1 100644 --- a/layout/generic/nsGfxScrollFrame.h +++ b/layout/generic/nsGfxScrollFrame.h @@ -72,10 +72,10 @@ class ScrollFrameHelper : public nsIReflowCallback { nsTArray& aElements); void AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter); - void PostOverflowEvent(); - void FireScrollPortEvent(); + nsresult FireScrollPortEvent(); void PostScrollEndEvent(); void FireScrollEndEvent(); + void PostOverflowEvent(); using PostDestroyData = nsIFrame::PostDestroyData; void Destroy(PostDestroyData& aPostDestroyData); @@ -521,12 +521,12 @@ class ScrollFrameHelper : public nsIReflowCallback { class ScrollEvent; class ScrollEndEvent; - class ScrollPortEvent; + class AsyncScrollPortEvent; class ScrolledAreaEvent; RefPtr mScrollEvent; RefPtr mScrollEndEvent; - RefPtr mScrollPortEvent; + nsRevocableEventPtr mAsyncScrollPortEvent; nsRevocableEventPtr mScrolledAreaEvent; nsIFrame* mHScrollbarBox; nsIFrame* mVScrollbarBox;