Bug 582057, part g: Split nsIView::CreateWidget into CreateWidget, CreateWidgetForParent, and CreateWidgetForPopup in preparation of eliminating IIDs here. sr=roc
☠☠ backed out by 3dcc30237679 ☠ ☠
authorChris Jones <jones.chris.g@gmail.com>
Thu, 19 Aug 2010 13:49:35 -0500
changeset 50924 f1af117d459810a18daa1b069f73d29ff033b4c2
parent 50923 5bf0b315a5aa5fcddcae8628aaaff4513e0b85ba
child 50925 037a5d6b376a0e990bb27cbebfa37259f9c07fec
child 50956 3dcc302376790362a94d34a09b85602f15043477
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs582057
milestone2.0b5pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 582057, part g: Split nsIView::CreateWidget into CreateWidget, CreateWidgetForParent, and CreateWidgetForPopup in preparation of eliminating IIDs here. sr=roc
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsDocumentViewer.cpp
layout/base/nsPresShell.cpp
layout/generic/nsFrameFrame.cpp
layout/printing/nsPrintEngine.cpp
layout/xul/base/src/nsMenuPopupFrame.cpp
view/public/nsIView.h
view/src/nsView.cpp
view/src/nsView.h
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -3259,20 +3259,20 @@ nsCSSFrameConstructor::InitializeSelectF
       view->GetViewManager()->SetViewFloating(view, PR_TRUE);
 
       nsWidgetInitData widgetData;
       widgetData.mWindowType  = eWindowType_popup;
       widgetData.mBorderStyle = eBorderStyle_default;
 
 #if defined(XP_MACOSX) || defined(XP_BEOS) 
       static NS_DEFINE_IID(kCPopUpCID,  NS_POPUP_CID);
-      view->CreateWidget(kCPopUpCID, &widgetData, nsnull);
+      view->CreateWidgetForPopup(kCPopUpCID, &widgetData);
 #else
       static NS_DEFINE_IID(kCChildCID, NS_CHILD_CID);
