summaryrefslogtreecommitdiffstats
path: root/layout/generic
diff options
context:
space:
mode:
Diffstat (limited to 'layout/generic')
-rw-r--r--layout/generic/nsGfxScrollFrame.cpp63
-rw-r--r--layout/generic/nsGfxScrollFrame.h3
2 files changed, 42 insertions, 24 deletions
diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp
index ccdc3a0ce..3ed3b0bb3 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();
+ }
};
/*
@@ -2150,8 +2152,7 @@ void
ScrollFrameHelper::CompleteAsyncScroll(const nsRect &aRange, nsIAtom* aOrigin)
{
// Apply desired destination range since this is the last step of scrolling.
- mAsyncSmoothMSDScroll = nullptr;
- mAsyncScroll = nullptr;
+ RemoveObservers();
nsWeakFrame weakFrame(mOuter);
ScrollToImpl(mDestination, aRange, aOrigin);
if (!weakFrame.IsAlive()) {
@@ -4586,6 +4587,20 @@ ScrollFrameHelper::Destroy()
mScrollActivityTimer->Cancel();
mScrollActivityTimer = nullptr;
}
+ RemoveObservers();
+}
+
+void
+ScrollFrameHelper::RemoveObservers()
+{
+ if (mAsyncScroll) {
+ mAsyncScroll->RemoveObserver();
+ mAsyncScroll = nullptr;
+ }
+ if (mAsyncSmoothMSDScroll) {
+ mAsyncSmoothMSDScroll->RemoveObserver();
+ mAsyncSmoothMSDScroll = nullptr;
+ }
}
/**
diff --git a/layout/generic/nsGfxScrollFrame.h b/layout/generic/nsGfxScrollFrame.h
index f1ef44ae8..81bbb358f 100644
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -638,6 +638,9 @@ protected:
bool HasBgAttachmentLocal() const;
uint8_t GetScrolledFrameDir() const;
+ // Removes any RefreshDriver observers we might have registered.
+ void RemoveObservers();
+
static void EnsureFrameVisPrefsCached();
static bool sFrameVisPrefsCached;
// The number of scrollports wide/high to expand when tracking frame visibility.