tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 3b9fd7d6dbf2f8bc0a428887a0611a66ebcbf0bd
parent e787eae82043d0ad011ca6b5f1691ebe4faf5158
Author: Emilio Cobos Álvarez <emilio@crisal.io>
Date:   Fri, 14 Nov 2025 01:48:16 +0000

Bug 1999868 - Simplify PresShell's / nsViewManager resize APIs. r=tnikkel,layout-reviewers

Differential Revision: https://phabricator.services.mozilla.com/D272384

Diffstat:
Mlayout/base/GeckoMVMContext.cpp | 3+--
Mlayout/base/PresShell.cpp | 52+++++++++++++++++++++++++---------------------------
Mlayout/base/PresShell.h | 13++++---------
Mlayout/base/nsDocumentViewer.cpp | 17+++++++----------
Mlayout/base/nsPresContext.cpp | 23++++++++---------------
Mview/nsView.cpp | 5++---
Mview/nsViewManager.cpp | 76++++++++++++++++++++++++++++++++++------------------------------------------
Mview/nsViewManager.h | 20+++++---------------
8 files changed, 86 insertions(+), 123 deletions(-)

diff --git a/layout/base/GeckoMVMContext.cpp b/layout/base/GeckoMVMContext.cpp @@ -204,8 +204,7 @@ void GeckoMVMContext::Reflow(const CSSSize& aNewSize) { MOZ_ASSERT(doc); MOZ_ASSERT(ps); - if (ps->ResizeReflowIgnoreOverride(CSSPixel::ToAppUnits(aNewSize.width), - CSSPixel::ToAppUnits(aNewSize.height))) { + if (ps->ResizeReflowIgnoreOverride(CSSPixel::ToAppUnits(aNewSize))) { doc->FlushPendingNotifications(FlushType::InterruptibleLayout); } } diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp @@ -1792,13 +1792,10 @@ void PresShell::RefreshZoomConstraintsForScreenSizeChange() { } void PresShell::ForceResizeReflowWithCurrentDimensions() { - nscoord currentWidth = 0; - nscoord currentHeight = 0; - mViewManager->GetWindowDimensions(&currentWidth, &currentHeight); - ResizeReflow(currentWidth, currentHeight); + ResizeReflow(mViewManager->GetWindowDimensions()); } -void PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight, +void PresShell::ResizeReflow(const nsSize& aSize, ResizeReflowOptions aOptions) { if (mZoomConstraintsClient) { // If we have a ZoomConstraintsClient and the available screen area @@ -1816,21 +1813,21 @@ void PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight, mMobileViewportManager->RequestReflow(false); return; } - ResizeReflowIgnoreOverride(aWidth, aHeight, aOptions); + ResizeReflowIgnoreOverride(aSize, aOptions); } -bool PresShell::SimpleResizeReflow(nscoord aWidth, nscoord aHeight) { - MOZ_ASSERT(aWidth != NS_UNCONSTRAINEDSIZE); - MOZ_ASSERT(aHeight != NS_UNCONSTRAINEDSIZE); +bool PresShell::SimpleResizeReflow(const nsSize& aSize) { + MOZ_ASSERT(aSize.width != NS_UNCONSTRAINEDSIZE); + MOZ_ASSERT(aSize.height != NS_UNCONSTRAINEDSIZE); nsSize oldSize = mPresContext->GetVisibleArea().Size(); - mPresContext->SetVisibleArea(nsRect(0, 0, aWidth, aHeight)); + mPresContext->SetVisibleArea(nsRect(nsPoint(), aSize)); nsIFrame* rootFrame = GetRootFrame(); if (!rootFrame) { return false; } WritingMode wm = rootFrame->GetWritingMode(); - bool isBSizeChanging = - wm.IsVertical() ? oldSize.width != aWidth : oldSize.height != aHeight; + bool isBSizeChanging = wm.IsVertical() ? oldSize.width != aSize.width + : oldSize.height != aSize.height; if (isBSizeChanging) { nsLayoutUtils::MarkIntrinsicISizesDirtyIfDependentOnBSize(rootFrame); rootFrame->SetHasBSizeChange(true); @@ -1898,7 +1895,7 @@ void PresShell::ScheduleResizeEventIfNeeded(ResizeEventKind aKind) { RenderingPhase::ResizeSteps); } -bool PresShell::ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight, +bool PresShell::ResizeReflowIgnoreOverride(const nsSize& aSize, ResizeReflowOptions aOptions) { MOZ_ASSERT(!mIsReflowing, "Shouldn't be in reflow here!"); @@ -1922,11 +1919,11 @@ bool PresShell::ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight, if (!(aOptions & ResizeReflowOptions::BSizeLimit)) { nsSize oldSize = mPresContext->GetVisibleArea().Size(); - if (oldSize == nsSize(aWidth, aHeight)) { + if (oldSize == aSize) { return false; } - bool changed = SimpleResizeReflow(aWidth, aHeight); + bool changed = SimpleResizeReflow(aSize); postResizeEventIfNeeded(); return changed; } @@ -1944,31 +1941,32 @@ bool PresShell::ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight, // If we don't have a root frame yet, that means we haven't had our initial // reflow... If that's the case, and aWidth or aHeight is unconstrained, // ignore them altogether. - if (aHeight == NS_UNCONSTRAINEDSIZE || aWidth == NS_UNCONSTRAINEDSIZE) { + if (aSize.height == NS_UNCONSTRAINEDSIZE || + aSize.width == NS_UNCONSTRAINEDSIZE) { // We can't do the work needed for SizeToContent without a root // frame, and we want to return before setting the visible area. return false; } - mPresContext->SetVisibleArea(nsRect(0, 0, aWidth, aHeight)); + mPresContext->SetVisibleArea(nsRect(nsPoint(), aSize)); // There isn't anything useful we can do if the initial reflow hasn't // happened. return true; } WritingMode wm = rootFrame->GetWritingMode(); - MOZ_ASSERT((wm.IsVertical() ? aHeight : aWidth) != NS_UNCONSTRAINEDSIZE, - "unconstrained isize not allowed"); + MOZ_ASSERT( + (wm.IsVertical() ? aSize.height : aSize.width) != NS_UNCONSTRAINEDSIZE, + "unconstrained isize not allowed"); - nscoord targetWidth = aWidth; - nscoord targetHeight = aHeight; + nsSize targetSize = aSize; if (wm.IsVertical()) { - targetWidth = NS_UNCONSTRAINEDSIZE; + targetSize.width = NS_UNCONSTRAINEDSIZE; } else { - targetHeight = NS_UNCONSTRAINEDSIZE; + targetSize.height = NS_UNCONSTRAINEDSIZE; } - mPresContext->SetVisibleArea(nsRect(0, 0, targetWidth, targetHeight)); + mPresContext->SetVisibleArea(nsRect(nsPoint(), targetSize)); // XXX Do a full invalidate at the beginning so that invalidates along // the way don't have region accumulation issues? @@ -1991,11 +1989,11 @@ bool PresShell::ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight, DoReflow(rootFrame, true, nullptr); const bool reflowAgain = - wm.IsVertical() ? mPresContext->GetVisibleArea().width > aWidth - : mPresContext->GetVisibleArea().height > aHeight; + wm.IsVertical() ? mPresContext->GetVisibleArea().width > aSize.width + : mPresContext->GetVisibleArea().height > aSize.height; if (reflowAgain) { - mPresContext->SetVisibleArea(nsRect(0, 0, aWidth, aHeight)); + mPresContext->SetVisibleArea(nsRect(nsPoint(), aSize)); rootFrame->SetHasBSizeChange(true); DoReflow(rootFrame, true, nullptr); } diff --git a/layout/base/PresShell.h b/layout/base/PresShell.h @@ -359,17 +359,12 @@ class PresShell final : public nsStubDocumentObserver, MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult Initialize(); /** - * Schedule a reflow for the frame model into a new width and height. The - * coordinates for aWidth and aHeight must be in standard nscoord's. - * - * Returns whether layout might have changed. + * Schedule a reflow for the frame model into a new size, in app units. */ MOZ_CAN_RUN_SCRIPT void ResizeReflow( - nscoord aWidth, nscoord aHeight, - ResizeReflowOptions = ResizeReflowOptions::NoOption); + const nsSize&, ResizeReflowOptions = ResizeReflowOptions::NoOption); MOZ_CAN_RUN_SCRIPT bool ResizeReflowIgnoreOverride( - nscoord aWidth, nscoord aHeight, - ResizeReflowOptions = ResizeReflowOptions::NoOption); + const nsSize&, ResizeReflowOptions = ResizeReflowOptions::NoOption); MOZ_CAN_RUN_SCRIPT void ForceResizeReflowWithCurrentDimensions(); /** Schedule a resize event if applicable. */ @@ -398,7 +393,7 @@ class PresShell final : public nsStubDocumentObserver, * This is what ResizeReflowIgnoreOverride does when not shrink-wrapping (that * is, when ResizeReflowOptions::BSizeLimit is not specified). */ - bool SimpleResizeReflow(nscoord aWidth, nscoord aHeight); + bool SimpleResizeReflow(const nsSize&); bool CanHandleUserInputEvents(WidgetGUIEvent* aGUIEvent); diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp @@ -714,8 +714,7 @@ nsresult nsDocumentViewer::InitPresentationStuff(bool aDoInitialReflow) { mPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom()); const nsSize size = LayoutDevicePixel::ToAppUnits(mBounds.Size(), p2a); - - mViewManager->SetWindowDimensions(size.width, size.height); + mViewManager->SetWindowDimensions(size); mPresContext->SetInitialVisibleArea(nsRect(nsPoint(), size)); // We rely on the default zoom not being initialized until here. mPresContext->RecomputeBrowsingContextDependentData(); @@ -1915,8 +1914,7 @@ nsDocumentViewer::SetBoundsWithFlags(const LayoutDeviceIntRect& aBounds, } int32_t p2a = mPresContext->AppUnitsPerDevPixel(); - nscoord width = NSIntPixelsToAppUnits(mBounds.width, p2a); - nscoord height = NSIntPixelsToAppUnits(mBounds.height, p2a); + const nsSize size = LayoutDeviceSize::ToAppUnits(mBounds.Size(), p2a); nsView* rootView = mViewManager->GetRootView(); if (boundsChanged && rootView) { nsRect viewDims = rootView->GetBounds(); @@ -1929,7 +1927,7 @@ nsDocumentViewer::SetBoundsWithFlags(const LayoutDeviceIntRect& aBounds, // if they are the same as the new size it won't do anything, but we still // need to invalidate because what we want to draw to the screen has // changed. - if (viewDims.width == width && viewDims.height == height) { + if (viewDims.Size() == size) { if (nsIFrame* f = rootView->GetFrame()) { f->InvalidateFrame(); @@ -1943,7 +1941,7 @@ nsDocumentViewer::SetBoundsWithFlags(const LayoutDeviceIntRect& aBounds, } mViewManager->SetWindowDimensions( - width, height, !!(aFlags & nsIDocumentViewer::eDelayResize)); + size, !!(aFlags & nsIDocumentViewer::eDelayResize)); } // If there's a previous viewer, it's the one that's actually showing, @@ -2569,10 +2567,9 @@ MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP nsDocumentViewer::GetContentSize( // Just bail if that happens. NS_ENSURE_TRUE(prefISize != NS_UNCONSTRAINEDSIZE, NS_ERROR_FAILURE); - nscoord height = wm.IsVertical() ? prefISize : aMaxHeight; - nscoord width = wm.IsVertical() ? aMaxWidth : prefISize; - - presShell->ResizeReflow(width, height, ResizeReflowOptions::BSizeLimit); + const nsSize size(wm.IsVertical() ? aMaxWidth : prefISize, + wm.IsVertical() ? prefISize : aMaxHeight); + presShell->ResizeReflow(size, ResizeReflowOptions::BSizeLimit); RefPtr<nsPresContext> presContext = GetPresContext(); NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE); diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp @@ -544,20 +544,16 @@ void nsPresContext::PreferenceChanged(const char* aPrefName) { OwningNonNull<mozilla::PresShell> presShell(*mPresShell); // Re-fetch the view manager's window dimensions in case there's a // deferred resize which hasn't affected our mVisibleArea yet - nscoord oldWidthAppUnits, oldHeightAppUnits; RefPtr<nsViewManager> vm = presShell->GetViewManager(); if (!vm) { return; } - vm->GetWindowDimensions(&oldWidthAppUnits, &oldHeightAppUnits); - float oldWidthDevPixels = oldWidthAppUnits / oldAppUnitsPerDevPixel; - float oldHeightDevPixels = oldHeightAppUnits / oldAppUnitsPerDevPixel; + auto oldSizeDevPixels = LayoutDeviceSize::FromAppUnits( + vm->GetWindowDimensions(), oldAppUnitsPerDevPixel); UIResolutionChangedInternal(); - - nscoord width = NSToCoordRound(oldWidthDevPixels * AppUnitsPerDevPixel()); - nscoord height = NSToCoordRound(oldHeightDevPixels * AppUnitsPerDevPixel()); - vm->SetWindowDimensions(width, height); + vm->SetWindowDimensions( + LayoutDeviceSize::ToAppUnits(oldSizeDevPixels, AppUnitsPerDevPixel())); return; } @@ -1402,11 +1398,9 @@ void nsPresContext::SetFullZoom(float aZoom) { // Re-fetch the view manager's window dimensions in case there's a deferred // resize which hasn't affected our mVisibleArea yet - nscoord oldWidthAppUnits, oldHeightAppUnits; - mPresShell->GetViewManager()->GetWindowDimensions(&oldWidthAppUnits, - &oldHeightAppUnits); - float oldWidthDevPixels = oldWidthAppUnits / float(mCurAppUnitsPerDevPixel); - float oldHeightDevPixels = oldHeightAppUnits / float(mCurAppUnitsPerDevPixel); + const auto oldSizeDevPixels = LayoutDeviceSize::FromAppUnits( + mPresShell->GetViewManager()->GetWindowDimensions(), + mCurAppUnitsPerDevPixel); mDeviceContext->SetFullZoom(aZoom); mFullZoom = aZoom; @@ -1414,8 +1408,7 @@ void nsPresContext::SetFullZoom(float aZoom) { AppUnitsPerDevPixelChanged(); mPresShell->GetViewManager()->SetWindowDimensions( - NSToCoordRound(oldWidthDevPixels * AppUnitsPerDevPixel()), - NSToCoordRound(oldHeightDevPixels * AppUnitsPerDevPixel())); + LayoutDeviceSize::ToAppUnits(oldSizeDevPixels, AppUnitsPerDevPixel())); } void nsPresContext::SetOverrideDPPX(float aDPPX) { diff --git a/view/nsView.cpp b/view/nsView.cpp @@ -341,9 +341,8 @@ bool nsView::WindowResized(nsIWidget* aWidget, int32_t aWidth, // due to a call to e.g. nsDocumentViewer::GetContentSize or so. frame->InvalidateFrame(); } - - mViewManager->SetWindowDimensions(NSIntPixelsToAppUnits(aWidth, p2a), - NSIntPixelsToAppUnits(aHeight, p2a)); + const LayoutDeviceIntSize size(aWidth, aHeight); + mViewManager->SetWindowDimensions(LayoutDeviceIntSize::ToAppUnits(size, p2a)); if (nsXULPopupManager* pm = nsXULPopupManager::GetInstance()) { pm->AdjustPopupsOnWindowChange(ps); diff --git a/view/nsViewManager.cpp b/view/nsViewManager.cpp @@ -85,33 +85,24 @@ void nsViewManager::SetRootView(nsView* aView) { mRootView = aView; } -void nsViewManager::GetWindowDimensions(nscoord* aWidth, nscoord* aHeight) { - if (nullptr != mRootView) { - if (mDelayedResize == nsSize(NSCOORD_NONE, NSCOORD_NONE)) { - nsRect dim = mRootView->GetBounds(); - *aWidth = dim.Width(); - *aHeight = dim.Height(); - } else { - *aWidth = mDelayedResize.width; - *aHeight = mDelayedResize.height; - } - } else { - *aWidth = 0; - *aHeight = 0; +nsSize nsViewManager::GetWindowDimensions() const { + if (!mRootView) { + return {}; + } + if (mDelayedResize != nsSize(NSCOORD_NONE, NSCOORD_NONE)) { + return mDelayedResize; } + return mRootView->GetBounds().Size(); } -void nsViewManager::DoSetWindowDimensions(nscoord aWidth, nscoord aHeight) { - nsRect oldDim = mRootView->GetBounds(); - nsRect newDim(0, 0, aWidth, aHeight); - // We care about resizes even when one dimension is already zero. - if (oldDim.IsEqualEdges(newDim)) { +void nsViewManager::DoSetWindowDimensions(const nsSize& aSize) { + if (mRootView->GetBounds().Size() == aSize) { return; } // Don't resize the widget. It is already being set elsewhere. - mRootView->SetDimensions(newDim); + mRootView->SetDimensions(nsRect(nsPoint(), aSize)); if (RefPtr<PresShell> presShell = mPresShell) { - presShell->ResizeReflow(aWidth, aHeight); + presShell->ResizeReflow(aSize); } } @@ -128,35 +119,36 @@ bool nsViewManager::ShouldDelayResize() const { return false; } -void nsViewManager::SetWindowDimensions(nscoord aWidth, nscoord aHeight, +void nsViewManager::SetWindowDimensions(const nsSize& aSize, bool aDelayResize) { - if (mRootView) { - if (!ShouldDelayResize() && !aDelayResize) { - if (mDelayedResize != nsSize(NSCOORD_NONE, NSCOORD_NONE) && - mDelayedResize != nsSize(aWidth, aHeight)) { - // We have a delayed resize; that now obsolete size may already have - // been flushed to the PresContext so we need to update the PresContext - // with the new size because if the new size is exactly the same as the - // root view's current size then DoSetWindowDimensions will not - // request a resize reflow (which would correct it). See bug 617076. - mDelayedResize = nsSize(aWidth, aHeight); - FlushDelayedResize(); - } - mDelayedResize.SizeTo(NSCOORD_NONE, NSCOORD_NONE); - DoSetWindowDimensions(aWidth, aHeight); - } else { - mDelayedResize.SizeTo(aWidth, aHeight); - if (mPresShell) { - mPresShell->SetNeedStyleFlush(); - mPresShell->SetNeedLayoutFlush(); - } + if (!mRootView) { + return; + } + if (!ShouldDelayResize() && !aDelayResize) { + if (mDelayedResize != nsSize(NSCOORD_NONE, NSCOORD_NONE) && + mDelayedResize != aSize) { + // We have a delayed resize; that now obsolete size may already have + // been flushed to the PresContext so we need to update the PresContext + // with the new size because if the new size is exactly the same as the + // root view's current size then DoSetWindowDimensions will not + // request a resize reflow (which would correct it). See bug 617076. + mDelayedResize = aSize; + FlushDelayedResize(); + } + mDelayedResize.SizeTo(NSCOORD_NONE, NSCOORD_NONE); + DoSetWindowDimensions(aSize); + } else { + mDelayedResize = aSize; + if (mPresShell) { + mPresShell->SetNeedStyleFlush(); + mPresShell->SetNeedLayoutFlush(); } } } void nsViewManager::FlushDelayedResize() { if (mDelayedResize != nsSize(NSCOORD_NONE, NSCOORD_NONE)) { - DoSetWindowDimensions(mDelayedResize.width, mDelayedResize.height); + DoSetWindowDimensions(mDelayedResize); mDelayedResize.SizeTo(NSCOORD_NONE, NSCOORD_NONE); } } diff --git a/view/nsViewManager.h b/view/nsViewManager.h @@ -67,23 +67,14 @@ class nsViewManager final { */ void SetRootView(nsView* aView); - /** - * Get the dimensions of the root window. The dimensions are in - * twips - * @param aWidth out parameter for width of window in twips - * @param aHeight out parameter for height of window in twips - */ - void GetWindowDimensions(nscoord* aWidth, nscoord* aHeight); + /** Get the dimensions of the root view. */ + nsSize GetWindowDimensions() const; /** * Set the dimensions of the root window. - * Called if the root window is resized. The dimensions are in - * twips - * @param aWidth of window in twips - * @param aHeight of window in twips + * Called if the root window is resized. */ - void SetWindowDimensions(nscoord aWidth, nscoord aHeight, - bool aDelayResize = false); + void SetWindowDimensions(const nsSize& aSize, bool aDelayResize = false); /** * Do any resizes that are pending. @@ -175,8 +166,7 @@ class nsViewManager final { MOZ_CAN_RUN_SCRIPT void Refresh(nsView* aView, const LayoutDeviceIntRegion& aRegion); - MOZ_CAN_RUN_SCRIPT_BOUNDARY - void DoSetWindowDimensions(nscoord aWidth, nscoord aHeight); + MOZ_CAN_RUN_SCRIPT_BOUNDARY void DoSetWindowDimensions(const nsSize&); bool ShouldDelayResize() const; bool IsPainting() const { return RootViewManager()->mPainting; }