-      view->CreateWidget(kCChildCID, &widgetData, nsnull);
+      view->CreateWidgetForPopup(kCChildCID, &widgetData);
 #endif
     }
   }
 
   BuildScrollFrame(aState, aContent, aStyleContext, scrolledFrame,
                    geometricParent, scrollFrame);
 
   if (aState.mFrameState && aState.mFrameManager) {
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -2315,19 +2315,23 @@ DocumentViewerImpl::MakeWindow(const nsS
 
   // The root view is always at 0,0.
   nsRect tbounds(nsPoint(0, 0), aSize);
   // Create a view
   nsIView* view = mViewManager->CreateView(tbounds, aContainerView);
   if (!view)
     return NS_ERROR_OUT_OF_MEMORY;
 
-  // Don't create a widget if we weren't given a parent widget but we
-  // have a container view we can hook up to without a widget
-  if (mParentWidget || !aContainerView) {
+  PRBool isExternalResource = !!mDocument->GetDisplayDocument();
+
+  // Create a widget if we were given a parent widget or don't have a
+  // container view that we can hook up to without a widget.  Don't
+  // create widgets for external resource documents, since they're not
+  // displayed.
+  if (!isExternalResource && (mParentWidget || !aContainerView)) {
     // pass in a native widget to be the parent widget ONLY if the view hierarchy will stand alone.
     // otherwise the view will find its own parent widget and "do the right thing" to
     // establish a parent/child widget relationship
     nsWidgetInitData initData;
     nsWidgetInitData* initDataPtr;
     if (!mParentWidget) {
       initDataPtr = &initData;
       initData.mWindowType = eWindowType_invisible;
@@ -2338,21 +2342,22 @@ DocumentViewerImpl::MakeWindow(const nsS
     } else {
       initDataPtr = nsnull;
     }
 
     if (mAttachedToParent) {
       // Reuse the top level parent widget.
       rv = view->AttachToTopLevelWidget(mParentWidget);
     }
+    else if (!aContainerView && mParentWidget) {
+      rv = view->CreateWidgetForParent(kWidgetCID, mParentWidget, initDataPtr,
+                                       PR_TRUE, PR_FALSE);
+    }
     else {
-      nsNativeWidget nw = (aContainerView != nsnull || !mParentWidget) ?
-                 nsnull : mParentWidget->GetNativeData(NS_NATIVE_WIDGET);
-      rv = view->CreateWidget(kWidgetCID, initDataPtr,
-                              nw, PR_TRUE, PR_FALSE);
+      rv = view->CreateWidget(kWidgetCID, initDataPtr, PR_TRUE, PR_FALSE);
     }
     if (NS_FAILED(rv))
       return rv;
   }
 
   // Setup hierarchical relationship in view manager
   mViewManager->SetRootView(view);
 
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -8263,32 +8263,32 @@ PresShell::VerifyIncrementalReflow()
   nsIDeviceContext *dc = mPresContext->DeviceContext();
   nsresult rv = cx->Init(dc);
   NS_ENSURE_SUCCESS(rv, PR_FALSE);
 
   // Get our scrolling preference
   nsIView* rootView;
   mViewManager->GetRootView(rootView);
   NS_ENSURE_TRUE(rootView->HasWidget(), PR_FALSE);
-  void* nativeParentWidget = rootView->GetWidget()->GetNativeData(NS_NATIVE_WIDGET);
+  nsIWidget* parentWidget = rootView->GetWidget();
 
   // Create a new view manager.
   nsCOMPtr<nsIViewManager> vm = do_CreateInstance(kViewManagerCID);
   NS_ENSURE_TRUE(vm, PR_FALSE);
   rv = vm->Init(dc);
   NS_ENSURE_SUCCESS(rv, PR_FALSE);
 
   // Create a child window of the parent that is our "root view/window"
   // Create a view
   nsRect tbounds = mPresContext->GetVisibleArea();
   nsIView* view = vm->CreateView(tbounds, nsnull);
   NS_ENSURE_TRUE(view, PR_FALSE);
 
   //now create the widget for the view
-  rv = view->CreateWidget(kWidgetCID, nsnull, nativeParentWidget, PR_TRUE);
+  rv = view->CreateWidgetForParent(kWidgetCID, parentWidget, nsnull, PR_TRUE);
   NS_ENSURE_SUCCESS(rv, PR_FALSE);
 
   // Setup hierarchical relationship in view manager
   vm->SetRootView(view);
 
   // Make the new presentation context the same size as our
   // presentation context.
   nsRect r = mPresContext->GetVisibleArea();
--- a/layout/generic/nsFrameFrame.cpp
+++ b/layout/generic/nsFrameFrame.cpp
@@ -962,17 +962,17 @@ nsSubDocumentFrame::CreateViewAndWidget(
     NS_ERROR("Could not create inner view");
     return nsnull;
   }
   mInnerView = innerView;
   viewMan->InsertChild(outerView, innerView, nsnull, PR_TRUE);
 
   if (aContentType == eContentTypeContent) {
     // widget needed.
-    nsresult rv = innerView->CreateWidget(kCChildCID, nsnull, nsnull,
+    nsresult rv = innerView->CreateWidget(kCChildCID, nsnull,
                                           PR_TRUE, PR_TRUE, aContentType);
     if (NS_FAILED(rv)) {
       NS_WARNING("Couldn't create widget for frame.");
       mInnerView = nsnull;
     }
   }
   return mInnerView;
 }
--- a/layout/printing/nsPrintEngine.cpp
+++ b/layout/printing/nsPrintEngine.cpp
@@ -1991,22 +1991,25 @@ nsPrintEngine::ReflowPrintObject(nsPrint
   nsRect tbounds = nsRect(nsPoint(0, 0), adjSize);
   nsIView* rootView = aPO->mViewManager->CreateView(tbounds, parentView);
   NS_ENSURE_TRUE(rootView, NS_ERROR_OUT_OF_MEMORY);
 
   // Only create a widget for print preview; when printing, a widget is
   // unnecessary and unexpected
   // Also, no widget should be needed except for the top-level document
   if (mIsCreatingPrintPreview && documentIsTopLevel) {
-    nsNativeWidget widget = nsnull;
+    nsIWidget* widget = nsnull;
     if (!frame)
-      widget = mParentWidget->GetNativeData(NS_NATIVE_WIDGET);
-    rv = rootView->CreateWidget(kWidgetCID, nsnull,
-                                widget, PR_TRUE, PR_TRUE,
-                                eContentTypeContent);
+      widget = mParentWidget;
+    rv = widget ? rootView->CreateWidgetForParent(kWidgetCID, widget, nsnull,
+                                                  PR_TRUE, PR_TRUE,
+                                                  eContentTypeContent)
+                : rootView->CreateWidget(kWidgetCID, nsnull,
+                                         PR_TRUE, PR_TRUE,
+                                         eContentTypeContent);
     NS_ENSURE_SUCCESS(rv, rv);
     aPO->mWindow = rootView->GetWidget();
     aPO->mPresContext->SetPaginatedScrolling(canCreateScrollbars);
   }
 
   // Setup hierarchical relationship in view manager
   aPO->mViewManager->SetRootView(rootView);
 
--- a/layout/xul/base/src/nsMenuPopupFrame.cpp
+++ b/layout/xul/base/src/nsMenuPopupFrame.cpp
@@ -317,22 +317,22 @@ nsMenuPopupFrame::CreateWidgetForView(ns
 
     nsCOMPtr<nsIBaseWindow> baseWindow(do_QueryInterface(treeOwner));
     if (baseWindow)
       baseWindow->GetMainWidget(getter_AddRefs(parentWidget));
   }
 
 #if defined(XP_MACOSX) || defined(XP_BEOS)
   static NS_DEFINE_IID(kCPopupCID,  NS_POPUP_CID);
-  aView->CreateWidget(kCPopupCID, &widgetData, nsnull, PR_TRUE, PR_TRUE, 
-                      eContentTypeUI, parentWidget);
+  aView->CreateWidgetForPopup(kCPopupCID, &widgetData, parentWidget,
+                              PR_TRUE, PR_TRUE, eContentTypeUI);
 #else
   static NS_DEFINE_IID(kCChildCID,  NS_CHILD_CID);
-  aView->CreateWidget(kCChildCID, &widgetData, nsnull, PR_TRUE, PR_TRUE,
-                      eContentTypeInherit, parentWidget);
+  aView->CreateWidgetForPopup(kCChildCID, &widgetData, parentWidget,
+                              PR_TRUE, PR_TRUE, eContentTypeInherit);
 #endif
   nsIWidget* widget = aView->GetWidget();
   widget->SetTransparencyMode(mode);
   widget->SetWindowShadowStyle(GetShadowStyle());
 
   // most popups don't have a title so avoid setting the title if there isn't one
   if (!title.IsEmpty()) {
     widget->SetTitle(title);
--- a/view/public/nsIView.h
+++ b/view/public/nsIView.h
@@ -56,20 +56,19 @@ class nsIWidget;
 // hide - the layer is not shown.
 // show - the layer is shown irrespective of the visibility of 
 //        the layer's parent.
 enum nsViewVisibility {
   nsViewVisibility_kHide = 0,
   nsViewVisibility_kShow = 1
 };
 
-// IID for the nsIView interface
 #define NS_IVIEW_IID    \
-  { 0xfb9900df, 0x5956, 0x4175, \
-    { 0x83, 0xba, 0x05, 0x74, 0x31, 0x96, 0x61, 0xee } }
+  { 0x01258624, 0xca90, 0x47a4, \
+    { 0xb1, 0xfd, 0x52, 0x11, 0x26, 0xe6, 0xc8, 0xdc } }
 
 // Public view flags are defined in this file
 #define NS_VIEW_FLAGS_PUBLIC              0x00FF
 // Private view flags are private to the view module,
 // and are defined in nsView.h
 #define NS_VIEW_FLAGS_PRIVATE             0xFF00
 
 // Public view flags
@@ -271,39 +270,60 @@ public:
    * don't have widgets at all (e.g., printing), but if any view in the view tree
    * has a widget, then it's safe to assume this will not return null
    * XXX Remove this 'virtual' when gfx+widget are merged into gklayout;
    * Mac widget depends on this method, which is BOGUS!
    */
   virtual nsIWidget* GetNearestWidget(nsPoint* aOffset) const;
 
   /**
-   * Create a widget to associate with this view.
+   * Create a widget to associate with this view.  This variant of
+   * CreateWidget*() will look around in the view hierarchy for an
+   * appropriate parent widget for the view.
+   *
    * @param aWindowIID IID for Widget type that this view
-   *        should have associated with it. if nsull, then no
-   *        width will be created for this view
+   *        should have associated with it.
    * @param aWidgetInitData data used to initialize this view's widget before
    *        its create is called.
-   * @param aNative native window that will be used as parent of
-   *        aWindowIID. if nsnull, then parent will be derived from
-   *        parent view and it's ancestors
-   * @param aWindowType is either content, UI or inherit from parent window.
+   * @param aContentType is either content, UI or inherit from parent window.
    *        This is used to expose what type of window this is to 
    *        assistive technology like screen readers.
-   * @param aParentWidget alternative parent to aNative used for popups. Must
-   *        be null for non-popups.
    * @return error status
    */
   nsresult CreateWidget(const nsIID &aWindowIID,
                         nsWidgetInitData *aWidgetInitData = nsnull,
-                        nsNativeWidget aNative = nsnull,
                         PRBool aEnableDragDrop = PR_TRUE,
                         PRBool aResetVisibility = PR_TRUE,
-                        nsContentType aWindowType = eContentTypeInherit,
-                        nsIWidget* aParentWidget = nsnull);
+                        nsContentType aContentType = eContentTypeInherit);
+
+  /**
+   * Create a widget for this view with an explicit parent widget.
+   * |aParentWidget| must be nonnull.  The other params are the same
+   * as for |CreateWidget()|.
+   */
+  nsresult CreateWidgetForParent(const nsIID &aWindowIID,
+                                 nsIWidget* aParentWidget,
+                                 nsWidgetInitData *aWidgetInitData = nsnull,
+                                 PRBool aEnableDragDrop = PR_TRUE,
+                                 PRBool aResetVisibility = PR_TRUE,
+                                 nsContentType aContentType = eContentTypeInherit);
+
+  /**
+   * Create a popup widget for this view.  Pass |aParentWidget| to
+   * explicitly set the popup's parent.  If it's not passed, the view
+   * hierarchy will be searched for an appropriate parent widget.  The
+   * other params are the same as for |CreateWidget()|, except that
+   * |aWidgetInitData| must be nonnull.
+   */
+  nsresult CreateWidgetForPopup(const nsIID &aWindowIID,
+                                nsWidgetInitData *aWidgetInitData,
+                                nsIWidget* aParentWidget = nsnull,
+                                PRBool aEnableDragDrop = PR_TRUE,
+                                PRBool aResetVisibility = PR_TRUE,
+                                nsContentType aContentType = eContentTypeInherit);
 
   /**
    * 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
    * gecko events. The underlying base window associated with the widget will
    * continues to receive events it expects.
    *
    * An attached widget will not be destroyed when the view is destroyed,
--- a/view/src/nsView.cpp
+++ b/view/src/nsView.cpp
@@ -655,43 +655,60 @@ static PRInt32 FindNonAutoZIndex(nsView*
     }
     aView = aView->GetParent();
   }
   return 0;
 }
 
 nsresult nsIView::CreateWidget(const nsIID &aWindowIID,
                                nsWidgetInitData *aWidgetInitData,
-                               nsNativeWidget aNative,
                                PRBool aEnableDragDrop,
                                PRBool aResetVisibility,
-                               nsContentType aContentType,
-                               nsIWidget* aParentWidget)
+                               nsContentType aContentType)
+{
+  return Impl()->CreateWidget(aWindowIID, aWidgetInitData,
+                              aEnableDragDrop, aResetVisibility,
+                              aContentType);
+}
+
+nsresult nsIView::CreateWidgetForParent(const nsIID &aWindowIID,
+                                        nsIWidget* aParentWidget,
+                                        nsWidgetInitData *aWidgetInitData,
+                                        PRBool aEnableDragDrop,
+                                        PRBool aResetVisibility,
+                                        nsContentType aContentType)
 {
-  return Impl()->CreateWidget(aWindowIID, aWidgetInitData, aNative,
-                              aEnableDragDrop, aResetVisibility,
-                              aContentType, aParentWidget);
+  return Impl()->CreateWidgetForParent(aWindowIID, aParentWidget, 
+                                       aWidgetInitData,
+                                       aEnableDragDrop, aResetVisibility,
+                                       aContentType);
+}
+
+nsresult nsIView::CreateWidgetForPopup(const nsIID &aWindowIID,
+                                       nsWidgetInitData *aWidgetInitData,
+                                       nsIWidget* aParentWidget,
+                                       PRBool aEnableDragDrop,
+                                       PRBool aResetVisibility,
+                                       nsContentType aContentType)
+{
+  return Impl()->CreateWidgetForPopup(aWindowIID, aWidgetInitData,
+                                      aParentWidget,
+                                      aEnableDragDrop, aResetVisibility,
+                                      aContentType);
 }
 
 nsresult nsView::CreateWidget(const nsIID &aWindowIID,
                               nsWidgetInitData *aWidgetInitData,
-                              nsNativeWidget aNative,
                               PRBool aEnableDragDrop,
                               PRBool aResetVisibility,
-                              nsContentType aContentType,
-                              nsIWidget* aParentWidget)
+                              nsContentType aContentType)
 {
-  if (NS_UNLIKELY(mWindow)) {
-    NS_ERROR("We already have a window for this view? BAD");
-    ViewWrapper* wrapper = GetWrapperFor(mWindow);
-    NS_IF_RELEASE(wrapper);
-    mWindow->SetClientData(nsnull);
-    mWindow->Destroy();
-    NS_RELEASE(mWindow);
-  }
+  NS_ABORT_IF_FALSE(!aWidgetInitData ||
+                    aWidgetInitData->mWindowType != eWindowType_popup,
+                    "Use CreateWidgetForPopup");
 
   nsresult rv = LoadWidget(aWindowIID);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   PRBool initDataPassedIn = PR_TRUE;
   nsWidgetInitData initData;
@@ -705,58 +722,111 @@ nsresult nsView::CreateWidget(const nsII
   }
   aWidgetInitData->mContentType = aContentType;
 
   nsIntRect trect = CalcWidgetBounds(aWidgetInitData->mWindowType);
 
   nsCOMPtr<nsIDeviceContext> dx;
   mViewManager->GetDeviceContext(*getter_AddRefs(dx));
 
-  if (aWidgetInitData->mWindowType == eWindowType_popup) {
-    if (aParentWidget) {
-      mWindow->Create(aParentWidget, nsnull, trect,
-                      ::HandleEvent, dx, nsnull, nsnull, aWidgetInitData);
-    }
-    else {
-      // XXX/cjones: having these two separate creation cases seems
-      // ... um ... unnecessary, but it's the way the old code did it.
-      // Please unify them by first finding a suitable parent nsIWidget,
-      // then passing only either the non-null parentWidget or the
-      // native ID to Create().
-      nsIWidget* nearestParent = GetParent() ? GetParent()->GetNearestWidget(nsnull)
-                                             : nsnull;
-      if (!nearestParent) {
-        // Without a parent, we can't make a popup.  This can happen
-        // when printing
-        return NS_ERROR_FAILURE;
-      }
+  initData.mListenForResizes = (!initDataPassedIn && GetParent() && 
+                                GetParent()->GetViewManager() != mViewManager);
+
+  nsIWidget* parentWidget =
+    GetParent() ? GetParent()->GetNearestWidget(nsnull) : nsnull;
+
+  mWindow->Create(parentWidget, nsnull,
+                  trect, ::HandleEvent, dx, nsnull, nsnull, aWidgetInitData);
+
+  InitializeWindow(aEnableDragDrop, aResetVisibility);
+
+  return NS_OK;
+}
+
+nsresult nsView::CreateWidgetForParent(const nsIID &aWindowIID,
+                                       nsIWidget* aParentWidget,
+                                       nsWidgetInitData *aWidgetInitData,
+                                       PRBool aEnableDragDrop,
+                                       PRBool aResetVisibility,
+                                       nsContentType aWindowType)
+{
+  NS_ABORT_IF_FALSE(!aWidgetInitData ||
+                    aWidgetInitData->mWindowType != eWindowType_popup,
+                    "Use CreateWidgetForPopup");
+  NS_ABORT_IF_FALSE(aParentWidget, "Parent widget required");
+
+  nsresult rv = LoadWidget(aWindowIID);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+
+  nsIntRect trect = CalcWidgetBounds(
+    aWidgetInitData ? aWidgetInitData->mWindowType : eWindowType_child);
+
+  nsCOMPtr<nsIDeviceContext> dx;
+  mViewManager->GetDeviceContext(*getter_AddRefs(dx));
 
-      mWindow->Create(nsnull, nearestParent->GetNativeData(NS_NATIVE_WIDGET), trect,
-                      ::HandleEvent, dx, nsnull, nsnull, aWidgetInitData);
-    }
+  mWindow->Create(nsnull, aParentWidget->GetNativeData(NS_NATIVE_WIDGET),
+                  trect, ::HandleEvent, dx, nsnull, nsnull, aWidgetInitData);
+
+  InitializeWindow(aEnableDragDrop, aResetVisibility);
+
+  return NS_OK;
+}
+
+nsresult nsView::CreateWidgetForPopup(const nsIID &aWindowIID,
+                                      nsWidgetInitData *aWidgetInitData,
+                                      nsIWidget* aParentWidget,
+                                      PRBool aEnableDragDrop,
+                                      PRBool aResetVisibility,
+                                      nsContentType aWindowType)
+{
+  NS_ABORT_IF_FALSE(aWidgetInitData, "Widget init data required");
+  NS_ABORT_IF_FALSE(aWidgetInitData->mWindowType == eWindowType_popup,
+                    "Use one of the other CreateWidget methods");
+
+  nsresult rv = LoadWidget(aWindowIID);
+  if (NS_FAILED(rv)) {
+    return rv;
   }
-  else if (aNative) {
-    mWindow->Create(nsnull, aNative, trect, ::HandleEvent, dx, nsnull, nsnull, aWidgetInitData);
+
+  nsIntRect trect = CalcWidgetBounds(aWidgetInitData->mWindowType);
+
+  nsCOMPtr<nsIDeviceContext> dx;
+  mViewManager->GetDeviceContext(*getter_AddRefs(dx));
+
+  // XXX/cjones: having these two separate creation cases seems ... um
+  // ... unnecessary, but it's the way the old code did it.  Please
+  // unify them by first finding a suitable parent nsIWidget, then
+  // passing only either the non-null parentWidget or the native ID to
+  // Create().
+  if (aParentWidget) {
+    mWindow->Create(aParentWidget, nsnull, trect,
+                    ::HandleEvent, dx, nsnull, nsnull, aWidgetInitData);
   }
   else {
-    initData.mListenForResizes = (!initDataPassedIn && GetParent() && 
-                                  GetParent()->GetViewManager() != mViewManager);
-    nsIWidget* parentWidget = GetParent() ? GetParent()->GetNearestWidget(nsnull)
-                                          : nsnull;
-    mWindow->Create(parentWidget, nsnull, trect,
+    nsIWidget* nearestParent = GetParent() ? GetParent()->GetNearestWidget(nsnull)
+                                           : nsnull;
+    if (!nearestParent) {
+      // Without a parent, we can't make a popup.  This can happen
+      // when printing
+      return NS_ERROR_FAILURE;
+    }
+
+    mWindow->Create(nsnull, nearestParent->GetNativeData(NS_NATIVE_WIDGET), trect,
                     ::HandleEvent, dx, nsnull, nsnull, aWidgetInitData);
   }
 
   InitializeWindow(aEnableDragDrop, aResetVisibility);
 
   return NS_OK;
 }
 
 void
-nsView::InitializeWindow(bool aEnableDragDrop, bool aResetVisibility)
+nsView::InitializeWindow(PRBool aEnableDragDrop, PRBool aResetVisibility)
 {
   NS_ABORT_IF_FALSE(mWindow, "Must have a window to initialize");
 
   if (aEnableDragDrop) {
     mWindow->EnableDragDrop(PR_TRUE);
   }
       
   // propagate the z-index to the widget.
@@ -836,17 +906,24 @@ void nsView::SetZIndex(PRBool aAuto, PRI
   }
 }
 
 //
 // internal window creation functions
 //
 nsresult nsView::LoadWidget(const nsCID &aClassIID)
 {
-  NS_ABORT_IF_FALSE(!mWindow, "Already have a widget?");
+  if (NS_UNLIKELY(mWindow)) {
+    NS_ERROR("We already have a window for this view? BAD");
+    ViewWrapper* wrapper = GetWrapperFor(mWindow);
+    NS_IF_RELEASE(wrapper);
+    mWindow->SetClientData(nsnull);
+    mWindow->Destroy();
+    NS_RELEASE(mWindow);
+  }
 
   nsresult rv = CallCreateInstance(aClassIID, &mWindow);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   ViewWrapper* wrapper = new ViewWrapper(this);
   NS_ADDREF(wrapper); // Will be released in ~nsView
--- a/view/src/nsView.h
+++ b/view/src/nsView.h
@@ -115,21 +115,35 @@ public:
   // Helper function to get mouse grabbing off this view (by moving it to the
   // parent, if we can)
   void DropMouseGrabbing();
 
 public:
   // See nsIView::CreateWidget.
   nsresult CreateWidget(const nsIID &aWindowIID,
                         nsWidgetInitData *aWidgetInitData,
-                        nsNativeWidget aNative,
                         PRBool aEnableDragDrop,
                         PRBool aResetVisibility,
-                        nsContentType aContentType,
-                        nsIWidget* aParentWidget);
+                        nsContentType aContentType);
+
+  // See nsIView::CreateWidgetForParent.
+  nsresult CreateWidgetForParent(const nsIID &aWindowIID,
+                                 nsIWidget* aParentWidget,
+                                 nsWidgetInitData *aWidgetInitData,
+                                 PRBool aEnableDragDrop,
+                                 PRBool aResetVisibility,
+                                 nsContentType aContentType);
+
+  // See nsIView::CreateWidgetForPopup.
+  nsresult CreateWidgetForPopup(const nsIID &aWindowIID,
+                                nsWidgetInitData *aWidgetInitData,
+                                nsIWidget* aParentWidget,
+                                PRBool aEnableDragDrop,
+                                PRBool aResetVisibility,
+                                nsContentType aContentType);
 
   // 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.
   nsView* GetFirstChild() const { return mFirstChild; }
   nsView* GetNextSibling() const { return mNextSibling; }
   nsView* GetParent() const { return mParent; }
   nsViewManager* GetViewManager() const { return mViewManager; }
@@ -191,12 +205,12 @@ public:
 protected:
   // Do the actual work of ResetWidgetBounds, unconditionally.  Don't
   // call this method if we have no widget.
   void DoResetWidgetBounds(PRBool aMoveOnly, PRBool aInvalidateChangedSize);
 
   nsRegion*    mDirtyRegion;
 
 private:
-  void InitializeWindow(bool aEnableDragDrop, bool aResetVisibility);
+  void InitializeWindow(PRBool aEnableDragDrop, PRBool aResetVisibility);
 };
 
 #endif