Bug 682041 - Don't destroy the select drop-down widget right away, instead wait to hit the event loop once, in case we're being called by the widget code itself somewhere down the stack; r=roc

This commit is contained in:
Ehsan Akhgari 2011-09-08 11:35:33 -04:00
Родитель 51214de074
Коммит e3552b96ea
1 изменённых файлов: 56 добавлений и 1 удалений

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

@ -169,6 +169,59 @@ NS_NewComboboxControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, P
NS_IMPL_FRAMEARENA_HELPERS(nsComboboxControlFrame)
namespace {
class DestroyWidgetRunnable : public nsRunnable {
public:
NS_DECL_NSIRUNNABLE
explicit DestroyWidgetRunnable(nsIContent* aCombobox) :
mCombobox(aCombobox),
mWidget(GetWidget())
{
}
private:
nsIWidget* GetWidget(nsIView** aOutView = nsnull) const;
private:
nsCOMPtr<nsIContent> mCombobox;
nsIWidget* mWidget;
};
NS_IMETHODIMP DestroyWidgetRunnable::Run()
{
nsIView* view = nsnull;
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();
}
}
nsIWidget* DestroyWidgetRunnable::GetWidget(nsIView** aOutView) const
{
nsIFrame* primaryFrame = mCombobox->GetPrimaryFrame();
nsIComboboxControlFrame* comboboxFrame = do_QueryFrame(primaryFrame);
if (comboboxFrame) {
nsIFrame* dropdown = comboboxFrame->GetDropDown();
if (dropdown) {
nsIView* view = dropdown->GetView();
NS_ASSERTION(view, "nsComboboxControlFrame view is null");
if (aOutView) {
*aOutView = view;
}
if (view) {
return view->GetWidget();
}
}
}
return nsnull;
}
}
//-----------------------------------------------------------
// Reflow Debugging Macros
// These let us "see" how many reflow counts are happening
@ -423,7 +476,9 @@ nsComboboxControlFrame::ShowList(PRBool aShowList)
widget->CaptureRollupEvents(this, nsnull, mDroppedDown, mDroppedDown);
if (!aShowList) {
view->DestroyWidget();
nsCOMPtr<nsIRunnable> widgetDestroyer =
new DestroyWidgetRunnable(GetContent());
NS_DispatchToMainThread(widgetDestroyer);
}
}
}