Bug 582057, part g: Split nsIView::CreateWidget into CreateWidget, CreateWidgetForParent, and CreateWidgetForPopup in preparation of eliminating IIDs here. sr=roc

This commit is contained in:
Chris Jones 2010-08-20 14:29:02 -05:00
parent d7454a33bb
commit 3cc44e2456
9 changed files with 205 additions and 86 deletions

View File

@ -3264,10 +3264,10 @@ nsCSSFrameConstructor::InitializeSelectFrame(nsFrameConstructorState& aState,
#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
}
}

View File

@ -2320,9 +2320,13 @@ DocumentViewerImpl::MakeWindow(const nsSize& aSize, nsIView* 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
@ -2343,11 +2347,12 @@ DocumentViewerImpl::MakeWindow(const nsSize& aSize, nsIView* aContainerView)
// 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;

View File

@ -8268,7 +8268,7 @@ PresShell::VerifyIncrementalReflow()
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);
@ -8283,7 +8283,7 @@ PresShell::VerifyIncrementalReflow()
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

View File

@ -967,7 +967,7 @@ nsSubDocumentFrame::CreateViewAndWidget(nsContentType aContentType)
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.");

View File

@ -1996,12 +1996,15 @@ nsPrintEngine::ReflowPrintObject(nsPrintObject * aPO)
// 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);

View File

@ -322,12 +322,12 @@ nsMenuPopupFrame::CreateWidgetForView(nsIView* aView)
#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);

View File

@ -61,10 +61,9 @@ enum nsViewVisibility {
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
@ -276,29 +275,50 @@ public:
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

View File

@ -660,33 +660,50 @@ static PRInt32 FindNonAutoZIndex(nsView* aView)
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, aNative,
return Impl()->CreateWidget(aWindowIID, aWidgetInitData,
aEnableDragDrop, aResetVisibility,
aContentType, aParentWidget);
aContentType);
}
nsresult nsIView::CreateWidgetForParent(const nsIID &aWindowIID,
nsIWidget* aParentWidget,
nsWidgetInitData *aWidgetInitData,
PRBool aEnableDragDrop,
PRBool aResetVisibility,
nsContentType aContentType)
{
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)) {
@ -710,38 +727,91 @@ nsresult nsView::CreateWidget(const nsIID &aWindowIID,
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);
mWindow->Create(nsnull, nearestParent->GetNativeData(NS_NATIVE_WIDGET), trect,
::HandleEvent, dx, nsnull, nsnull, aWidgetInitData);
}
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;
}
else if (aNative) {
mWindow->Create(nsnull, aNative, trect, ::HandleEvent, dx, nsnull, nsnull, aWidgetInitData);
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);
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;
}
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);
}
@ -751,7 +821,7 @@ nsresult nsView::CreateWidget(const nsIID &aWindowIID,
}
void
nsView::InitializeWindow(bool aEnableDragDrop, bool aResetVisibility)
nsView::InitializeWindow(PRBool aEnableDragDrop, PRBool aResetVisibility)
{
NS_ABORT_IF_FALSE(mWindow, "Must have a window to initialize");
@ -841,7 +911,14 @@ void nsView::SetZIndex(PRBool aAuto, PRInt32 aZIndex, PRBool aTopMost)
//
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)) {

View File

@ -120,11 +120,25 @@ 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
@ -196,7 +210,7 @@ protected:
nsRegion* mDirtyRegion;
private:
void InitializeWindow(bool aEnableDragDrop, bool aResetVisibility);
void InitializeWindow(PRBool aEnableDragDrop, PRBool aResetVisibility);
};
#endif