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:
Родитель
9aec132fd7
Коммит
a2761e090c
|
@ -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()) {
|
||||
|
|
|
@ -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));
|
||||
|
|
Загрузка…
Ссылка в новой задаче