mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 598482 part 16. When flushing layout, also flush out widget geometry changes. r=roc
This commit is contained in:
parent
81d739b868
commit
5bdbbbc47c
@ -3616,6 +3616,9 @@ PresShell::ScheduleViewManagerFlush()
|
||||
if (presContext) {
|
||||
presContext->RefreshDriver()->ScheduleViewManagerFlush();
|
||||
}
|
||||
if (mDocument) {
|
||||
mDocument->SetNeedLayoutFlush();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -4094,6 +4097,10 @@ PresShell::FlushPendingNotifications(mozFlushType aType)
|
||||
if (rootPresContext) {
|
||||
rootPresContext->UpdatePluginGeometry();
|
||||
}
|
||||
|
||||
if (!mIsDestroying) {
|
||||
mViewManager->UpdateWidgetGeometry();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -331,6 +331,11 @@ public:
|
||||
* geometry.
|
||||
*/
|
||||
virtual void ProcessPendingUpdates()=0;
|
||||
|
||||
/**
|
||||
* Just update widget geometry without flushing the dirty region
|
||||
*/
|
||||
virtual void UpdateWidgetGeometry() = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIViewManager, NS_IVIEWMANAGER_IID)
|
||||
|
@ -351,7 +351,7 @@ void nsView::SetPosition(nscoord aX, nscoord aY)
|
||||
NS_ASSERTION(GetParent() || (aX == 0 && aY == 0),
|
||||
"Don't try to move the root widget to something non-zero");
|
||||
|
||||
ResetWidgetBounds(true, true, false);
|
||||
ResetWidgetBounds(true, false);
|
||||
}
|
||||
|
||||
void nsIView::SetInvalidationDimensions(const nsRect* aRect)
|
||||
@ -359,22 +359,23 @@ void nsIView::SetInvalidationDimensions(const nsRect* aRect)
|
||||
return Impl()->SetInvalidationDimensions(aRect);
|
||||
}
|
||||
|
||||
void nsView::ResetWidgetBounds(bool aRecurse, bool aMoveOnly,
|
||||
bool aInvalidateChangedSize) {
|
||||
void nsView::ResetWidgetBounds(bool aRecurse, bool aForceSync)
|
||||
{
|
||||
if (mWindow) {
|
||||
// Don't change widget geometry while refresh is disabled, for example
|
||||
// during reflow. Changing widget sizes can cause synchronous painting
|
||||
// which is forbidden during reflow.
|
||||
if (!mViewManager->IsPaintingAllowed()) {
|
||||
if (!aForceSync) {
|
||||
// Don't change widget geometry synchronously, since that can
|
||||
// cause synchronous painting.
|
||||
mViewManager->PostPendingUpdate();
|
||||
return;
|
||||
} else {
|
||||
DoResetWidgetBounds(false, true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
DoResetWidgetBounds(aMoveOnly, aInvalidateChangedSize);
|
||||
} else if (aRecurse) {
|
||||
if (aRecurse) {
|
||||
// reposition any widgets under this view
|
||||
for (nsView* v = GetFirstChild(); v; v = v->GetNextSibling()) {
|
||||
v->ResetWidgetBounds(true, aMoveOnly, aInvalidateChangedSize);
|
||||
v->ResetWidgetBounds(true, aForceSync);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -492,7 +493,7 @@ void nsView::SetDimensions(const nsRect& aRect, bool aPaint, bool aResizeWidget)
|
||||
mDimBounds = dims;
|
||||
|
||||
if (aResizeWidget) {
|
||||
ResetWidgetBounds(false, false, aPaint);
|
||||
ResetWidgetBounds(false, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -181,7 +181,7 @@ public:
|
||||
void SetTopMost(bool aTopMost) { aTopMost ? mVFlags |= NS_VIEW_FLAG_TOPMOST : mVFlags &= ~NS_VIEW_FLAG_TOPMOST; }
|
||||
bool IsTopMost() { return((mVFlags & NS_VIEW_FLAG_TOPMOST) != 0); }
|
||||
|
||||
void ResetWidgetBounds(bool aRecurse, bool aMoveOnly, bool aInvalidateChangedSize);
|
||||
void ResetWidgetBounds(bool aRecurse, bool aForceSync);
|
||||
void AssertNoWindow();
|
||||
|
||||
void NotifyEffectiveVisibilityChanged(bool aEffectivelyVisible);
|
||||
|
@ -105,6 +105,7 @@ nsViewManager::nsViewManager()
|
||||
// NOTE: we use a zeroing operator new, so all data members are
|
||||
// assumed to be cleared here.
|
||||
mHasPendingUpdates = false;
|
||||
mHasPendingWidgetGeometryChanges = false;
|
||||
mRecursiveRefreshPending = false;
|
||||
}
|
||||
|
||||
@ -395,7 +396,8 @@ void nsViewManager::RenderViews(nsView *aView, nsIWidget *aWidget,
|
||||
}
|
||||
}
|
||||
|
||||
void nsViewManager::ProcessPendingUpdatesForView(nsView* aView)
|
||||
void nsViewManager::ProcessPendingUpdatesForView(nsView* aView,
|
||||
bool aFlushDirtyRegion)
|
||||
{
|
||||
NS_ASSERTION(IsRootVM(), "Updates will be missed");
|
||||
|
||||
@ -405,18 +407,20 @@ void nsViewManager::ProcessPendingUpdatesForView(nsView* aView)
|
||||
}
|
||||
|
||||
if (aView->HasWidget()) {
|
||||
aView->ResetWidgetBounds(false, false, true);
|
||||
aView->ResetWidgetBounds(false, true);
|
||||
}
|
||||
|
||||
// process pending updates in child view.
|
||||
for (nsView* childView = aView->GetFirstChild(); childView;
|
||||
childView = childView->GetNextSibling()) {
|
||||
ProcessPendingUpdatesForView(childView);
|
||||
ProcessPendingUpdatesForView(childView, aFlushDirtyRegion);
|
||||
}
|
||||
|
||||
// Push out updates after we've processed the children; ensures that
|
||||
// damage is applied based on the final widget geometry
|
||||
FlushDirtyRegionToWidget(aView);
|
||||
if (aFlushDirtyRegion) {
|
||||
FlushDirtyRegionToWidget(aView);
|
||||
}
|
||||
}
|
||||
|
||||
void nsViewManager::FlushDirtyRegionToWidget(nsView* aView)
|
||||
@ -459,6 +463,7 @@ nsViewManager::PostPendingUpdate()
|
||||
{
|
||||
nsViewManager* rootVM = RootViewManager();
|
||||
rootVM->mHasPendingUpdates = true;
|
||||
rootVM->mHasPendingWidgetGeometryChanges = true;
|
||||
if (rootVM->mPresShell) {
|
||||
rootVM->mPresShell->ScheduleViewManagerFlush();
|
||||
}
|
||||
@ -1362,11 +1367,25 @@ nsViewManager::ProcessPendingUpdates()
|
||||
}
|
||||
|
||||
if (mHasPendingUpdates) {
|
||||
ProcessPendingUpdatesForView(mRootView);
|
||||
ProcessPendingUpdatesForView(mRootView, true);
|
||||
mHasPendingUpdates = false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsViewManager::UpdateWidgetGeometry()
|
||||
{
|
||||
if (!IsRootVM()) {
|
||||
RootViewManager()->UpdateWidgetGeometry();
|
||||
return;
|
||||
}
|
||||
|
||||
if (mHasPendingWidgetGeometryChanges) {
|
||||
ProcessPendingUpdatesForView(mRootView, false);
|
||||
mHasPendingWidgetGeometryChanges = false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsViewManager::CallWillPaintOnObservers(bool aWillSendDidPaint)
|
||||
{
|
||||
|
@ -145,6 +145,7 @@ public:
|
||||
void InvalidateHierarchy();
|
||||
|
||||
virtual void ProcessPendingUpdates();
|
||||
virtual void UpdateWidgetGeometry();
|
||||
|
||||
protected:
|
||||
virtual ~nsViewManager();
|
||||
@ -152,7 +153,8 @@ protected:
|
||||
private:
|
||||
|
||||
void FlushPendingInvalidates();
|
||||
void ProcessPendingUpdatesForView(nsView *aView);
|
||||
void ProcessPendingUpdatesForView(nsView *aView,
|
||||
bool aFlushDirtyRegion = true);
|
||||
void FlushDirtyRegionToWidget(nsView* aView);
|
||||
/**
|
||||
* Call WillPaint() on all view observers under this vm root.
|
||||
@ -241,6 +243,7 @@ private:
|
||||
bool mPainting;
|
||||
bool mRecursiveRefreshPending;
|
||||
bool mHasPendingUpdates;
|
||||
bool mHasPendingWidgetGeometryChanges;
|
||||
bool mInScroll;
|
||||
|
||||
//from here to public should be static and locked... MMP
|
||||
|
Loading…
Reference in New Issue
Block a user