Bug 526394. Part 35: Prevent event dispatch and script execution during UpdateViewAfterScroll, even in the presence of malign Win32 reentrant APIs. r=mats

This commit is contained in:
Robert O'Callahan 2010-01-12 10:45:20 +13:00
parent 4eda29f7e1
commit 8d3cbbd5d2
2 changed files with 33 additions and 16 deletions

View File

@ -1687,7 +1687,21 @@ void nsGfxScrollFrameInner::ScrollVisual(nsIntPoint aPixDelta)
nearestWidget->Scroll(aPixDelta, blitRects, configurations);
AdjustViewsAndWidgets(mScrolledFrame, PR_TRUE);
repaintRegion.MoveBy(-nearestWidgetOffset + offsetToDisplayRoot);
vm->UpdateViewAfterScroll(view, repaintRegion);
{
// Block script execution. This suppresses event dispatching in
// PresShell::HandleEvent. We need to do this because Windows
// is evil and can dispatch WM_MOUSEACTIVATE messages during
// our call to ::UpdateWindow (in the presence of out-of-process
// plugins, it seems). We are not able to handle event dispatch
// here.
// No script runners should be added as we paint!
nsContentUtils::AddScriptBlockerAndPreventAddingRunners();
vm->UpdateViewAfterScroll(view, repaintRegion);
nsContentUtils::RemoveScriptBlocker();
// Nothing should run here on removing the blocker, since we
// prevented the addition of any script runners.
}
nsIFrame* presContextRootFrame = presContext->FrameManager()->GetRootFrame();
if (nearestWidget == presContextRootFrame->GetWindow()) {

View File

@ -861,25 +861,29 @@ NS_IMETHODIMP nsViewManager::DispatchEvent(nsGUIEvent *aEvent,
// Refresh the view
if (IsRefreshEnabled()) {
nsRefPtr<nsViewManager> rootVM = RootViewManager();
// If an ancestor widget was hidden and then shown, we could
// have a delayed resize to handle.
PRBool didResize = PR_FALSE;
for (nsViewManager *vm = this; vm;
vm = vm->mRootView->GetParent()
? vm->mRootView->GetParent()->GetViewManager()
: nsnull) {
if (vm->mDelayedResize != nsSize(NSCOORD_NONE, NSCOORD_NONE) &&
IsViewVisible(vm->mRootView)) {
vm->FlushDelayedResize();
if (rootVM->mScrollCnt == 0) {
for (nsViewManager *vm = this; vm;
vm = vm->mRootView->GetParent()
? vm->mRootView->GetParent()->GetViewManager()
: nsnull) {
if (vm->mDelayedResize != nsSize(NSCOORD_NONE, NSCOORD_NONE) &&
IsViewVisible(vm->mRootView)) {
vm->FlushDelayedResize();
// Paint later.
vm->UpdateView(vm->mRootView, NS_VMREFRESH_NO_SYNC);
didResize = PR_TRUE;
// Paint later.
vm->UpdateView(vm->mRootView, NS_VMREFRESH_NO_SYNC);
didResize = PR_TRUE;
// not sure if it's valid for us to claim that we
// ignored this, but we're going to do so anyway, since
// we didn't actually paint anything
*aStatus = nsEventStatus_eIgnore;
// not sure if it's valid for us to claim that we
// ignored this, but we're going to do so anyway, since
// we didn't actually paint anything
*aStatus = nsEventStatus_eIgnore;
}
}
}
@ -888,7 +892,6 @@ NS_IMETHODIMP nsViewManager::DispatchEvent(nsGUIEvent *aEvent,
// Notify view observers that we're about to paint.
// Make sure to not send WillPaint notifications while scrolling.
nsRefPtr<nsViewManager> rootVM = RootViewManager();
nsCOMPtr<nsIWidget> widget;
rootVM->GetRootWidget(getter_AddRefs(widget));