зеркало из https://github.com/mozilla/gecko-dev.git
Bug 473805 - Prevent resize event loops, r=dbaron
--HG-- extra : rebase_source : e0476c7c1b390ebe194e508c3c728d517483989b
This commit is contained in:
Родитель
90dc08a58b
Коммит
72a18ed5c6
|
@ -1394,7 +1394,11 @@ private:
|
||||||
nsIntPoint& aTargetPt);
|
nsIntPoint& aTargetPt);
|
||||||
|
|
||||||
void FireResizeEvent();
|
void FireResizeEvent();
|
||||||
|
static void AsyncResizeEventCallback(nsITimer* aTimer, void* aPresShell);
|
||||||
nsRevocableEventPtr<nsRunnableMethod<PresShell> > mResizeEvent;
|
nsRevocableEventPtr<nsRunnableMethod<PresShell> > mResizeEvent;
|
||||||
|
nsCOMPtr<nsITimer> mAsyncResizeEventTimer;
|
||||||
|
PRPackedBool mAsyncResizeTimerIsActive;
|
||||||
|
PRPackedBool mInResize;
|
||||||
|
|
||||||
typedef void (*nsPluginEnumCallback)(PresShell*, nsIContent*);
|
typedef void (*nsPluginEnumCallback)(PresShell*, nsIContent*);
|
||||||
void EnumeratePlugins(nsIDOMDocument *aDocument,
|
void EnumeratePlugins(nsIDOMDocument *aDocument,
|
||||||
|
@ -2029,6 +2033,10 @@ PresShell::Destroy()
|
||||||
// plug-ins are involved(!).
|
// plug-ins are involved(!).
|
||||||
mReflowEvent.Revoke();
|
mReflowEvent.Revoke();
|
||||||
mResizeEvent.Revoke();
|
mResizeEvent.Revoke();
|
||||||
|
if (mAsyncResizeTimerIsActive) {
|
||||||
|
mAsyncResizeEventTimer->Cancel();
|
||||||
|
mAsyncResizeTimerIsActive = PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
CancelAllPendingReflows();
|
CancelAllPendingReflows();
|
||||||
CancelPostedReflowCallbacks();
|
CancelPostedReflowCallbacks();
|
||||||
|
@ -2798,6 +2806,12 @@ PresShell::sPaintSuppressionCallback(nsITimer *aTimer, void* aPresShell)
|
||||||
self->UnsuppressPainting();
|
self->UnsuppressPainting();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PresShell::AsyncResizeEventCallback(nsITimer* aTimer, void* aPresShell)
|
||||||
|
{
|
||||||
|
static_cast<PresShell*>(aPresShell)->FireResizeEvent();
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight)
|
PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight)
|
||||||
{
|
{
|
||||||
|
@ -2862,11 +2876,24 @@ PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight)
|
||||||
nsRect(0, 0, aWidth, rootFrame->GetRect().height));
|
nsRect(0, 0, aWidth, rootFrame->GetRect().height));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mIsDestroying && !mResizeEvent.IsPending()) {
|
if (!mIsDestroying && !mResizeEvent.IsPending() &&
|
||||||
nsRefPtr<nsRunnableMethod<PresShell> > resizeEvent =
|
!mAsyncResizeTimerIsActive) {
|
||||||
NS_NEW_RUNNABLE_METHOD(PresShell, this, FireResizeEvent);
|
if (mInResize) {
|
||||||
if (NS_SUCCEEDED(NS_DispatchToCurrentThread(resizeEvent))) {
|
if (!mAsyncResizeEventTimer) {
|
||||||
mResizeEvent = resizeEvent;
|
mAsyncResizeEventTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||||
|
}
|
||||||
|
if (mAsyncResizeEventTimer) {
|
||||||
|
mAsyncResizeTimerIsActive = PR_TRUE;
|
||||||
|
mAsyncResizeEventTimer->InitWithFuncCallback(AsyncResizeEventCallback,
|
||||||
|
this, 15,
|
||||||
|
nsITimer::TYPE_ONE_SHOT);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
nsRefPtr<nsRunnableMethod<PresShell> > resizeEvent =
|
||||||
|
NS_NEW_RUNNABLE_METHOD(PresShell, this, FireResizeEvent);
|
||||||
|
if (NS_SUCCEEDED(NS_DispatchToCurrentThread(resizeEvent))) {
|
||||||
|
mResizeEvent = resizeEvent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2876,6 +2903,10 @@ PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight)
|
||||||
void
|
void
|
||||||
PresShell::FireResizeEvent()
|
PresShell::FireResizeEvent()
|
||||||
{
|
{
|
||||||
|
if (mAsyncResizeTimerIsActive) {
|
||||||
|
mAsyncResizeTimerIsActive = PR_FALSE;
|
||||||
|
mAsyncResizeEventTimer->Cancel();
|
||||||
|
}
|
||||||
mResizeEvent.Revoke();
|
mResizeEvent.Revoke();
|
||||||
|
|
||||||
if (mIsDocumentGone)
|
if (mIsDocumentGone)
|
||||||
|
@ -2887,8 +2918,10 @@ PresShell::FireResizeEvent()
|
||||||
|
|
||||||
nsPIDOMWindow *window = mDocument->GetWindow();
|
nsPIDOMWindow *window = mDocument->GetWindow();
|
||||||
if (window) {
|
if (window) {
|
||||||
|
nsCOMPtr<nsIPresShell> kungFuDeathGrip(this);
|
||||||
|
mInResize = PR_TRUE;
|
||||||
nsEventDispatcher::Dispatch(window, mPresContext, &event, nsnull, &status);
|
nsEventDispatcher::Dispatch(window, mPresContext, &event, nsnull, &status);
|
||||||
// |this| may now be destroyed
|
mInResize = PR_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче