diff options
author | wolfbeast <mcwerewolf@gmail.com> | 2018-10-31 18:47:29 +0100 |
---|---|---|
committer | wolfbeast <mcwerewolf@gmail.com> | 2018-10-31 18:47:29 +0100 |
commit | fdbac095968bc952fec6a03765a7156940ae4733 (patch) | |
tree | c81e48c9862af599ba7f5820e65b0e3cb692d4f9 /layout/generic/nsGfxScrollFrame.cpp | |
parent | 752311fd47d24fe949aeabedbd8c9ffe25f740f4 (diff) | |
download | uxp-fdbac095968bc952fec6a03765a7156940ae4733.tar.gz |
Ensure that the scroll frame deregisters its refresh driver observers (mAsyncScroll & mAsyncSmoothMSDScroll) before it's destroyed.
Tag #345
Diffstat (limited to 'layout/generic/nsGfxScrollFrame.cpp')
-rw-r--r-- | layout/generic/nsGfxScrollFrame.cpp | 52 |
1 files changed, 30 insertions, 22 deletions
diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index ccdc3a0cea..cfa366aa3c 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -1774,6 +1774,18 @@ public: return true; } + /** + * The mCallee holds a strong ref to us since the refresh driver doesn't. + * Our dtor and mCallee's Destroy() method both call RemoveObserver() - + * whichever comes first removes us from the refresh driver. + */ + void RemoveObserver() { + if (mCallee) { + RefreshDriver(mCallee)->RemoveRefreshObserver(this, Flush_Style); + mCallee = nullptr; + } + } + private: // Private destructor, to discourage deletion outside of Release(): ~AsyncSmoothMSDScroll() { @@ -1786,17 +1798,6 @@ private: return aCallee->mOuter->PresContext()->RefreshDriver(); } - /* - * The refresh driver doesn't hold a reference to its observers, - * so releasing this object can (and is) used to remove the observer on DTOR. - * Currently, this object is released once the scrolling ends. - */ - void RemoveObserver() { - if (mCallee) { - RefreshDriver(mCallee)->RemoveRefreshObserver(this, Flush_Style); - } - } - mozilla::layers::AxisPhysicsMSDModel mXAxisModel, mYAxisModel; nsRect mRange; mozilla::TimeStamp mLastRefreshTime; @@ -1875,24 +1876,25 @@ public: ScrollFrameHelper::AsyncScrollCallback(mCallee, aTime); } -private: - ScrollFrameHelper *mCallee; - - nsRefreshDriver* RefreshDriver(ScrollFrameHelper* aCallee) { - return aCallee->mOuter->PresContext()->RefreshDriver(); - } - - /* - * The refresh driver doesn't hold a reference to its observers, - * so releasing this object can (and is) used to remove the observer on DTOR. - * Currently, this object is released once the scrolling ends. + /** + * The mCallee holds a strong ref to us since the refresh driver doesn't. + * Our dtor and mCallee's Destroy() method both call RemoveObserver() - + * whichever comes first removes us from the refresh driver. */ void RemoveObserver() { if (mCallee) { RefreshDriver(mCallee)->RemoveRefreshObserver(this, Flush_Style); APZCCallbackHelper::SuppressDisplayport(false, mCallee->mOuter->PresContext()->PresShell()); + mCallee = nullptr; } } + +private: + ScrollFrameHelper *mCallee; + + nsRefreshDriver* RefreshDriver(ScrollFrameHelper* aCallee) { + return aCallee->mOuter->PresContext()->RefreshDriver(); + } }; /* @@ -4586,6 +4588,12 @@ ScrollFrameHelper::Destroy() mScrollActivityTimer->Cancel(); mScrollActivityTimer = nullptr; } + if (mAsyncScroll) { + mAsyncScroll->RemoveObserver(); + } + if (mAsyncSmoothMSDScroll) { + mAsyncSmoothMSDScroll->RemoveObserver(); + } } /** |