Mozilla Home
Privacy
Cookies
Legal
Bugzilla
Browse
Advanced Search
New Bug
Reports
Documentation
Log In
Log In with GitHub
or
Remember me
Browse
Advanced Search
New Bug
Reports
Documentation
Attachment 69248 Details for
Bug 91516
[patch]
new fix --- last patch leaked view managers
patch (text/plain), 20.44 KB, created by
Robert O'Callahan (:roc) (email my personal email if necessary)
(
hide
)
Description:
new fix --- last patch leaked view managers
Filename:
MIME Type:
Creator:
Robert O'Callahan (:roc) (email my personal email if necessary)
Size:
20.44 KB
patch
obsolete
>? layout/svg/base/public/Makefile >? layout/svg/content/Makefile >? layout/svg/content/src/Makefile >Index: content/base/src/nsDocumentViewer.cpp >=================================================================== >RCS file: /cvsroot/mozilla/content/base/src/nsDocumentViewer.cpp,v >retrieving revision 1.200 >diff -u -r1.200 nsDocumentViewer.cpp >--- content/base/src/nsDocumentViewer.cpp 6 Feb 2002 13:04:47 -0000 1.200 >+++ content/base/src/nsDocumentViewer.cpp 13 Feb 2002 16:12:04 -0000 >@@ -4200,14 +4200,64 @@ > rv = CallCreateInstance(kViewCID, &mView); > if (NS_FAILED(rv)) > return rv; >- rv = mView->Init(mViewManager, tbounds, nsnull); >+ >+ // if aParentWidget has a view, we'll hook our view manager up to its view tree >+ void* clientData; >+ nsIView* containerView = nsnull; >+ if (NS_SUCCEEDED(aParentWidget->GetClientData(clientData))) { >+ nsISupports* data = (nsISupports*)clientData; >+ >+ if (nsnull != data) { >+ data->QueryInterface(NS_GET_IID(nsIView), (void **)&containerView); >+ } >+ } >+ >+ if (nsnull != containerView) { >+ // see if the containerView has already been hooked into a foreign view manager hierarchy >+ // if it has, then we have to hook into the hierarchy too otherwise bad things will happen. >+ nsCOMPtr<nsIViewManager> containerVM; >+ containerView->GetViewManager(*getter_AddRefs(containerVM)); >+ nsCOMPtr<nsIViewManager> checkVM; >+ nsIView* pView = containerView; >+ do { >+ pView->GetParent(pView); >+ } while (pView != nsnull >+ && NS_SUCCEEDED(pView->GetViewManager(*getter_AddRefs(checkVM))) && checkVM == containerVM); >+ >+ if (nsnull == pView) { >+ // OK, so the container is not already hooked up into a foreign view manager hierarchy. >+ // That means we can choose not to hook ourselves up. >+ // >+ // If the parent container is a chrome shell, or a frameset, then we won't hook into its view >+ // tree. This will improve performance a little bit (especially given scrolling/painting perf bugs) >+ // but is really just for peace of mind. This check can be removed if we want to support fancy >+ // chrome effects like transparent controls floating over content, transparent Web browsers, and >+ // things like that, and the perf bugs are fixed. >+ nsCOMPtr<nsIDocShellTreeItem> container(do_QueryInterface(mContainer)); >+ nsCOMPtr<nsIDocShellTreeItem> parentContainer; >+ PRInt32 itemType; >+ if (nsnull == container >+ || NS_FAILED(container->GetParent(getter_AddRefs(parentContainer))) >+ || nsnull == parentContainer >+ || NS_FAILED(parentContainer->GetItemType(&itemType)) >+ || itemType != nsIDocShellTreeItem::typeContent) { >+ containerView = nsnull; >+ } else { >+ nsCOMPtr<nsIWebShell> webShell(do_QueryInterface(parentContainer)); >+ if (nsnull == webShell || IsWebShellAFrameSet(webShell)) { >+ containerView = nsnull; >+ } >+ } >+ } >+ } >+ >+ rv = mView->Init(mViewManager, tbounds, containerView); > if (NS_FAILED(rv)) > return rv; > > rv = mView->CreateWidget(kWidgetCID, nsnull, > aParentWidget->GetNativeData(NS_NATIVE_WIDGET), > PR_TRUE, PR_FALSE); >- > if (rv != NS_OK) > return rv; > >Index: layout/html/base/src/nsContainerFrame.cpp >=================================================================== >RCS file: /cvsroot/mozilla/layout/html/base/src/nsContainerFrame.cpp,v >retrieving revision 1.132 >diff -u -r1.132 nsContainerFrame.cpp >--- layout/html/base/src/nsContainerFrame.cpp 7 Feb 2002 22:39:13 -0000 1.132 >+++ layout/html/base/src/nsContainerFrame.cpp 13 Feb 2002 15:48:09 -0000 >@@ -410,7 +410,11 @@ > nsCOMPtr<nsIViewManager> vm; > view->GetViewManager(*getter_AddRefs(vm)); > >- if (containingView != parentView) { >+ // it's possible for the parentView to be nonnull but containingView to be >+ // null, when the parent view doesn't belong to this frame tree but to >+ // the frame tree of some enclosing document. We do nothing in that case, >+ // but we have to check that containingView is nonnull or we will crash. >+ if (nsnull != containingView && containingView != parentView) { > // it is possible for parent view not to have a frame attached to it > // kind of an anonymous view. This happens with native scrollbars and > // the clip view. To fix this we need to go up and parentView chain >@@ -539,9 +543,17 @@ > // See if the view should be hidden or visible > PRBool viewIsVisible = PR_TRUE; > PRBool viewHasTransparentContent = >- !isCanvas && > (!hasBG || > (bg->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT)); >+ if (isCanvas && viewHasTransparentContent) { >+ nsIView* rootView; >+ vm->GetRootView(rootView); >+ nsIView* rootParent; >+ rootView->GetParent(rootParent); >+ if (nsnull == rootParent) { >+ viewHasTransparentContent = PR_FALSE; >+ } >+ } > > if (NS_STYLE_VISIBILITY_COLLAPSE == vis->mVisible) { > viewIsVisible = PR_FALSE; >Index: layout/html/forms/src/nsFormControlFrame.cpp >=================================================================== >RCS file: /cvsroot/mozilla/layout/html/forms/src/nsFormControlFrame.cpp,v >retrieving revision 1.141 >diff -u -r1.141 nsFormControlFrame.cpp >--- layout/html/forms/src/nsFormControlFrame.cpp 9 Jan 2002 19:17:43 -0000 1.141 >+++ layout/html/forms/src/nsFormControlFrame.cpp 13 Feb 2002 15:48:10 -0000 >@@ -981,23 +981,32 @@ > float p2t; > aPresContext->GetTwipsToPixels(&t2p); > aPresContext->GetPixelsToTwips(&p2t); >- >+ > // Add in frame's offset from it it's containing view > nsIView *containingView = nsnull; > nsPoint offset; > rv = aFrame->GetOffsetFromView(aPresContext, offset, &containingView); >+ > if (NS_SUCCEEDED(rv) && (nsnull != containingView)) { > aAbsoluteTwipsRect.x += offset.x; > aAbsoluteTwipsRect.y += offset.y; > > nsPoint viewOffset; > containingView->GetPosition(&viewOffset.x, &viewOffset.y); >+ > nsIView * parent; > containingView->GetParent(parent); > > // if we don't have a parent view then > // check to see if we have a widget and adjust our offset for the widget > if (parent == nsnull) { >+ // account for space above and to the left of the containingView origin. >+ // the widget is aligned with containingView's bounds, not its origin >+ nsRect bounds; >+ containingView->GetBounds(bounds); >+ aAbsoluteTwipsRect.x += viewOffset.x - bounds.x; >+ aAbsoluteTwipsRect.y += viewOffset.y - bounds.y; >+ > nsIWidget * widget; > containingView->GetWidget(widget); > if (nsnull != widget) { >@@ -1012,7 +1021,6 @@ > } > rv = NS_OK; > } else { >- > while (nsnull != parent) { > nsPoint po; > parent->GetPosition(&po.x, &po.y); >@@ -1029,6 +1037,13 @@ > nsIWidget * widget; > parent->GetWidget(widget); > if (nsnull != widget) { >+ // account for space above and to the left of the containingView origin. >+ // the widget is aligned with containingView's bounds, not its origin >+ nsRect bounds; >+ parent->GetBounds(bounds); >+ aAbsoluteTwipsRect.x += po.x - bounds.x; >+ aAbsoluteTwipsRect.y += po.y - bounds.y; >+ > // Add in the absolute offset of the widget. > nsRect absBounds; > nsRect lc; >Index: layout/html/forms/src/nsListControlFrame.cpp >=================================================================== >RCS file: /cvsroot/mozilla/layout/html/forms/src/nsListControlFrame.cpp,v >retrieving revision 1.242 >diff -u -r1.242 nsListControlFrame.cpp >--- layout/html/forms/src/nsListControlFrame.cpp 8 Feb 2002 18:35:47 -0000 1.242 >+++ layout/html/forms/src/nsListControlFrame.cpp 13 Feb 2002 15:48:13 -0000 >@@ -2275,6 +2275,12 @@ > > parent = aView; > while (nsnull != parent) { >+ nsCOMPtr<nsIViewManager> vm; >+ parent->GetViewManager(*getter_AddRefs(vm)); >+ if (vm != aManager) { >+ break; >+ } >+ > nscoord x, y; > parent->GetPosition(&x, &y); > aPoint.x += x; >Index: layout/html/style/src/nsCSSRendering.cpp >=================================================================== >RCS file: /cvsroot/mozilla/layout/html/style/src/nsCSSRendering.cpp,v >retrieving revision 3.164 >diff -u -r3.164 nsCSSRendering.cpp >--- layout/html/style/src/nsCSSRendering.cpp 15 Jan 2002 22:37:15 -0000 3.164 >+++ layout/html/style/src/nsCSSRendering.cpp 13 Feb 2002 15:48:16 -0000 >@@ -2529,18 +2529,26 @@ > return; > } > >- // Ensure that we always paint a color for the root (in case there's >- // no background at all or a partly transparent image). > nsStyleBackground canvasColor(*color); >- if (canvasColor.mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) { >- canvasColor.mBackgroundFlags &= ~NS_STYLE_BG_COLOR_TRANSPARENT; >- aPresContext->GetDefaultBackgroundColor(&canvasColor.mBackgroundColor); >- } > > nsCOMPtr<nsIPresShell> shell; > aPresContext->GetShell(getter_AddRefs(shell)); > nsCOMPtr<nsIViewManager> vm; > shell->GetViewManager(getter_AddRefs(vm)); >+ >+ if (canvasColor.mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) { >+ nsIView* rootView; >+ vm->GetRootView(rootView); >+ nsIView* rootParent; >+ rootView->GetParent(rootParent); >+ if (nsnull == rootParent) { >+ // Ensure that we always paint a color for the root (in case there's >+ // no background at all or a partly transparent image). >+ canvasColor.mBackgroundFlags &= ~NS_STYLE_BG_COLOR_TRANSPARENT; >+ aPresContext->GetDefaultBackgroundColor(&canvasColor.mBackgroundColor); >+ } >+ } >+ > vm->SetDefaultBackgroundColor(canvasColor.mBackgroundColor); > > // Since nsHTMLContainerFrame::CreateViewForFrame might have created >Index: view/public/nsIViewManager.h >=================================================================== >RCS file: /cvsroot/mozilla/view/public/nsIViewManager.h,v >retrieving revision 3.61 >diff -u -r3.61 nsIViewManager.h >--- view/public/nsIViewManager.h 16 Jan 2002 03:06:59 -0000 3.61 >+++ view/public/nsIViewManager.h 13 Feb 2002 15:48:20 -0000 >@@ -83,7 +83,7 @@ > > /** > * Set the root of the view tree. Does not destroy the current root view. >- * One of following must be true: >+ * At least one of following must be true: > * a) the aWidget parameter is an nsIWidget instance to render into > * that is not owned by any view and aView has no widget, or > * b) aView has a nsIWidget instance and aWidget is null, or >Index: view/src/nsView.cpp >=================================================================== >RCS file: /cvsroot/mozilla/view/src/nsView.cpp,v >retrieving revision 3.150 >diff -u -r3.150 nsView.cpp >--- view/src/nsView.cpp 12 Feb 2002 03:46:32 -0000 3.150 >+++ view/src/nsView.cpp 13 Feb 2002 15:48:20 -0000 >@@ -103,33 +103,30 @@ > > while (GetFirstChild() != nsnull) > { >- GetFirstChild()->Destroy(); >+ nsView* child = GetFirstChild(); >+ if (child->GetViewManager() == mViewManager) { >+ child->Destroy(); >+ } else { >+ // just unhook it. Someone else will want to destroy this. >+ RemoveChild(child); >+ } >+ } >+ >+ if (nsnull != mParent) >+ { >+ mParent->RemoveChild(this); > } > > if (nsnull != mViewManager) > { > nsView *rootView = mViewManager->GetRootView(); > >- if (nsnull != rootView) >- { >- if (rootView == this) >- { >- // Inform the view manager that the root view has gone away... >- mViewManager->SetRootView(nsnull); >- } >- else >- { >- if (nsnull != mParent) >- { >- mViewManager->RemoveChild(this); >- } >- } >- } >- else if (nsnull != mParent) >+ if (rootView == this) > { >- mParent->RemoveChild(this); >+ // Inform the view manager that the root view has gone away... >+ mViewManager->SetRootView(nsnull); > } >- >+ > nsView* grabbingView = mViewManager->GetMouseEventGrabber(); //check to see if we are capturing!!! > if (grabbingView == this) > { >@@ -139,11 +136,7 @@ > > mViewManager = nsnull; > } >- else if (nsnull != mParent) >- { >- mParent->RemoveChild(this); >- } >- >+ > if (nsnull != mZParent) > { > mZParent->RemoveReparentedView(); >Index: view/src/nsViewManager.cpp >=================================================================== >RCS file: /cvsroot/mozilla/view/src/nsViewManager.cpp,v >retrieving revision 3.227 >diff -u -r3.227 nsViewManager.cpp >--- view/src/nsViewManager.cpp 12 Feb 2002 03:46:33 -0000 3.227 >+++ view/src/nsViewManager.cpp 13 Feb 2002 15:48:23 -0000 >@@ -64,17 +64,6 @@ > XXX TODO XXX > > DeCOMify newly private methods >- Move event handling into nsViewManager >- Make event handling use CreateDisplayList >- Reverse storage order of views so that LAST view in document order is the LAST child >- of its parent view >- Audit users of nsIView::GetPosition and nsIView::GetBounds, then >- fix nsContainerFrame::SyncFrameViewAfterReflow to size views to contain >- left-or-above content >- Remove nsIClipView stuff and just use the CLIPCHILDREN flag >- Put in support for hierarchy of viewmanagers (handle nsViewManager::SetRootView >- case where aWidget == null and aView has a non-null parent with a different view >- manager) > Fix opacity model to conform to SVG (requires backbuffer stack) > Optimize view storage > */ >@@ -530,6 +519,13 @@ > > // case b) The aView has a nsIWidget instance > if (nsnull != mRootView) { >+ nsView* parent = mRootView->GetParent(); >+ if (nsnull != parent) { >+ parent->InsertChild(mRootView, nsnull); >+ } >+ >+ mRootView->SetZIndex(PR_FALSE, 0); >+ > mRootView->GetWidget(mRootWindow); > if (nsnull != mRootWindow) { > return NS_OK; >@@ -1388,7 +1396,9 @@ > // process pending updates in child view. > nsView* childView = aView->GetFirstChild(); > while (nsnull != childView) { >- ProcessPendingUpdates(childView); >+ if (childView->GetViewManager() == this) { >+ ProcessPendingUpdates(childView); >+ } > childView = childView->GetNextSibling(); > } > >@@ -1441,7 +1451,12 @@ > return NS_OK; > } > >- UpdateAllCoveringWidgets(mRootView, view, damageRect, PR_FALSE); >+ nsView* realRoot = mRootView; >+ while (realRoot->GetParent() != nsnull) { >+ realRoot = realRoot->GetParent(); >+ } >+ >+ UpdateAllCoveringWidgets(realRoot, view, damageRect, PR_FALSE); > Composite(); > return NS_OK; > } >@@ -1494,19 +1509,20 @@ > } > > if (!childCovers && (!isBlittable || (hasWidget && !aRepaintOnlyUnblittableViews))) { >- ++mUpdateCnt; >+ nsViewManager* vm = aView->GetViewManager(); >+ ++vm->mUpdateCnt; > >- if (!mRefreshEnabled) { >+ if (!vm->mRefreshEnabled) { > // accumulate this rectangle in the view's dirty region, so we can process it later. >- AddRectToDirtyRegion(aView, bounds); >- mHasPendingInvalidates = PR_TRUE; >+ vm->AddRectToDirtyRegion(aView, bounds); >+ vm->mHasPendingInvalidates = PR_TRUE; > } else { > nsView* widgetView = GetWidgetView(aView); > if (widgetView != nsnull) { > ViewToWidget(aView, widgetView, bounds); > > nsCOMPtr<nsIWidget> widget; >- GetWidgetForView(widgetView, getter_AddRefs(widget)); >+ vm->GetWidgetForView(widgetView, getter_AddRefs(widget)); > widget->Invalidate(bounds, PR_FALSE); > } > } >@@ -1584,7 +1600,12 @@ > damagedRect.x = origin.x; > damagedRect.y = origin.y; > >- UpdateAllCoveringWidgets(mRootView, nsnull, damagedRect, PR_FALSE); >+ nsView* realRoot = mRootView; >+ while (realRoot->GetParent() != nsnull) { >+ realRoot = realRoot->GetParent(); >+ } >+ >+ UpdateAllCoveringWidgets(realRoot, nsnull, damagedRect, PR_FALSE); > } > > ++mUpdateCnt; >@@ -1615,7 +1636,9 @@ > // update all children as well. > nsView* childView = aView->GetFirstChild(); > while (nsnull != childView) { >- UpdateViews(childView, aUpdateFlags); >+ if (childView->GetViewManager() == this) { >+ UpdateViews(childView, aUpdateFlags); >+ } > childView = childView->GetNextSibling(); > } > } >@@ -1800,14 +1823,14 @@ > nsView *parent; > > parent = baseView; >- while (nsnull != parent) { >+ while (mRootView != parent) { > parent->ConvertToParentCoords(&offset.x, &offset.y); > parent = parent->GetParent(); > } > > //Subtract back offset from root of view > parent = view; >- while (nsnull != parent) { >+ while (mRootView != parent) { > parent->ConvertFromParentCoords(&offset.x, &offset.y); > parent = parent->GetParent(); > } >@@ -1979,17 +2000,33 @@ > } > > nsAutoVoidArray targetViews; >+ nsAutoVoidArray heldRefCountsToOtherVMs; > > // In fact, we only need to take this expensive path when the event is a mouse event ... riiiight? > BuildEventTargetList(targetViews, aView, aEvent, aCaptured); > > nsEventStatus status = nsEventStatus_eIgnore; > >- for (PRInt32 i = 0; i < targetViews.Count(); i++) { >+ // get a death grip on any view managers' view observers (other than this one) >+ PRInt32 i; >+ for (i = 0; i < targetViews.Count(); i++) { >+ DisplayListElement2* element = NS_STATIC_CAST(DisplayListElement2*, targetViews.ElementAt(i)); >+ nsView* v = element->mView; >+ nsViewManager* vVM = v->GetViewManager(); >+ if (vVM != this) { >+ nsIViewObserver* vobs = nsnull; >+ vVM->GetViewObserver(vobs); >+ if (nsnull != vobs) { >+ heldRefCountsToOtherVMs.AppendElement(vobs); >+ } >+ } >+ } >+ >+ for (i = 0; i < targetViews.Count(); i++) { > DisplayListElement2* element = NS_STATIC_CAST(DisplayListElement2*, targetViews.ElementAt(i)); > nsView* v = element->mView; > >- if (nsnull != v->GetClientData() && nsnull != obs) { >+ if (nsnull != v->GetClientData()) { > PRBool handled = PR_FALSE; > nsRect r; > v->GetDimensions(r); >@@ -2000,7 +2037,18 @@ > aEvent->point.x -= x; > aEvent->point.y -= y; > >- obs->HandleEvent(v, aEvent, &status, i == targetViews.Count() - 1, handled); >+ nsViewManager* vVM = v->GetViewManager(); >+ if (vVM == this) { >+ if (nsnull != obs) { >+ obs->HandleEvent(v, aEvent, &status, i == targetViews.Count() - 1, handled); >+ } >+ } else { >+ nsIViewObserver* vobs = nsnull; >+ vVM->GetViewObserver(vobs); >+ if (nsnull != vobs) { >+ vobs->HandleEvent(v, aEvent, &status, i == targetViews.Count() - 1, handled); >+ } >+ } > > aEvent->point.x += x; > aEvent->point.y += y; >@@ -2020,6 +2068,12 @@ > delete element; > } > >+ // release death grips >+ for (i = 0; i < heldRefCountsToOtherVMs.Count(); i++) { >+ nsIViewObserver* element = NS_STATIC_CAST(nsIViewObserver*, heldRefCountsToOtherVMs.ElementAt(i)); >+ NS_RELEASE(element); >+ } >+ > return status; > } > >@@ -2450,6 +2504,12 @@ > > NS_ASSERTION((view != nsnull), "no view"); > >+ // don't allow the root view's z-index to be changed. It should always be zero. >+ // This could be removed and replaced with a style rule, or just removed altogether, with interesting consequences >+ if (aView == mRootView) { >+ return rv; >+ } >+ > if (aAutoZIndex) { > aZIndex = 0; > } >@@ -2758,7 +2818,9 @@ > mRootScrollable = aScrollable; > > //XXX this needs to go away when layout start setting this bit on it's own. MMP >- if (mRootScrollable) >+ // We don't set ALWAYS_BLIT if this isn't the root of the view manager tree, >+ // because non-roots may not, in fact, always be able to blit >+ if (mRootScrollable && mRootView->GetParent() == nsnull) > mRootScrollable->SetScrollProperties(NS_SCROLL_PROPERTY_ALWAYS_BLIT); > > return NS_OK; >@@ -3433,7 +3495,7 @@ > } > > >-nsView* nsViewManager::GetWidgetView(nsView *aView) const >+nsView* nsViewManager::GetWidgetView(nsView *aView) > { > while (aView != nsnull) { > PRBool hasWidget; >@@ -3646,9 +3708,11 @@ > > nsView *child = aView->GetFirstChild(); > while (nsnull != child) { >- rv = ProcessWidgetChanges(child); >- if (NS_FAILED(rv)) >- return rv; >+ if (child->GetViewManager() == this) { >+ rv = ProcessWidgetChanges(child); >+ if (NS_FAILED(rv)) >+ return rv; >+ } > > child = child->GetNextSibling(); > } >Index: view/src/nsViewManager.h >=================================================================== >RCS file: /cvsroot/mozilla/view/src/nsViewManager.h,v >retrieving revision 3.91 >diff -u -r3.91 nsViewManager.h >--- view/src/nsViewManager.h 12 Feb 2002 03:46:35 -0000 3.91 >+++ view/src/nsViewManager.h 13 Feb 2002 15:48:23 -0000 >@@ -309,7 +309,7 @@ > * Returns the nearest parent view with an attached widget. Can be the > * same view as passed-in. > */ >- nsView* GetWidgetView(nsView *aView) const; >+ static nsView* GetWidgetView(nsView *aView); > > /** > * Transforms a rectangle from specified view's coordinate system to
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
Actions:
View
|
Diff
|
Review
Attachments on
bug 91516
:
49641
|
52486
|
53555
|
68262
|
69246
|
69248
|
70019
|
70236
|
70312
|
156854
|
156863
|
234879