void nsViewManager::InvalidateHierarchy() { if (mRootView) { if (!IsRootVM()) { NS_RELEASE(mRootViewManager); } nsView *parent = mRootView->GetParent(); if (parent) { mRootViewManager = parent->GetViewManager()->RootViewManager(); NS_ADDREF(mRootViewManager); NS_ASSERTION(mRootViewManager != this, "Root view had a parent, but it has the same view manager"); } else { mRootViewManager = this; } } }
void nsViewManager::UpdateWidgetGeometry() { if (!IsRootVM()) { RootViewManager()->UpdateWidgetGeometry(); return; } if (mHasPendingWidgetGeometryChanges) { if (IsRefreshDriverPaintingEnabled()) { mHasPendingWidgetGeometryChanges = false; } ProcessPendingUpdatesForView(mRootView, false); if (!IsRefreshDriverPaintingEnabled()) { mHasPendingWidgetGeometryChanges = false; } } }
void nsViewManager::CallWillPaintOnObservers(bool aWillSendDidPaint) { NS_PRECONDITION(IsRootVM(), "Must be root VM for this to be called!"); PRInt32 index; for (index = 0; index < mVMCount; index++) { nsViewManager* vm = (nsViewManager*)gViewManagers->ElementAt(index); if (vm->RootViewManager() == this) { // One of our kids. if (vm->mRootView && vm->mRootView->IsEffectivelyVisible()) { nsCOMPtr<nsIPresShell> shell = vm->GetPresShell(); if (shell) { shell->WillPaint(aWillSendDidPaint); } } } } }
void nsViewManager::ProcessPendingUpdates() { if (!IsRootVM()) { RootViewManager()->ProcessPendingUpdates(); return; } if (IsRefreshDriverPaintingEnabled()) { mPresShell->GetPresContext()->RefreshDriver()->RevokeViewManagerFlush(); // Flush things like reflows by calling WillPaint on observer presShells. if (mPresShell) { CallWillPaintOnObservers(true); } ProcessPendingUpdatesForView(mRootView, true); } else { ProcessPendingUpdatesForView(mRootView, true); } }
void nsViewManager::ProcessPendingUpdatesForView(nsView* aView, bool aFlushDirtyRegion) { NS_ASSERTION(IsRootVM(), "Updates will be missed"); // Protect against a null-view. if (!aView) { return; } if (aView->HasWidget()) { aView->ResetWidgetBounds(false, true); } // process pending updates in child view. for (nsView* childView = aView->GetFirstChild(); childView; childView = childView->GetNextSibling()) { ProcessPendingUpdatesForView(childView, aFlushDirtyRegion); } // Push out updates after we've processed the children; ensures that // damage is applied based on the final widget geometry if (aFlushDirtyRegion) { if (IsRefreshDriverPaintingEnabled()) { nsIWidget *widget = aView->GetWidget(); if (widget && widget->NeedsPaint()) { // If an ancestor widget was hidden and then shown, we could // have a delayed resize to handle. for (nsViewManager *vm = this; vm; vm = vm->mRootView->GetParent() ? vm->mRootView->GetParent()->GetViewManager() : nullptr) { if (vm->mDelayedResize != nsSize(NSCOORD_NONE, NSCOORD_NONE) && vm->mRootView->IsEffectivelyVisible() && mPresShell && mPresShell->IsVisible()) { vm->FlushDelayedResize(true); vm->InvalidateView(vm->mRootView); } } NS_ASSERTION(aView->HasWidget(), "Must have a widget!"); SetPainting(true); #ifdef DEBUG_INVALIDATIONS printf("---- PAINT START ----PresShell(%p), nsView(%p), nsIWidget(%p)\n", mPresShell, aView, widget); #endif nsAutoScriptBlocker scriptBlocker; NS_ASSERTION(aView->HasWidget(), "Must have a widget!"); mPresShell->Paint(aView, nsRegion(), nsIPresShell::PAINT_LAYERS | nsIPresShell::PAINT_WILL_SEND_DID_PAINT); #ifdef DEBUG_INVALIDATIONS printf("---- PAINT END ----\n"); #endif aView->SetForcedRepaint(false); SetPainting(false); } } FlushDirtyRegionToWidget(aView); } }