diff --git a/mozilla/content/events/src/nsDOMEvent.cpp b/mozilla/content/events/src/nsDOMEvent.cpp index 7acfecdec2c..60b839d8ef7 100644 --- a/mozilla/content/events/src/nsDOMEvent.cpp +++ b/mozilla/content/events/src/nsDOMEvent.cpp @@ -336,11 +336,7 @@ NS_METHOD nsDOMEvent::GetClientX(PRInt32* aClientX) nsIViewManager* vm; shell->GetViewManager(&vm); if (vm) { - nsIView* rootView = nsnull; - vm->GetRootView(rootView); - if (rootView) { - rootView->GetWidget(rootWidget); - } + vm->GetWidget(&rootWidget); NS_RELEASE(vm); } NS_RELEASE(shell); @@ -385,11 +381,7 @@ NS_METHOD nsDOMEvent::GetClientY(PRInt32* aClientY) nsIViewManager* vm; shell->GetViewManager(&vm); if (vm) { - nsIView* rootView = nsnull; - vm->GetRootView(rootView); - if (rootView) { - rootView->GetWidget(rootWidget); - } + vm->GetWidget(&rootWidget); NS_RELEASE(vm); } NS_RELEASE(shell); diff --git a/mozilla/content/events/src/nsEventStateManager.cpp b/mozilla/content/events/src/nsEventStateManager.cpp index a184330b7ae..f93994307d1 100644 --- a/mozilla/content/events/src/nsEventStateManager.cpp +++ b/mozilla/content/events/src/nsEventStateManager.cpp @@ -958,14 +958,7 @@ nsEventStateManager::PostHandleEvent(nsIPresContext* aPresContext, if (NS_OK == aView->GetViewManager(vm) && nsnull != vm) { // I'd use Composite here, but it doesn't always work. // vm->Composite(); - nsIView* rootView = nsnull; - if (NS_OK == vm->GetRootView(rootView) && nsnull != rootView) { - nsIWidget* rootWidget = nsnull; - if (NS_OK == rootView->GetWidget(rootWidget) && nsnull != rootWidget) { - rootWidget->Update(); - NS_RELEASE(rootWidget); - } - } + vm->ForceUpdate(); NS_RELEASE(vm); } } @@ -2461,15 +2454,7 @@ void nsEventStateManager::ForceViewUpdate(nsIView* aView) if (NS_OK == aView->GetViewManager(vm) && nsnull != vm) { // I'd use Composite here, but it doesn't always work. // vm->Composite(); - nsIView* rootView = nsnull; - if (NS_OK == vm->GetRootView(rootView) && nsnull != rootView) { - nsIWidget* rootWidget = nsnull; - if (NS_OK == rootView->GetWidget(rootWidget) && - nsnull != rootWidget) { - rootWidget->Update(); - NS_RELEASE(rootWidget); - } - } + vm->ForceUpdate(); NS_RELEASE(vm); } } diff --git a/mozilla/dom/src/base/nsGlobalWindow.cpp b/mozilla/dom/src/base/nsGlobalWindow.cpp index 41aa8e9617d..3985fdbb14d 100644 --- a/mozilla/dom/src/base/nsGlobalWindow.cpp +++ b/mozilla/dom/src/base/nsGlobalWindow.cpp @@ -1325,15 +1325,10 @@ GlobalWindowImpl::Focus() nsIViewManager *vm = nsnull; shell->GetViewManager(&vm); if (nsnull != vm) { - nsIView *rootview = nsnull; - vm->GetRootView(rootview); - if (rootview) { - nsIWidget* widget; - rootview->GetWidget(widget); - if (widget) { - result = widget->SetFocus(); - NS_RELEASE(widget); - } + nsCOMPtr widget; + vm->GetWidget(getter_AddRefs(widget)); + if (widget) { + result = widget->SetFocus(); } NS_RELEASE(vm); } diff --git a/mozilla/layout/base/nsPresShell.cpp b/mozilla/layout/base/nsPresShell.cpp index 4a1af8443d3..76a834c60f3 100644 --- a/mozilla/layout/base/nsPresShell.cpp +++ b/mozilla/layout/base/nsPresShell.cpp @@ -1446,15 +1446,7 @@ PresShell::ScrollLine(PRBool aForward) // I'd use Composite here, but it doesn't always work. // vm->Composite(); - nsIView* rootView = nsnull; - if (NS_OK == viewManager->GetRootView(rootView) && nsnull != rootView) - { - nsCOMPtr rootWidget; - if (NS_OK == rootView->GetWidget(*getter_AddRefs(rootWidget)) && rootWidget!= nsnull) - { - rootWidget->Update(); - } - } + viewManager->ForceUpdate(); } } @@ -2048,7 +2040,6 @@ PresShell::CreateRenderingContext(nsIFrame *aFrame, return NS_ERROR_NULL_POINTER; } - nsIWidget *widget = nsnull; nsIView *view = nsnull; nsPoint pt; nsresult rv; @@ -2058,17 +2049,11 @@ PresShell::CreateRenderingContext(nsIFrame *aFrame, if (nsnull == view) aFrame->GetOffsetFromView(mPresContext, pt, &view); - while (nsnull != view) - { - view->GetWidget(widget); - - if (nsnull != widget) - { - NS_RELEASE(widget); - break; - } - - view->GetParent(view); + nsCOMPtr widget; + if (nsnull != view) { + nsCOMPtr vm; + view->GetViewManager(*getter_AddRefs(vm)); + vm->GetWidgetForView(view, getter_AddRefs(widget)); } nsCOMPtr dx; @@ -2076,8 +2061,8 @@ PresShell::CreateRenderingContext(nsIFrame *aFrame, nsIRenderingContext* result = nsnull; rv = mPresContext->GetDeviceContext(getter_AddRefs(dx)); if (NS_SUCCEEDED(rv) && dx) { - if (nsnull != view) { - rv = dx->CreateRenderingContext(view, result); + if (nsnull != widget) { + rv = dx->CreateRenderingContext(widget, result); } else { rv = dx->CreateRenderingContext(result); diff --git a/mozilla/layout/events/src/nsDOMEvent.cpp b/mozilla/layout/events/src/nsDOMEvent.cpp index 7acfecdec2c..60b839d8ef7 100644 --- a/mozilla/layout/events/src/nsDOMEvent.cpp +++ b/mozilla/layout/events/src/nsDOMEvent.cpp @@ -336,11 +336,7 @@ NS_METHOD nsDOMEvent::GetClientX(PRInt32* aClientX) nsIViewManager* vm; shell->GetViewManager(&vm); if (vm) { - nsIView* rootView = nsnull; - vm->GetRootView(rootView); - if (rootView) { - rootView->GetWidget(rootWidget); - } + vm->GetWidget(&rootWidget); NS_RELEASE(vm); } NS_RELEASE(shell); @@ -385,11 +381,7 @@ NS_METHOD nsDOMEvent::GetClientY(PRInt32* aClientY) nsIViewManager* vm; shell->GetViewManager(&vm); if (vm) { - nsIView* rootView = nsnull; - vm->GetRootView(rootView); - if (rootView) { - rootView->GetWidget(rootWidget); - } + vm->GetWidget(&rootWidget); NS_RELEASE(vm); } NS_RELEASE(shell); diff --git a/mozilla/layout/events/src/nsEventStateManager.cpp b/mozilla/layout/events/src/nsEventStateManager.cpp index a184330b7ae..f93994307d1 100644 --- a/mozilla/layout/events/src/nsEventStateManager.cpp +++ b/mozilla/layout/events/src/nsEventStateManager.cpp @@ -958,14 +958,7 @@ nsEventStateManager::PostHandleEvent(nsIPresContext* aPresContext, if (NS_OK == aView->GetViewManager(vm) && nsnull != vm) { // I'd use Composite here, but it doesn't always work. // vm->Composite(); - nsIView* rootView = nsnull; - if (NS_OK == vm->GetRootView(rootView) && nsnull != rootView) { - nsIWidget* rootWidget = nsnull; - if (NS_OK == rootView->GetWidget(rootWidget) && nsnull != rootWidget) { - rootWidget->Update(); - NS_RELEASE(rootWidget); - } - } + vm->ForceUpdate(); NS_RELEASE(vm); } } @@ -2461,15 +2454,7 @@ void nsEventStateManager::ForceViewUpdate(nsIView* aView) if (NS_OK == aView->GetViewManager(vm) && nsnull != vm) { // I'd use Composite here, but it doesn't always work. // vm->Composite(); - nsIView* rootView = nsnull; - if (NS_OK == vm->GetRootView(rootView) && nsnull != rootView) { - nsIWidget* rootWidget = nsnull; - if (NS_OK == rootView->GetWidget(rootWidget) && - nsnull != rootWidget) { - rootWidget->Update(); - NS_RELEASE(rootWidget); - } - } + vm->ForceUpdate(); NS_RELEASE(vm); } } diff --git a/mozilla/layout/generic/nsFrame.cpp b/mozilla/layout/generic/nsFrame.cpp index 4e1664a46b1..de82068d62c 100644 --- a/mozilla/layout/generic/nsFrame.cpp +++ b/mozilla/layout/generic/nsFrame.cpp @@ -1508,6 +1508,27 @@ NS_IMETHODIMP nsFrame::GetWindow(nsIPresContext* aPresContext, } } } + + if (nsnull == window) { + // Ask the view manager for the widget + + // First we have to get to a frame with a view + nsIView* view; + GetView(aPresContext, &view); + if (nsnull == view) { + GetParentWithView(aPresContext, &frame); + if (nsnull != frame) { + GetView(aPresContext, &view); + } + } + // From the view get the view manager + if (nsnull != view) { + nsCOMPtr vm; + view->GetViewManager(*getter_AddRefs(vm)); + vm->GetWidget(&window); + } + } + NS_POSTCONDITION(nsnull != window, "no window in frame tree"); *aWindow = window; return NS_OK; diff --git a/mozilla/layout/html/base/src/nsFrame.cpp b/mozilla/layout/html/base/src/nsFrame.cpp index 4e1664a46b1..de82068d62c 100644 --- a/mozilla/layout/html/base/src/nsFrame.cpp +++ b/mozilla/layout/html/base/src/nsFrame.cpp @@ -1508,6 +1508,27 @@ NS_IMETHODIMP nsFrame::GetWindow(nsIPresContext* aPresContext, } } } + + if (nsnull == window) { + // Ask the view manager for the widget + + // First we have to get to a frame with a view + nsIView* view; + GetView(aPresContext, &view); + if (nsnull == view) { + GetParentWithView(aPresContext, &frame); + if (nsnull != frame) { + GetView(aPresContext, &view); + } + } + // From the view get the view manager + if (nsnull != view) { + nsCOMPtr vm; + view->GetViewManager(*getter_AddRefs(vm)); + vm->GetWidget(&window); + } + } + NS_POSTCONDITION(nsnull != window, "no window in frame tree"); *aWindow = window; return NS_OK; diff --git a/mozilla/layout/html/base/src/nsPresShell.cpp b/mozilla/layout/html/base/src/nsPresShell.cpp index 4a1af8443d3..76a834c60f3 100644 --- a/mozilla/layout/html/base/src/nsPresShell.cpp +++ b/mozilla/layout/html/base/src/nsPresShell.cpp @@ -1446,15 +1446,7 @@ PresShell::ScrollLine(PRBool aForward) // I'd use Composite here, but it doesn't always work. // vm->Composite(); - nsIView* rootView = nsnull; - if (NS_OK == viewManager->GetRootView(rootView) && nsnull != rootView) - { - nsCOMPtr rootWidget; - if (NS_OK == rootView->GetWidget(*getter_AddRefs(rootWidget)) && rootWidget!= nsnull) - { - rootWidget->Update(); - } - } + viewManager->ForceUpdate(); } } @@ -2048,7 +2040,6 @@ PresShell::CreateRenderingContext(nsIFrame *aFrame, return NS_ERROR_NULL_POINTER; } - nsIWidget *widget = nsnull; nsIView *view = nsnull; nsPoint pt; nsresult rv; @@ -2058,17 +2049,11 @@ PresShell::CreateRenderingContext(nsIFrame *aFrame, if (nsnull == view) aFrame->GetOffsetFromView(mPresContext, pt, &view); - while (nsnull != view) - { - view->GetWidget(widget); - - if (nsnull != widget) - { - NS_RELEASE(widget); - break; - } - - view->GetParent(view); + nsCOMPtr widget; + if (nsnull != view) { + nsCOMPtr vm; + view->GetViewManager(*getter_AddRefs(vm)); + vm->GetWidgetForView(view, getter_AddRefs(widget)); } nsCOMPtr dx; @@ -2076,8 +2061,8 @@ PresShell::CreateRenderingContext(nsIFrame *aFrame, nsIRenderingContext* result = nsnull; rv = mPresContext->GetDeviceContext(getter_AddRefs(dx)); if (NS_SUCCEEDED(rv) && dx) { - if (nsnull != view) { - rv = dx->CreateRenderingContext(view, result); + if (nsnull != widget) { + rv = dx->CreateRenderingContext(widget, result); } else { rv = dx->CreateRenderingContext(result); diff --git a/mozilla/view/public/nsIViewManager.h b/mozilla/view/public/nsIViewManager.h index e68551ef078..922ca025f03 100644 --- a/mozilla/view/public/nsIViewManager.h +++ b/mozilla/view/public/nsIViewManager.h @@ -70,9 +70,15 @@ public: /** * Set the root of the view tree. Does not destroy the current root view. + * One of following must be true: + * a) the aWidget parameter is an nsIWidget instance to render into + * that is not owned by any view or + * b) aView has a nsIWidget instance or + * c) aView has a parent view managed by a different view manager * @param aView view to set as root + * @param aWidget widget to render into. (Can not be owned by a view) */ - NS_IMETHOD SetRootView(nsIView *aView) = 0; + NS_IMETHOD SetRootView(nsIView *aView, nsIWidget* aWidget = nsnull) = 0; /** * Get the current framerate i.e. the rate at which timed @@ -427,6 +433,34 @@ public: * @result error status */ NS_IMETHOD RemoveCompositeListener(nsICompositeListener *aListener) = 0; + + /** + * Retrieve the widget that a view renders into. + * @param aView the view to get the widget for + * @param aWidget the widget that aView renders into. + * @result error status + */ + + NS_IMETHOD GetWidgetForView(nsIView *aView, nsIWidget **aWidget) = 0; + + /** + * Retrieve the widget that a view manager renders into + * @param aWidget the widget that aView renders into. + * @result error status + */ + + NS_IMETHOD GetWidget(nsIWidget **aWidget) = 0; + + /** + * Force update of view manager widget + * Callers should use UpdateView(view, NS_VMREFRESH_IMMEDIATE) in most cases instead + * @param aWidget the widget that aView renders into. + * @result error status + */ + + NS_IMETHOD ForceUpdate() = 0; + + }; //when the refresh happens, should it be double buffered? diff --git a/mozilla/view/src/nsView.cpp b/mozilla/view/src/nsView.cpp index ebc5d2053fb..7710b7e174c 100644 --- a/mozilla/view/src/nsView.cpp +++ b/mozilla/view/src/nsView.cpp @@ -1392,6 +1392,7 @@ NS_IMETHODIMP nsView :: GetViewFlags(PRUint32 *aFlags) const NS_IMETHODIMP nsView :: GetOffsetFromWidget(nscoord *aDx, nscoord *aDy, nsIWidget *&aWidget) { nsIView *ancestor; + aWidget = nsnull; // XXX aDx and aDy are OUT parameters and so we should initialize them // to 0 rather than relying on the caller to do so... @@ -1415,7 +1416,15 @@ NS_IMETHODIMP nsView :: GetOffsetFromWidget(nscoord *aDx, nscoord *aDy, nsIWidge ancestor->GetParent(ancestor); } - aWidget = nsnull; + + if (nsnull == aWidget) { + // The root view doesn't have a widget + // but maybe the view manager does. + nsCOMPtr vm; + GetViewManager(*getter_AddRefs(vm)); + vm->GetWidget(&aWidget); + } + return NS_OK; } diff --git a/mozilla/view/src/nsViewManager.cpp b/mozilla/view/src/nsViewManager.cpp index 9780fd40c08..a559f8ddb9c 100644 --- a/mozilla/view/src/nsViewManager.cpp +++ b/mozilla/view/src/nsViewManager.cpp @@ -298,7 +298,7 @@ NS_IMETHODIMP nsViewManager :: GetRootView(nsIView *&aView) return NS_OK; } -NS_IMETHODIMP nsViewManager :: SetRootView(nsIView *aView) +NS_IMETHODIMP nsViewManager :: SetRootView(nsIView *aView, nsIWidget* aWidget) { UpdateTransCnt(mRootView, aView); // Do NOT destroy the current root view. It's the caller's responsibility @@ -308,8 +308,27 @@ NS_IMETHODIMP nsViewManager :: SetRootView(nsIView *aView) //now get the window too. NS_IF_RELEASE(mRootWindow); - if (nsnull != mRootView) + // The window must be specified through one of the following: + //* a) The aView has a nsIWidget instance or + //* b) the aWidget parameter is an nsIWidget instance to render into + //* that is not owned by a view. + //* c) aView has a parent view managed by a different view manager or + + if (nsnull != aWidget) { + mRootWindow = aWidget; + NS_ADDREF(mRootWindow); + return NS_OK; + } + + // case b) The aView has a nsIWidget instance + if (nsnull != mRootView) { mRootView->GetWidget(mRootWindow); + if (nsnull != mRootWindow) { + return NS_OK; + } + } + + // case c) aView has a parent view managed by a different view manager return NS_OK; } @@ -2454,6 +2473,56 @@ NS_IMETHODIMP nsViewManager :: RemoveCompositeListener(nsICompositeListener* aLi return NS_ERROR_FAILURE; } + +NS_IMETHODIMP nsViewManager::GetWidgetForView(nsIView *aView, nsIWidget **aWidget) +{ + *aWidget = nsnull; + nsIView *view = aView; + PRBool hasWidget = PR_FALSE; + while (!hasWidget && view) + { + view->HasWidget(&hasWidget); + if (!hasWidget) + view->GetParent(view); + } + + if (hasWidget) { + // Widget was found in the view hierarchy + view->GetWidget(*aWidget); + } else { + // No widget was found in the view hierachy, so use try to use the mRootWindow + if (nsnull != mRootWindow) { +#ifdef NS_DEBUG + nsCOMPtr vm; + nsCOMPtr thisInstance(this); + aView->GetViewManager(*getter_AddRefs(vm)); + NS_ASSERTION(thisInstance == vm, "Must use the view instances view manager when calling GetWidgetForView"); +#endif + *aWidget = mRootWindow; + NS_ADDREF(mRootWindow); + } + } + + return NS_OK; +} + + +NS_IMETHODIMP nsViewManager::GetWidget(nsIWidget **aWidget) +{ + NS_IF_ADDREF(mRootWindow); + *aWidget = mRootWindow; + return NS_OK; +} + +NS_IMETHODIMP nsViewManager::ForceUpdate() +{ + if (mRootWindow) { + mRootWindow->Update(); + } + return NS_OK; +} + + PRBool nsViewManager :: CreateDisplayList(nsIView *aView, PRInt32 *aIndex, nscoord aOriginX, nscoord aOriginY, nsIView *aRealView, const nsRect *aDamageRect, nsIView *aTopView, @@ -2754,3 +2823,4 @@ void nsViewManager::ViewToWidget(nsIView *aView, nsIView* aWidgetView, nsRect &a mContext->GetAppUnitsToDevUnits(t2p); aRect.ScaleRoundOut(t2p); } + diff --git a/mozilla/view/src/nsViewManager.h b/mozilla/view/src/nsViewManager.h index 7960c1ae9cc..1d17853773d 100644 --- a/mozilla/view/src/nsViewManager.h +++ b/mozilla/view/src/nsViewManager.h @@ -48,7 +48,7 @@ public: NS_IMETHOD Init(nsIDeviceContext* aContext); NS_IMETHOD GetRootView(nsIView *&aView); - NS_IMETHOD SetRootView(nsIView *aView); + NS_IMETHOD SetRootView(nsIView *aView, nsIWidget* aWidget=nsnull); NS_IMETHOD GetFrameRate(PRUint32 &aRate); NS_IMETHOD SetFrameRate(PRUint32 frameRate); @@ -129,6 +129,10 @@ public: NS_IMETHOD AddCompositeListener(nsICompositeListener *aListener); NS_IMETHOD RemoveCompositeListener(nsICompositeListener *aListener); + NS_IMETHOD GetWidgetForView(nsIView *aView, nsIWidget **aWidget); + NS_IMETHOD GetWidget(nsIWidget **aWidget); + NS_IMETHOD ForceUpdate(); + protected: virtual ~nsViewManager();