Bug 813442 - CaptureRollupEvents(false) before calling anything that can destroy us. r=roc

This commit is contained in:
Mats Palmgren 2013-02-05 18:19:15 +01:00
parent 3b2a23ea54
commit 2e75758b6d

View File

@ -350,12 +350,8 @@ nsComboboxControlFrame::ShowPopup(bool aShowPopup)
bool
nsComboboxControlFrame::ShowList(bool aShowList)
{
nsCOMPtr<nsIPresShell> 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<nsIRunnable> 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<nsIRunnable> 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);
}
}