Bug 813442 - Do the DestroyWidget() synchronously with a strong ref on the widget so that it's not deleted, drop the ref asynchronously later. r=roc

This commit is contained in:
Mats Palmgren 2013-02-05 18:19:15 +01:00
Родитель 0508d1fe86
Коммит 72c7697d68
1 изменённых файлов: 7 добавлений и 38 удалений

Просмотреть файл

@ -136,52 +136,18 @@ class DestroyWidgetRunnable : public nsRunnable {
public:
NS_DECL_NSIRUNNABLE
explicit DestroyWidgetRunnable(nsIContent* aCombobox) :
mCombobox(aCombobox),
mWidget(GetWidget())
{
}
explicit DestroyWidgetRunnable(nsIWidget* aWidget) : mWidget(aWidget) {}
private:
nsIWidget* GetWidget(nsView** aOutView = nullptr) const;
private:
nsCOMPtr<nsIContent> mCombobox;
nsIWidget* mWidget;
nsCOMPtr<nsIWidget> mWidget;
};
NS_IMETHODIMP DestroyWidgetRunnable::Run()
{
nsView* view = nullptr;
nsIWidget* currentWidget = GetWidget(&view);
// Make sure that we are destroying the same widget as what was requested
// when the event was fired.
if (view && mWidget && mWidget == currentWidget) {
view->DestroyWidget();
}
mWidget = nullptr;
return NS_OK;
}
nsIWidget* DestroyWidgetRunnable::GetWidget(nsView** aOutView) const
{
nsIFrame* primaryFrame = mCombobox->GetPrimaryFrame();
nsIComboboxControlFrame* comboboxFrame = do_QueryFrame(primaryFrame);
if (comboboxFrame) {
nsIFrame* dropdown = comboboxFrame->GetDropDown();
if (dropdown) {
nsView* view = dropdown->GetView();
NS_ASSERTION(view, "nsComboboxControlFrame view is null");
if (aOutView) {
*aOutView = view;
}
if (view) {
return view->GetWidget();
}
}
}
return nullptr;
}
}
//-----------------------------------------------------------
@ -432,7 +398,10 @@ nsComboboxControlFrame::ShowList(bool aShowList)
if (!aShowList) {
nsCOMPtr<nsIRunnable> widgetDestroyer =
new DestroyWidgetRunnable(GetContent());
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);
}
}