bug #10261: fix for dropping calls to UpdateView, also now correctly handles calls to UpdateView(nsIView*, nsIRegion*, ...) with non-null nsIRegion*.

This commit is contained in:
beard%netscape.com 1999-09-03 02:27:40 +00:00
Родитель e5c321d37d
Коммит 2e6af96bc5
3 изменённых файлов: 77 добавлений и 44 удалений

Просмотреть файл

@ -893,6 +893,7 @@ NS_IMETHODIMP nsScrollingView::ComputeScrollOffsets(PRBool aAdjustWidgets)
nsIView *scrolledView;
GetScrolledView(scrolledView);
nsIScrollbar *scrollv = nsnull, *scrollh = nsnull;
PRBool hasVertical = PR_TRUE, hasHorizontal = PR_FALSE;
nsIWidget *win;
if (nsnull != scrolledView)
@ -902,7 +903,6 @@ NS_IMETHODIMP nsScrollingView::ComputeScrollOffsets(PRBool aAdjustWidgets)
nscoord hwidth, hheight;
nscoord vwidth, vheight;
PRUint32 oldsizey = mSizeY, oldsizex = mSizeX;
// nsRect area(0, 0, 0, 0);
nscoord offx, offy;
float scale;
nsRect controlRect(0, 0, mBounds.width, mBounds.height);
@ -914,36 +914,31 @@ NS_IMETHODIMP nsScrollingView::ComputeScrollOffsets(PRBool aAdjustWidgets)
scrolledView->GetDimensions(&mSizeX, &mSizeY);
if (nsnull != mHScrollBarView)
{
if (nsnull != mHScrollBarView) {
mHScrollBarView->GetDimensions(&hwidth, &hheight);
mHScrollBarView->GetWidget(win);
if (NS_OK == win->QueryInterface(kIScrollbarIID, (void **)&scrollh)) {
if (((mSizeX > controlRect.width) &&
(mScrollPref != nsScrollPreference_kNeverScroll)) ||
(mScrollPref == nsScrollPreference_kAlwaysScroll))
{
scrollh->Release(); //DO NOT USE NS_RELEASE()! MMP
}
else
{
NS_RELEASE(scrollh); //MUST USE NS_RELEASE()! MMP
hasHorizontal = PR_TRUE;
}
NS_RELEASE(scrollh);
}
NS_RELEASE(win);
}
if (nsnull != mVScrollBarView)
{
if (nsnull != mVScrollBarView) {
mVScrollBarView->GetDimensions(&vwidth, &vheight);
offy = mOffsetY;
mVScrollBarView->GetWidget(win);
if (NS_OK == win->QueryInterface(kIScrollbarIID, (void **)&scrollv)) {
if ((mSizeY > (controlRect.height - ((nsnull != scrollh) ? hheight : 0)))) {
if ((mSizeY > (controlRect.height - (hasHorizontal ? hheight : 0)))) {
// if we are scrollable
if (mScrollPref != nsScrollPreference_kNeverScroll) {
//we need to be able to scroll
@ -960,7 +955,7 @@ NS_IMETHODIMP nsScrollingView::ComputeScrollOffsets(PRBool aAdjustWidgets)
scrollv->GetPosition(oldpos);
px->GetDevUnitsToAppUnits(p2t);
availheight = controlRect.height - ((nsnull != scrollh) ? hheight : 0);
availheight = controlRect.height - (hasHorizontal ? hheight : 0);
// XXX Check for 0 initial size. This is really indicative
// of a problem.
@ -984,8 +979,7 @@ NS_IMETHODIMP nsScrollingView::ComputeScrollOffsets(PRBool aAdjustWidgets)
scrollv->SetParameters(mSizeY, availheight,
mOffsetY, mLineHeight);
}
} else
{
} else {
// The scrolled view is entirely visible vertically. Either hide the
// vertical scrollbar or disable it
mOffsetY = 0;
@ -1002,13 +996,11 @@ NS_IMETHODIMP nsScrollingView::ComputeScrollOffsets(PRBool aAdjustWidgets)
{
((ScrollBarView *)mVScrollBarView)->SetEnabled(PR_FALSE);
win->Enable(PR_TRUE);
NS_RELEASE(scrollv);
hasVertical = PR_FALSE;
}
}
//don't release the vertical scroller here because if we need to
//create a horizontal one, it will need to know that there is a vertical one
// //create a horizontal one, it will need to tweak the vertical one
NS_RELEASE(scrollv);
}
NS_RELEASE(win);
@ -1016,11 +1008,10 @@ NS_IMETHODIMP nsScrollingView::ComputeScrollOffsets(PRBool aAdjustWidgets)
if (nsnull != mHScrollBarView) {
offx = mOffsetX;
mHScrollBarView->GetWidget(win);
if (NS_OK == win->QueryInterface(kIScrollbarIID, (void **)&scrollh)) {
if ((mSizeX > (controlRect.width - ((nsnull != scrollv) ? vwidth : 0)))) {
if ((mSizeX > (controlRect.width - (hasVertical ? vwidth : 0)))) {
if (mScrollPref != nsScrollPreference_kNeverScroll) {
//we need to be able to scroll
@ -1036,7 +1027,7 @@ NS_IMETHODIMP nsScrollingView::ComputeScrollOffsets(PRBool aAdjustWidgets)
scrollh->GetPosition(oldpos);
px->GetDevUnitsToAppUnits(p2t);
availwidth = controlRect.width - ((nsnull != scrollv) ? vwidth : 0);
availwidth = controlRect.width - (hasVertical ? vwidth : 0);
// XXX Check for 0 initial size. This is really indicative
// of a problem.
@ -1112,10 +1103,6 @@ NS_IMETHODIMP nsScrollingView::ComputeScrollOffsets(PRBool aAdjustWidgets)
((CornerView *)mCornerView)->Show(PR_FALSE, PR_FALSE);
}
// now we can release the vertical scroller if there was one...
NS_IF_RELEASE(scrollv);
if ((dx != 0) || (dy != 0) && aAdjustWidgets)
AdjustChildWidgets(this, scrolledView, 0, 0, scale);

Просмотреть файл

@ -529,6 +529,7 @@ void nsViewManager :: Refresh(nsIView *aView, nsIRenderingContext *aContext, con
if (localcx != aContext)
NS_RELEASE(localcx);
#if 0
// Subtract the area we just painted from the dirty region
nsIRegion *dirtyRegion;
aView->GetDirtyRegion(dirtyRegion);
@ -544,6 +545,7 @@ void nsViewManager :: Refresh(nsIView *aView, nsIRenderingContext *aContext, con
dirtyRegion->Subtract(pixrect.x, pixrect.y, pixrect.width, pixrect.height);
NS_RELEASE(dirtyRegion);
}
#endif
mLastRefresh = PR_IntervalNow();
@ -1278,6 +1280,25 @@ void nsViewManager :: UpdateDirtyViews(nsIView *aView, nsRect *aParentRect) cons
}
}
void nsViewManager::ProcessPendingUpdates(nsIView* aView)
{
nsIRegion* dirtyRegion = nsnull;
aView->GetDirtyRegion(dirtyRegion);
if (dirtyRegion != nsnull && !dirtyRegion->IsEmpty()) {
UpdateView(aView, dirtyRegion, 0);
dirtyRegion->Init();
NS_RELEASE(dirtyRegion);
}
// process pending updates in child view.
nsIView* childView = nsnull;
aView->GetChild(0, childView);
while (nsnull != childView) {
ProcessPendingUpdates(childView);
childView->GetNextSibling(childView);
}
}
NS_IMETHODIMP nsViewManager :: Composite()
{
if (mUpdateCnt > 0)
@ -1292,8 +1313,19 @@ NS_IMETHODIMP nsViewManager :: Composite()
return NS_OK;
}
NS_IMETHODIMP nsViewManager :: UpdateView(nsIView *aView, nsIRegion *aRegion, PRUint32 aUpdateFlags)
NS_IMETHODIMP nsViewManager::UpdateView(nsIView *aView, nsIRegion *aRegion, PRUint32 aUpdateFlags)
{
// TODO: should ads nsIWidget::Invalidate(nsIRegion*).
nsRect dirtyRect;
if (aRegion != nsnull) {
aRegion->GetBoundingBox(&dirtyRect.x, &dirtyRect.y, &dirtyRect.width, &dirtyRect.height);
} else {
aView->GetBounds(dirtyRect);
dirtyRect.x = dirtyRect.y = 0;
}
UpdateView(aView, dirtyRect, aUpdateFlags);
#if 0
// XXX Huh. What about the case where aRegion isn't nsull?
// XXX yeah? what about it?
if (aRegion == nsnull)
@ -1305,14 +1337,18 @@ NS_IMETHODIMP nsViewManager :: UpdateView(nsIView *aView, nsIRegion *aRegion, PR
trect.x = trect.y = 0;
UpdateView(aView, trect, aUpdateFlags);
}
#endif
return NS_OK;
return NS_OK;
}
NS_IMETHODIMP nsViewManager :: UpdateView(nsIView *aView, const nsRect &aRect, PRUint32 aUpdateFlags)
{
NS_PRECONDITION(nsnull != aView, "null view");
if (!mRefreshEnabled && 0 == mUpdateBatchCnt) {
// accumulate this rectangle in the view's dirty region, so we can process it later.
AddRectToDirtyRegion(aView, aRect);
++mUpdateCnt;
return NS_OK;
}
@ -2136,26 +2172,30 @@ nsIRenderingContext * nsViewManager :: CreateRenderingContext(nsIView &aView)
return cx;
}
void nsViewManager :: AddRectToDirtyRegion(nsIView* aView, const nsRect &aRect) const
void nsViewManager::AddRectToDirtyRegion(nsIView* aView, const nsRect &aRect) const
{
// Get the dirty region associated with the view
nsIRegion *dirtyRegion;
// Get the dirty region associated with the view
nsIRegion *dirtyRegion;
aView->GetDirtyRegion(dirtyRegion);
aView->GetDirtyRegion(dirtyRegion);
if (nsnull == dirtyRegion)
{
// The view doesn't have a dirty region so create one
nsresult rv = nsComponentManager::CreateInstance(kRegionCID,
nsnull,
kIRegionIID,
(void **)&dirtyRegion);
if (nsnull == dirtyRegion) {
// The view doesn't have a dirty region so create one
nsresult rv = nsComponentManager::CreateInstance(kRegionCID,
nsnull,
kIRegionIID,
(void **)&dirtyRegion);
if (NS_FAILED(rv)) return;
dirtyRegion->Init();
aView->SetDirtyRegion(dirtyRegion);
}
if (NS_FAILED(rv)) return;
dirtyRegion->Init();
aView->SetDirtyRegion(dirtyRegion);
}
// since this is only used to buffer update requests, keep them in app units.
dirtyRegion->Union(aRect.x, aRect.y, aRect.width, aRect.height);
NS_RELEASE(dirtyRegion);
#if 0
// Dirty regions are in device units, and aRect is in app units so
// we need to convert to device units
nsRect trect = aRect;
@ -2166,6 +2206,7 @@ void nsViewManager :: AddRectToDirtyRegion(nsIView* aView, const nsRect &aRect)
trect.ScaleRoundOut(t2p);
dirtyRegion->Union(trect.x, trect.y, trect.width, trect.height);
NS_IF_RELEASE(dirtyRegion);
#endif
}
void nsViewManager :: UpdateTransCnt(nsIView *oldview, nsIView *newview)
@ -2205,6 +2246,9 @@ NS_IMETHODIMP nsViewManager :: EnableRefresh(void)
{
mRefreshEnabled = PR_TRUE;
if (mUpdateCnt > 0)
ProcessPendingUpdates(mRootView);
if (mTrueFrameRate > 0)
{
PRInt32 deltams = PR_IntervalToMilliseconds(PR_IntervalNow() - mLastRefresh);

Просмотреть файл

@ -128,6 +128,8 @@ private:
void UpdateDirtyViews(nsIView *aView, nsRect *aParentRect) const;
void UpdateTransCnt(nsIView *oldview, nsIView *newview);
void ProcessPendingUpdates(nsIView *aView);
void Refresh(nsIView *aView, nsIRenderingContext *aContext,
nsIRegion *region, PRUint32 aUpdateFlags);
void Refresh(nsIView* aView, nsIRenderingContext *aContext,