Bug 582057, part i: Use nsIWidget::CreateChild in nsIView::CreateWidget* (where possible). r=roc a=blocking-fennecb1
☠☠ backed out by f0a721242933 ☠ ☠
authorChris Jones <jones.chris.g@gmail.com>
Thu, 19 Aug 2010 13:49:35 -0500
changeset 50926 90ad165ae21bad04e6dfab4502215d28c2a33aea
parent 50925 037a5d6b376a0e990bb27cbebfa37259f9c07fec
child 50927 301875d4f9b61b760afd638274bcdc3addd29917
child 50952 f0a721242933c44dcc43a6044750264b239d8f7d
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, blocking-fennecb1
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 i: Use nsIWidget::CreateChild in nsIView::CreateWidget* (where possible). r=roc a=blocking-fennecb1
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
widget/src/cocoa/nsChildView.h
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -3256,24 +3256,17 @@ nsCSSFrameConstructor::InitializeSelectF
     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;
-
-#if defined(XP_MACOSX) || defined(XP_BEOS) 
-      static NS_DEFINE_IID(kCPopUpCID,  NS_POPUP_CID);
-      view->CreateWidgetForPopup(kCPopUpCID, &widgetData);
-#else
-      static NS_DEFINE_IID(kCChildCID, NS_CHILD_CID);
-      view->CreateWidgetForPopup(kCChildCID, &widgetData);
-#endif
+      view->CreateWidgetForPopup(&widgetData);
     }
   }
 
   BuildScrollFrame(aState, aContent, aStyleContext, scrolledFrame,
                    geometricParent, scrollFrame);
 
   if (aState.mFrameState && aState.mFrameManager) {
     // Restore frame state for the scroll frame
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -498,17 +498,16 @@ protected:
   PRPackedBool mHidden;
 };
 
 //------------------------------------------------------------------
 // DocumentViewerImpl
 //------------------------------------------------------------------
 // Class IDs
 static NS_DEFINE_CID(kViewManagerCID,       NS_VIEW_MANAGER_CID);
