changeset: 312069:3c2bd9158ad3 user: Timothy Nikkel Date: Tue May 10 22:58:47 2016 -0500 summary: Bug 1261752. Part 3. r=mats a=ritu diff -r 73cc9a2d8fc1 -r 3c2bd9158ad3 layout/forms/nsComboboxControlFrame.cpp --- a/layout/forms/nsComboboxControlFrame.cpp Tue May 10 22:58:47 2016 -0500 +++ b/layout/forms/nsComboboxControlFrame.cpp Tue May 10 22:58:47 2016 -0500 @@ -1417,7 +1417,11 @@ // The popup's visibility doesn't update until the minimize animation has // finished, so call UpdateWidgetGeometry to update it right away. nsViewManager* viewManager = mDropdownFrame->GetView()->GetViewManager(); - viewManager->UpdateWidgetGeometry(); + viewManager->UpdateWidgetGeometry(); // might destroy us + } + + if (!weakFrame.IsAlive()) { + return consume; } return consume; diff -r 73cc9a2d8fc1 -r 3c2bd9158ad3 view/nsViewManager.cpp --- a/view/nsViewManager.cpp Tue May 10 22:58:47 2016 -0500 +++ b/view/nsViewManager.cpp Tue May 10 22:58:47 2016 -0500 @@ -670,15 +670,16 @@ void nsViewManager::WillPaintWindow(nsIWidget* aWidget) { - if (aWidget) { - nsView* view = nsView::GetViewFor(aWidget); - LayerManager *manager = aWidget->GetLayerManager(); + RefPtr widget(aWidget); + if (widget) { + nsView* view = nsView::GetViewFor(widget); + LayerManager* manager = widget->GetLayerManager(); if (view && (view->ForcedRepaint() || !manager->NeedsWidgetInvalidation())) { ProcessPendingUpdates(); // Re-get the view pointer here since the ProcessPendingUpdates might have // destroyed it during CallWillPaintOnObservers. - view = nsView::GetViewFor(aWidget); + view = nsView::GetViewFor(widget); if (view) { view->SetForcedRepaint(false); } diff -r 73cc9a2d8fc1 -r 3c2bd9158ad3 widget/PuppetWidget.cpp --- a/widget/PuppetWidget.cpp Tue May 10 22:58:47 2016 -0500 +++ b/widget/PuppetWidget.cpp Tue May 10 22:58:47 2016 -0500 @@ -823,6 +823,8 @@ mDirtyRegion.SetEmpty(); mPaintTask.Revoke(); + RefPtr strongThis(this); + mAttachedWidgetListener->WillPaintWindow(this); if (mAttachedWidgetListener) { diff -r 73cc9a2d8fc1 -r 3c2bd9158ad3 widget/cocoa/nsChildView.mm --- a/widget/cocoa/nsChildView.mm Tue May 10 22:58:47 2016 -0500 +++ b/widget/cocoa/nsChildView.mm Tue May 10 22:58:47 2016 -0500 @@ -3716,6 +3716,8 @@ - (void)viewWillDraw { + nsAutoRetainCocoaObject kungFuDeathGrip(self); + if (mGeckoChild) { // The OS normally *will* draw our NSWindow, no matter what we do here. // But Gecko can delete our parent widget(s) (along with mGeckoChild) diff -r 73cc9a2d8fc1 -r 3c2bd9158ad3 widget/gonk/nsWindow.cpp --- a/widget/gonk/nsWindow.cpp Tue May 10 22:58:47 2016 -0500 +++ b/widget/gonk/nsWindow.cpp Tue May 10 22:58:47 2016 -0500 @@ -196,7 +196,7 @@ return; } - nsWindow *targetWindow = (nsWindow *)sTopWindows[0]; + RefPtr targetWindow = (nsWindow *)sTopWindows[0]; while (targetWindow->GetLastChild()) targetWindow = (nsWindow *)targetWindow->GetLastChild(); @@ -205,15 +205,15 @@ listener->WillPaintWindow(targetWindow); } - LayerManager* lm = targetWindow->GetLayerManager(); - if (mozilla::layers::LayersBackend::LAYERS_CLIENT == lm->GetBackendType()) { - // No need to do anything, the compositor will handle drawing - } else { - NS_RUNTIMEABORT("Unexpected layer manager type"); - } - listener = targetWindow->GetWidgetListener(); if (listener) { + LayerManager* lm = targetWindow->GetLayerManager(); + if (mozilla::layers::LayersBackend::LAYERS_CLIENT == lm->GetBackendType()) { + // No need to do anything, the compositor will handle drawing + } else { + NS_RUNTIMEABORT("Unexpected layer manager type"); + } + listener->DidPaintWindow(); } } diff -r 73cc9a2d8fc1 -r 3c2bd9158ad3 widget/gtk/nsWindow.cpp --- a/widget/gtk/nsWindow.cpp Tue May 10 22:58:47 2016 -0500 +++ b/widget/gtk/nsWindow.cpp Tue May 10 22:58:47 2016 -0500 @@ -469,6 +469,12 @@ } } +nsIWidgetListener* +nsWindow::GetListener() +{ + return mAttachedWidgetListener ? mAttachedWidgetListener : mWidgetListener; +} + nsresult nsWindow::DispatchEvent(WidgetGUIEvent* aEvent, nsEventStatus& aStatus) { @@ -481,8 +487,7 @@ aEvent->refPoint.y = GdkCoordToDevicePixels(aEvent->refPoint.y); aStatus = nsEventStatus_eIgnore; - nsIWidgetListener* listener = - mAttachedWidgetListener ? mAttachedWidgetListener : mWidgetListener; + nsIWidgetListener* listener = GetListener(); if (listener) { aStatus = listener->HandleEvent(aEvent, mUseAttachedEvents); } @@ -2119,8 +2124,7 @@ if (!mGdkWindow || mIsFullyObscured || !mHasMappedToplevel) return FALSE; - nsIWidgetListener *listener = - mAttachedWidgetListener ? mAttachedWidgetListener : mWidgetListener; + nsIWidgetListener *listener = GetListener(); if (!listener) return FALSE; @@ -2149,6 +2153,8 @@ clientLayers->SendInvalidRegion(region); } + RefPtr strongThis(this); + // Dispatch WillPaintWindow notification to allow scripts etc. to run // before we paint { @@ -2161,8 +2167,7 @@ // Re-get the listener since the will paint notification might have // killed it. - listener = - mAttachedWidgetListener ? mAttachedWidgetListener : mWidgetListener; + listener = GetListener(); if (!listener) return FALSE; } @@ -2223,6 +2228,13 @@ // If this widget uses OMTC... if (GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_CLIENT) { listener->PaintWindow(this, region); + + // Re-get the listener since the will paint notification might have + // killed it. + listener = GetListener(); + if (!listener) + return TRUE; + listener->DidPaintWindow(); return TRUE; } @@ -2307,6 +2319,13 @@ if (GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_BASIC) { AutoLayerManagerSetup setupLayerManager(this, ctx, layerBuffering); painted = listener->PaintWindow(this, region); + + // Re-get the listener since the will paint notification might have + // killed it. + listener = GetListener(); + if (!listener) + return TRUE; + } } diff -r 73cc9a2d8fc1 -r 3c2bd9158ad3 widget/gtk/nsWindow.h --- a/widget/gtk/nsWindow.h Tue May 10 22:58:47 2016 -0500 +++ b/widget/gtk/nsWindow.h Tue May 10 22:58:47 2016 -0500 @@ -359,6 +359,7 @@ GdkWindow** aWindow, gint* aButton, gint* aRootX, gint* aRootY); void ClearCachedResources(); + nsIWidgetListener* GetListener(); GtkWidget *mShell; MozContainer *mContainer; diff -r 73cc9a2d8fc1 -r 3c2bd9158ad3 widget/qt/nsWindow.cpp --- a/widget/qt/nsWindow.cpp Tue May 10 22:58:47 2016 -0500 +++ b/widget/qt/nsWindow.cpp Tue May 10 22:58:47 2016 -0500 @@ -857,18 +857,28 @@ // EVENTS +nsIWidgetListener* +nsWindow::GetPaintListener() +{ + return mAttachedWidgetListener ? mAttachedWidgetListener : mWidgetListener; +} + void nsWindow::OnPaint() { LOGDRAW(("nsWindow::%s [%p]\n", __FUNCTION__, (void *)this)); - nsIWidgetListener* listener = - mAttachedWidgetListener ? mAttachedWidgetListener : mWidgetListener; + nsIWidgetListener* listener = GetPaintListener(); if (!listener) { return; } listener->WillPaintWindow(this); + nsIWidgetListener* listener = GetPaintListener(); + if (!listener) { + return; + } + switch (GetLayerManager()->GetBackendType()) { case mozilla::layers::LayersBackend::LAYERS_CLIENT: { nsIntRegion region(nsIntRect(0, 0, mWidget->width(), mWidget->height())); @@ -879,6 +889,11 @@ NS_ERROR("Invalid layer manager"); } + nsIWidgetListener* listener = GetPaintListener(); + if (!listener) { + return; + } + listener->DidPaintWindow(); } diff -r 73cc9a2d8fc1 -r 3c2bd9158ad3 widget/qt/nsWindow.h --- a/widget/qt/nsWindow.h Tue May 10 22:58:47 2016 -0500 +++ b/widget/qt/nsWindow.h Tue May 10 22:58:47 2016 -0500 @@ -254,6 +254,7 @@ bool needDispatch; } MozCachedMoveEvent; + nsIWidgetListener* GetPaintListener(); bool CheckForRollup(double aMouseX, double aMouseY, bool aIsWheel); void* SetupPluginPort(void); nsresult SetWindowIconList(const nsTArray &aIconList); diff -r 73cc9a2d8fc1 -r 3c2bd9158ad3 widget/windows/nsWindowGfx.cpp --- a/widget/windows/nsWindowGfx.cpp Tue May 10 22:58:47 2016 -0500 +++ b/widget/windows/nsWindowGfx.cpp Tue May 10 22:58:47 2016 -0500 @@ -298,6 +298,8 @@ clientLayerManager->SendInvalidRegion(region); } + RefPtr strongThis(this); + nsIWidgetListener* listener = GetPaintListener(); if (listener) { listener->WillPaintWindow(this);