From 8a30fce5dd188cf8763e383808706f8dcff41230 Mon Sep 17 00:00:00 2001 From: Mats Palmgren Date: Tue, 5 Feb 2013 18:19:15 +0100 Subject: [PATCH] Bug 813442 - CaptureRollupEvents(false) before calling anything that can destroy us. r=roc --- layout/forms/nsComboboxControlFrame.cpp | 51 ++++++++++--------------- 1 file changed, 20 insertions(+), 31 deletions(-) diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp index 6cec55efd1e3..9ecfa58a2177 100644 --- a/layout/forms/nsComboboxControlFrame.cpp +++ b/layout/forms/nsComboboxControlFrame.cpp @@ -350,12 +350,8 @@ nsComboboxControlFrame::ShowPopup(bool aShowPopup) bool nsComboboxControlFrame::ShowList(bool aShowList) { - nsCOMPtr shell = PresContext()->GetPresShell(); - - nsWeakFrame weakFrame(this); - + nsView* view = mDropdownFrame->GetView(); if (aShowList) { - nsView* view = mDropdownFrame->GetView(); NS_ASSERTION(!view->HasWidget(), "We shouldn't have a widget before we need to display the popup"); @@ -366,45 +362,38 @@ nsComboboxControlFrame::ShowList(bool aShowList) widgetData.mWindowType = eWindowType_popup; widgetData.mBorderStyle = eBorderStyle_default; view->CreateWidgetForPopup(&widgetData); + } else { + nsIWidget* widget = view->GetWidget(); + if (widget) { + // We must do this before ShowPopup in case it destroys us (bug 813442). + widget->CaptureRollupEvents(this, false); + } } + nsWeakFrame weakFrame(this); ShowPopup(aShowList); // might destroy us if (!weakFrame.IsAlive()) { return false; } mDroppedDown = aShowList; + nsIWidget* widget = view->GetWidget(); if (mDroppedDown) { // The listcontrol frame will call back to the nsComboboxControlFrame's // ListWasSelected which will stop the capture. mListControlFrame->AboutToDropDown(); mListControlFrame->CaptureMouseEvents(true); - } - - // XXXbz so why do we need to flush here, exactly? - shell->GetDocument()->FlushPendingNotifications(Flush_Layout); - if (!weakFrame.IsAlive()) { - return false; - } - - nsIFrame* listFrame = do_QueryFrame(mListControlFrame); - if (listFrame) { - nsView* view = listFrame->GetView(); - NS_ASSERTION(view, "nsComboboxControlFrame view is null"); - if (view) { - nsIWidget* widget = view->GetWidget(); - if (widget) { - widget->CaptureRollupEvents(this, mDroppedDown); - - if (!aShowList) { - nsCOMPtr widgetDestroyer = - new DestroyWidgetRunnable(widget); - // 'widgetDestroyer' now has a strong ref on the widget so calling - // DestroyWidget here will not *delete* it. - view->DestroyWidget(); - NS_DispatchToMainThread(widgetDestroyer); - } - } + if (widget) { + widget->CaptureRollupEvents(this, true); + } + } else { + if (widget) { + nsCOMPtr widgetDestroyer = + new DestroyWidgetRunnable(widget); + // 'widgetDestroyer' now has a strong ref on the widget so calling + // DestroyWidget here will not *delete* it. + view->DestroyWidget(); + NS_DispatchToMainThread(widgetDestroyer); } }