-static NS_DEFINE_CID(kWidgetCID,            NS_CHILD_CID);
 static NS_DEFINE_CID(kDeviceContextCID,     NS_DEVICE_CONTEXT_CID);
 
 //------------------------------------------------------------------
 nsresult
 NS_NewDocumentViewer(nsIDocumentViewer** aResult)
 {
   *aResult = new DocumentViewerImpl();
   if (!*aResult) {
@@ -2343,21 +2342,21 @@ DocumentViewerImpl::MakeWindow(const nsS
       initDataPtr = nsnull;
     }
 
     if (mAttachedToParent) {
       // Reuse the top level parent widget.
       rv = view->AttachToTopLevelWidget(mParentWidget);
     }
     else if (!aContainerView && mParentWidget) {
-      rv = view->CreateWidgetForParent(kWidgetCID, mParentWidget, initDataPtr,
+      rv = view->CreateWidgetForParent(mParentWidget, initDataPtr,
                                        PR_TRUE, PR_FALSE);
     }
     else {
-      rv = view->CreateWidget(kWidgetCID, initDataPtr, PR_TRUE, PR_FALSE);
+      rv = view->CreateWidget(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
@@ -7908,17 +7908,16 @@ nsIPresShell::RemoveRefreshObserverExter
 #ifdef NS_DEBUG
 #include "nsViewsCID.h"
 #include "nsWidgetsCID.h"
 #include "nsIDeviceContext.h"
 #include "nsIURL.h"
 #include "nsILinkHandler.h"
 
 static NS_DEFINE_CID(kViewManagerCID, NS_VIEW_MANAGER_CID);
-static NS_DEFINE_CID(kWidgetCID, NS_CHILD_CID);
 
 static void
 LogVerifyMessage(nsIFrame* k1, nsIFrame* k2, const char* aMsg)
 {
   nsAutoString n1, n2;
   if (k1) {
     k1->GetFrameName(n1);
   } else {
@@ -8278,17 +8277,17 @@ PresShell::VerifyIncrementalReflow()
 
   // 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->CreateWidgetForParent(kWidgetCID, parentWidget, nsnull, PR_TRUE);
+  rv = view->CreateWidgetForParent(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
@@ -99,18 +99,16 @@
 // For Accessibility
 #ifdef ACCESSIBILITY
 #include "nsIAccessibilityService.h"
 #endif
 #include "nsIServiceManager.h"
 
 class AsyncFrameInit;
 
-static NS_DEFINE_CID(kCChildCID, NS_CHILD_CID);
-
 /******************************************************************************
  * nsSubDocumentFrame
  *****************************************************************************/
 class nsSubDocumentFrame : public nsLeafFrame,
                            public nsIFrameFrame,
                            public nsIReflowCallback
 {
 public:
@@ -291,17 +289,17 @@ nsSubDocumentFrame::Init(nsIContent*    
   if (!HasView()) {
     rv = nsHTMLContainerFrame::CreateViewForFrame(this, PR_TRUE);
     NS_ENSURE_SUCCESS(rv, rv);
   }
   nsIView* view = GetView();
 
   if (aParent->GetStyleDisplay()->mDisplay == NS_STYLE_DISPLAY_DECK
       && !view->HasWidget()) {
-    view->CreateWidget(kCChildCID);
+    view->CreateWidget();
   }
 
   // Set the primary frame now so that
   // DocumentViewerImpl::FindContainerView called by ShowViewer below
   // can find it if necessary.
   aContent->SetPrimaryFrame(this);
 
   nsContentUtils::AddScriptRunner(new AsyncFrameInit(this));
@@ -962,17 +960,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,
+    nsresult rv = innerView->CreateWidget(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
@@ -244,17 +244,16 @@ public:
   void Disconnect() { mPrintEngine = nsnull; }
 protected:
   nsRefPtr<nsPrintEngine> mPrintEngine;
   PRBool                  mSuppressed;
 };
 
 // Class IDs
 static NS_DEFINE_CID(kViewManagerCID,       NS_VIEW_MANAGER_CID);
-static NS_DEFINE_CID(kWidgetCID,            NS_CHILD_CID);
 
 NS_IMPL_ISUPPORTS1(nsPrintEngine, nsIObserver)
 
 //---------------------------------------------------
 //-- nsPrintEngine Class Impl
 //---------------------------------------------------
 nsPrintEngine::nsPrintEngine() :
   mIsCreatingPrintPreview(PR_FALSE),
@@ -1994,20 +1993,20 @@ nsPrintEngine::ReflowPrintObject(nsPrint
 
   // 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) {
     nsIWidget* widget = nsnull;
     if (!frame)
       widget = mParentWidget;
-    rv = widget ? rootView->CreateWidgetForParent(kWidgetCID, widget, nsnull,
+    rv = widget ? rootView->CreateWidgetForParent(widget, nsnull,
                                                   PR_TRUE, PR_TRUE,
                                                   eContentTypeContent)
-                : rootView->CreateWidget(kWidgetCID, nsnull,
+                : rootView->CreateWidget(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
--- a/layout/xul/base/src/nsMenuPopupFrame.cpp
+++ b/layout/xul/base/src/nsMenuPopupFrame.cpp
@@ -315,25 +315,19 @@ nsMenuPopupFrame::CreateWidgetForView(ns
     dsti->GetTreeOwner(getter_AddRefs(treeOwner));
     if (!treeOwner) return NS_ERROR_FAILURE;
 
     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->CreateWidgetForPopup(kCPopupCID, &widgetData, parentWidget,
+  aView->CreateWidgetForPopup(&widgetData, parentWidget,
                               PR_TRUE, PR_TRUE, eContentTypeUI);
-#else
-  static NS_DEFINE_IID(kCChildCID,  NS_CHILD_CID);
-  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
@@ -57,18 +57,18 @@ class nsIWidget;
 // show - the layer is shown irrespective of the visibility of 
 //        the layer's parent.
 enum nsViewVisibility {
   nsViewVisibility_kHide = 0,
   nsViewVisibility_kShow = 1
 };
 
 #define NS_IVIEW_IID    \
-  { 0x01258624, 0xca90, 0x47a4, \
-    { 0xb1, 0xfd, 0x52, 0x11, 0x26, 0xe6, 0xc8, 0xdc } }
+  { 0xba00349c, 0xe58a, 0x436a, \
+    { 0x9f, 0x1f, 0x05, 0xb3, 0xdd, 0x9d, 0x9d, 0x36 } }
 
 // 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
@@ -274,52 +274,47 @@ public:
    */
   virtual nsIWidget* GetNearestWidget(nsPoint* aOffset) const;
 
   /**
    * 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.
    * @param aWidgetInitData data used to initialize this view's widget before
    *        its create is called.
    * @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.
    * @return error status
    */
-  nsresult CreateWidget(const nsIID &aWindowIID,
-                        nsWidgetInitData *aWidgetInitData = nsnull,
+  nsresult CreateWidget(nsWidgetInitData *aWidgetInitData = nsnull,
                         PRBool aEnableDragDrop = PR_TRUE,
                         PRBool aResetVisibility = PR_TRUE,
                         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,
+  nsresult CreateWidgetForParent(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,
+  nsresult CreateWidgetForPopup(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
--- a/view/src/nsView.cpp
+++ b/view/src/nsView.cpp
@@ -32,16 +32,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsView.h"
 #include "nsIWidget.h"
+#include "nsWidgetsCID.h"
 #include "nsViewManager.h"
 #include "nsGUIEvent.h"
 #include "nsIDeviceContext.h"
 #include "nsIComponentManager.h"
 #include "nsGfxCIID.h"
 #include "nsIRegion.h"
 #include "nsIInterfaceRequestor.h"
 
@@ -653,68 +654,58 @@ static PRInt32 FindNonAutoZIndex(nsView*
     if (!aView->GetZIndexIsAuto()) {
       return aView->GetZIndex();
     }
     aView = aView->GetParent();
   }
   return 0;
 }
 
-nsresult nsIView::CreateWidget(const nsIID &aWindowIID,
-                               nsWidgetInitData *aWidgetInitData,
+nsresult nsIView::CreateWidget(nsWidgetInitData *aWidgetInitData,
                                PRBool aEnableDragDrop,
                                PRBool aResetVisibility,
                                nsContentType aContentType)
 {
-  return Impl()->CreateWidget(aWindowIID, aWidgetInitData,
+  return Impl()->CreateWidget(aWidgetInitData,
                               aEnableDragDrop, aResetVisibility,
                               aContentType);
 }
 
-nsresult nsIView::CreateWidgetForParent(const nsIID &aWindowIID,
-                                        nsIWidget* aParentWidget,
+nsresult nsIView::CreateWidgetForParent(nsIWidget* aParentWidget,
                                         nsWidgetInitData *aWidgetInitData,
                                         PRBool aEnableDragDrop,
                                         PRBool aResetVisibility,
                                         nsContentType aContentType)
 {
-  return Impl()->CreateWidgetForParent(aWindowIID, aParentWidget, 
-                                       aWidgetInitData,
+  return Impl()->CreateWidgetForParent(aParentWidget, aWidgetInitData,
                                        aEnableDragDrop, aResetVisibility,
                                        aContentType);
 }
 
-nsresult nsIView::CreateWidgetForPopup(const nsIID &aWindowIID,
-                                       nsWidgetInitData *aWidgetInitData,
+nsresult nsIView::CreateWidgetForPopup(nsWidgetInitData *aWidgetInitData,
                                        nsIWidget* aParentWidget,
                                        PRBool aEnableDragDrop,
                                        PRBool aResetVisibility,
                                        nsContentType aContentType)
 {
-  return Impl()->CreateWidgetForPopup(aWindowIID, aWidgetInitData,
-                                      aParentWidget,
+  return Impl()->CreateWidgetForPopup(aWidgetInitData, aParentWidget,
                                       aEnableDragDrop, aResetVisibility,
                                       aContentType);
 }
 
-nsresult nsView::CreateWidget(const nsIID &aWindowIID,
-                              nsWidgetInitData *aWidgetInitData,
+nsresult nsView::CreateWidget(nsWidgetInitData *aWidgetInitData,
                               PRBool aEnableDragDrop,
                               PRBool aResetVisibility,
                               nsContentType aContentType)
 {
+  AssertNoWindow();
   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;
   if (!aWidgetInitData) {
     // No initData, we're a child window
     initDataPassedIn = PR_FALSE;
     initData.mWindowType = eWindowType_child;
     initData.clipChildren = PR_TRUE;
     initData.clipSiblings = PR_TRUE;
@@ -724,112 +715,125 @@ nsresult nsView::CreateWidget(const nsII
 
   nsIntRect trect = CalcWidgetBounds(aWidgetInitData->mWindowType);
 
   nsCOMPtr<nsIDeviceContext> dx;
   mViewManager->GetDeviceContext(*getter_AddRefs(dx));
 
   initData.mListenForResizes = (!initDataPassedIn && GetParent() && 
                                 GetParent()->GetViewManager() != mViewManager);
-
   nsIWidget* parentWidget =
     GetParent() ? GetParent()->GetNearestWidget(nsnull) : nsnull;
+  if (!parentWidget) {
+    NS_ERROR("nsView::CreateWidget without suitable parent widget??");
+    return NS_ERROR_FAILURE;
+  }
 
-  mWindow->Create(parentWidget, nsnull,
-                  trect, ::HandleEvent, dx, nsnull, nsnull, aWidgetInitData);
-
+  // XXX: using aForceUseIWidgetParent=true to preserve previous
+  // semantics.  It's not clear that it's actually needed.
+  mWindow = parentWidget->CreateChild(trect, ::HandleEvent,
+                                      dx, nsnull, nsnull, aWidgetInitData,
+                                      PR_TRUE).get();
+  if (!mWindow) {
+    return NS_ERROR_FAILURE;
+  }
+ 
   InitializeWindow(aEnableDragDrop, aResetVisibility);
 
   return NS_OK;
 }
 
-nsresult nsView::CreateWidgetForParent(const nsIID &aWindowIID,
-                                       nsIWidget* aParentWidget,
+nsresult nsView::CreateWidgetForParent(nsIWidget* aParentWidget,
                                        nsWidgetInitData *aWidgetInitData,
                                        PRBool aEnableDragDrop,
                                        PRBool aResetVisibility,
                                        nsContentType aWindowType)
 {
+  AssertNoWindow();
   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, aParentWidget->GetNativeData(NS_NATIVE_WIDGET),
-                  trect, ::HandleEvent, dx, nsnull, nsnull, aWidgetInitData);
+  mWindow =
+    aParentWidget->CreateChild(trect, ::HandleEvent,
+                               dx, nsnull, nsnull, aWidgetInitData).get();
+  if (!mWindow) {
+    return NS_ERROR_FAILURE;
+  }
 
   InitializeWindow(aEnableDragDrop, aResetVisibility);
 
   return NS_OK;
 }
 
-nsresult nsView::CreateWidgetForPopup(const nsIID &aWindowIID,
-                                      nsWidgetInitData *aWidgetInitData,
+nsresult nsView::CreateWidgetForPopup(nsWidgetInitData *aWidgetInitData,
                                       nsIWidget* aParentWidget,
                                       PRBool aEnableDragDrop,
                                       PRBool aResetVisibility,
                                       nsContentType aWindowType)
 {
+  AssertNoWindow();
   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;
-  }
-
   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().
+  // getting rid of aForceUseIWidgetParent.
   if (aParentWidget) {
-    mWindow->Create(aParentWidget, nsnull, trect,
-                    ::HandleEvent, dx, nsnull, nsnull, aWidgetInitData);
+    // XXX: using aForceUseIWidgetParent=true to preserve previous
+    // semantics.  It's not clear that it's actually needed.
+    mWindow = aParentWidget->CreateChild(trect, ::HandleEvent,
+                                         dx, nsnull, nsnull, aWidgetInitData,
+                                         PR_TRUE).get();
   }
   else {
     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);
+    mWindow =
+      nearestParent->CreateChild(trect, ::HandleEvent,
+                                 dx, nsnull, nsnull, aWidgetInitData).get();
+  }
+  if (!mWindow) {
+    return NS_ERROR_FAILURE;
   }
 
   InitializeWindow(aEnableDragDrop, aResetVisibility);
 
   return NS_OK;
 }
 
 void
 nsView::InitializeWindow(PRBool aEnableDragDrop, PRBool aResetVisibility)
 {
   NS_ABORT_IF_FALSE(mWindow, "Must have a window to initialize");
 
+  ViewWrapper* wrapper = new ViewWrapper(this);
+  NS_ADDREF(wrapper); // Will be released in ~nsView
+  mWindow->SetClientData(wrapper);
+
   if (aEnableDragDrop) {
     mWindow->EnableDragDrop(PR_TRUE);
   }
       
   // propagate the z-index to the widget.
   UpdateNativeWidgetZIndexes(this, FindNonAutoZIndex(this));
 
   //make sure visibility state is accurate
@@ -901,41 +905,32 @@ void nsView::SetZIndex(PRBool aAuto, PRI
   mZIndex = aZIndex;
   SetTopMost(aTopMost);
   
   if (HasWidget() || !oldIsAuto || !aAuto) {
     UpdateNativeWidgetZIndexes(this, FindNonAutoZIndex(this));
   }
 }
 
-//
-// internal window creation functions
-//
-nsresult nsView::LoadWidget(const nsCID &aClassIID)
+void nsView::AssertNoWindow()
 {
+  // XXX: it would be nice to make this a strong assert
   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
-  mWindow->SetClientData(wrapper);
-  return rv;
 }
 
+//
+// internal window creation functions
+//
 EVENT_CALLBACK nsIView::AttachWidgetEventHandler(nsIWidget* aWidget)
 {
 #ifdef DEBUG
   void* data = nsnull;
   aWidget->GetClientData(data);
   NS_ASSERTION(!data, "Already got client data");
 #endif
 
--- a/view/src/nsView.h
+++ b/view/src/nsView.h
@@ -113,33 +113,30 @@ 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,
+  nsresult CreateWidget(nsWidgetInitData *aWidgetInitData,
                         PRBool aEnableDragDrop,
                         PRBool aResetVisibility,
                         nsContentType aContentType);
 
   // See nsIView::CreateWidgetForParent.
-  nsresult CreateWidgetForParent(const nsIID &aWindowIID,
-                                 nsIWidget* aParentWidget,
+  nsresult CreateWidgetForParent(nsIWidget* aParentWidget,
                                  nsWidgetInitData *aWidgetInitData,
                                  PRBool aEnableDragDrop,
                                  PRBool aResetVisibility,
                                  nsContentType aContentType);
 
   // See nsIView::CreateWidgetForPopup.
-  nsresult CreateWidgetForPopup(const nsIID &aWindowIID,
-                                nsWidgetInitData *aWidgetInitData,
+  nsresult CreateWidgetForPopup(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.
@@ -180,17 +177,17 @@ public:
   void SetViewFlags(PRUint32 aFlags) { mVFlags = aFlags; }
 
   void SetTopMost(PRBool aTopMost) { aTopMost ? mVFlags |= NS_VIEW_FLAG_TOPMOST : mVFlags &= ~NS_VIEW_FLAG_TOPMOST; }
   PRBool IsTopMost() { return((mVFlags & NS_VIEW_FLAG_TOPMOST) != 0); }
 
   nsPoint ConvertFromParentCoords(nsPoint aPt) const;
   void ResetWidgetBounds(PRBool aRecurse, PRBool aMoveOnly, PRBool aInvalidateChangedSize);
   void SetPositionIgnoringChildWidgets(nscoord aX, nscoord aY);
-  nsresult LoadWidget(const nsCID &aClassIID);
+  void AssertNoWindow();
 
   void NotifyEffectiveVisibilityChanged(PRBool aEffectivelyVisible);
 
   // Update the cached RootViewManager for all view manager descendents,
   // If the hierarchy is being removed, aViewManagerParent points to the view
   // manager for the hierarchy's old parent, and will have its mouse grab
   // released if it points to any view in this view hierarchy.
   void InvalidateHierarchy(nsViewManager *aViewManagerParent);
--- a/widget/src/cocoa/nsChildView.h
+++ b/widget/src/cocoa/nsChildView.h
@@ -409,16 +409,24 @@ protected:
   PRBool            ReportSizeEvent();
 
   // override to create different kinds of child views. Autoreleases, so
   // caller must retain.
   virtual NSView*   CreateCocoaView(NSRect inFrame);
   void              TearDownView();
   nsCocoaWindow*    GetXULWindowWidget();
 
+  virtual already_AddRefed<nsIWidget>
+  AllocateChildPopupWidget()
+  {
+    static NS_DEFINE_IID(kCPopUpCID, NS_POPUP_CID);
+    nsCOMPtr<nsIWidget> widget = do_CreateInstance(kCPopUpCID);
+    return widget.forget();
+  }
+
 protected:
 
   NSView<mozView>*      mView;      // my parallel cocoa view (ChildView or NativeScrollbarView), [STRONG]
   nsCocoaTextInputHandler mTextInputHandler;
 
   NSView<mozView>*      mParentView;
   nsIWidget*            mParentWidget;