Bug 610391 - Create the widget for drop-down comboboxes lazily, and tear it down when the drop-down is closed; r=roc

This commit is contained in:
Ehsan Akhgari 2011-03-21 14:28:10 -04:00
parent ae216c0d07
commit 3bb129e1e3
5 changed files with 49 additions and 21 deletions

View File

@ -3216,19 +3216,6 @@ nsCSSFrameConstructor::InitializeSelectFrame(nsFrameConstructorState& aState,
}
nsHTMLContainerFrame::CreateViewForFrame(scrollFrame, aBuildCombobox);
if (aBuildCombobox) {
// Give the drop-down list a popup widget
nsIView* view = scrollFrame->GetView();
NS_ASSERTION(view, "We asked for a view but didn't get one");
if (view) {
view->GetViewManager()->SetViewFloating(view, PR_TRUE);
nsWidgetInitData widgetData;
widgetData.mWindowType = eWindowType_popup;
widgetData.mBorderStyle = eBorderStyle_default;
view->CreateWidgetForPopup(&widgetData);
}
}
BuildScrollFrame(aState, aContent, aStyleContext, scrolledFrame,
geometricParent, scrollFrame);

View File

@ -387,6 +387,21 @@ nsComboboxControlFrame::ShowList(PRBool aShowList)
nsCOMPtr<nsIPresShell> shell = PresContext()->GetPresShell();
nsWeakFrame weakFrame(this);
if (aShowList) {
nsIView* view = mDropdownFrame->GetView();
NS_ASSERTION(!view->HasWidget(),
"We shoudldn't have a widget before we need to display the popup");
// Create the widget for the drop-down list
view->GetViewManager()->SetViewFloating(view, PR_TRUE);
nsWidgetInitData widgetData;
widgetData.mWindowType = eWindowType_popup;
widgetData.mBorderStyle = eBorderStyle_default;
view->CreateWidgetForPopup(&widgetData);
}
ShowPopup(aShowList); // might destroy us
if (!weakFrame.IsAlive()) {
return PR_FALSE;
@ -412,8 +427,13 @@ nsComboboxControlFrame::ShowList(PRBool aShowList)
NS_ASSERTION(view, "nsComboboxControlFrame view is null");
if (view) {
nsIWidget* widget = view->GetWidget();
if (widget)
if (widget) {
widget->CaptureRollupEvents(this, nsnull, mDroppedDown, mDroppedDown);
if (!aShowList) {
view->DestroyWidget();
}
}
}
}

View File

@ -62,8 +62,8 @@ enum nsViewVisibility {
};
#define NS_IVIEW_IID \
{ 0xd0c2cf54, 0xb527, 0x4d8e, \
{ 0xba, 0x87, 0x39, 0x03, 0xa7, 0xc4, 0x13, 0xe1 } }
{ 0x63052d96, 0x2a4b, 0x434f, \
{ 0xb4, 0xd3, 0x61, 0x41, 0x83, 0x24, 0x00, 0x76 } }
// Public view flags are defined in this file
#define NS_VIEW_FLAGS_PUBLIC 0x00FF
@ -313,6 +313,13 @@ public:
PRBool aEnableDragDrop = PR_TRUE,
PRBool aResetVisibility = PR_TRUE);
/**
* Destroys the associated widget for this view. If this method is
* not called explicitly, the widget when be destroyed when its
* view gets destroyed.
*/
void DestroyWidget();
/**
* Attach/detach a top level widget from this view. When attached, the view
* updates the widget's device context and allows the view to begin receiving

View File

@ -268,6 +268,17 @@ nsView::~nsView()
}
// Destroy and release the widget
DestroyWidget();
delete mDirtyRegion;
if (mDeletionObserver) {
mDeletionObserver->Clear();
}
}
void nsView::DestroyWidget()
{
if (mWindow)
{
// Release memory for the view wrapper
@ -291,11 +302,6 @@ nsView::~nsView()
NS_RELEASE(mWindow);
}
delete mDirtyRegion;
if (mDeletionObserver) {
mDeletionObserver->Clear();
}
}
nsresult nsView::QueryInterface(const nsIID& aIID, void** aInstancePtr)
@ -685,6 +691,11 @@ nsresult nsIView::CreateWidgetForPopup(nsWidgetInitData *aWidgetInitData,
aEnableDragDrop, aResetVisibility);
}
void nsIView::DestroyWidget()
{
Impl()->DestroyWidget();
}
struct DefaultWidgetInitData : public nsWidgetInitData {
DefaultWidgetInitData() : nsWidgetInitData()
{

View File

@ -134,6 +134,9 @@ public:
PRBool aEnableDragDrop,
PRBool aResetVisibility);
// See nsIView::DestroyWidget
void DestroyWidget();
// NOT in nsIView, so only available in view module
// These are also present in nsIView, but these versions return nsView and nsViewManager
// instead of nsIView and nsIViewManager.