tor-browser

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

commit b29a50ebafaf877deaf51650767e8fb2392f6e8f
parent d673d2a47124bbf7f250cb86f6e1b5aafd76b6dd
Author: Serban Stanca <sstanca@mozilla.com>
Date:   Wed, 12 Nov 2025 12:14:33 +0200

Revert "Bug 1999623 - Remove view to widget offset. r=tnikkel,layout-reviewers" for causing build bustages in nsLayoutUtils.cpp.

This reverts commit e0b9d3d67032ec26a9ac82dc84dba9e924761de5.

Diffstat:
Mlayout/base/PresShell.cpp | 7+++++--
Mlayout/generic/nsIFrame.cpp | 1+
Mview/nsView.cpp | 44+++++++++++++++++++++++++++++++++++++++++++-
Mview/nsView.h | 10++++++++++
Mview/nsViewManager.cpp | 12++++++++++++
Mview/nsViewManager.h | 7+++++++
6 files changed, 78 insertions(+), 3 deletions(-)

diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp @@ -5961,7 +5961,9 @@ void PresShell::ProcessSynthMouseOrPointerMoveEvent( if (rootView->GetFrame()) { popupFrame = FindPopupFrame(mPresContext, rootView->GetWidget(), LayoutDeviceIntPoint::FromAppUnitsToNearest( - aPointerInfo.mLastRefPointInRootDoc, APD)); + aPointerInfo.mLastRefPointInRootDoc + + rootView->ViewToWidgetOffset(), + APD)); if (popupFrame) { pointShell = popupFrame->PresShell(); widget = popupFrame->GetWidget(); @@ -5985,7 +5987,8 @@ void PresShell::ProcessSynthMouseOrPointerMoveEvent( // pointView can be null in situations related to mouse capture pointShell = (pointView ? pointView : rootView)->GetPresShell(); bbc = GetChildBrowser(pointView); - refpoint = aPointerInfo.mLastRefPointInRootDoc; + refpoint = + aPointerInfo.mLastRefPointInRootDoc + rootView->ViewToWidgetOffset(); } NS_ASSERTION(widget, "view should have a widget here"); Maybe<WidgetMouseEvent> mouseMoveEvent; diff --git a/layout/generic/nsIFrame.cpp b/layout/generic/nsIFrame.cpp @@ -7868,6 +7868,7 @@ nsIWidget* nsIFrame::GetNearestWidget(nsPoint& aOffset) const { } if (auto* view = frame->GetView()) { if (auto* widget = view->GetWidget()) { + aOffset += view->ViewToWidgetOffset(); aOffset = aOffset.ScaleToOtherAppUnits(curAPD, targetAPD); return widget; } diff --git a/view/nsView.cpp b/view/nsView.cpp @@ -181,6 +181,29 @@ static LayoutDeviceIntRect WidgetViewBoundsToDevicePixels( aViewBounds.mRoundTo); } +LayoutDeviceIntRect nsView::CalcWidgetBounds(WindowType aType, + TransparencyMode aTransparency) { + int32_t p2a = mViewManager->AppUnitsPerDevPixel(); + auto viewBounds = + CalcWidgetViewBounds(mDimBounds, p2a, nullptr, mWindow.get(), aType); + auto newBounds = + WidgetViewBoundsToDevicePixels(viewBounds, p2a, aType, aTransparency); + + // Compute where the top-left of our widget ended up relative to the parent + // widget, in appunits. + nsPoint roundedOffset(NSIntPixelsToAppUnits(newBounds.X(), p2a), + NSIntPixelsToAppUnits(newBounds.Y(), p2a)); + + // mViewToWidgetOffset is added to coordinates relative to the view origin + // to get coordinates relative to the widget. + // The view origin, relative to the parent widget, is at + // mDimBounds.TopLeft() + viewBounds.TopLeft(). + // Our widget, relative to the parent widget, is roundedOffset. + mViewToWidgetOffset = + mDimBounds.TopLeft() + viewBounds.mBounds.TopLeft() - roundedOffset; + return newBounds; +} + LayoutDeviceIntRect nsView::CalcWidgetBounds( const nsRect& aBounds, int32_t aAppUnitsPerDevPixel, nsIFrame* aParentFrame, nsIWidget* aThisWidget, WindowType aType, TransparencyMode aTransparency) { @@ -190,7 +213,23 @@ LayoutDeviceIntRect nsView::CalcWidgetBounds( aTransparency); } -void nsView::SetDimensions(const nsRect& aRect) { mDimBounds = aRect; } +LayoutDeviceIntRect nsView::RecalcWidgetBounds() { + MOZ_ASSERT(mWindow); + return CalcWidgetBounds(mWindow->GetWindowType(), + mWindow->GetTransparencyMode()); +} + +void nsView::SetDimensions(const nsRect& aRect) { + // Don't use nsRect's operator== here, since it returns true when + // both rects are empty even if they have different widths and we + // have cases where that sort of thing matters to us. + if (mDimBounds.TopLeft() == aRect.TopLeft() && + mDimBounds.Size() == aRect.Size()) { + return; + } + + mDimBounds = aRect; +} void nsView::SetNeedsWindowPropertiesSync() { mNeedsWindowPropertiesSync = true; @@ -229,6 +268,9 @@ void nsView::AttachToTopLevelWidget(nsIWidget* aWidget) { mWindow->AsyncEnableDragDrop(true); } mWidgetIsTopLevel = true; + + // Refresh the view bounds + RecalcWidgetBounds(); } // Detach this view from an attached widget. diff --git a/view/nsView.h b/view/nsView.h @@ -252,6 +252,14 @@ class nsView final : public nsIWidgetListener { LayoutDeviceIntRect CalcWidgetBounds(mozilla::widget::WindowType, mozilla::widget::TransparencyMode); + LayoutDeviceIntRect RecalcWidgetBounds(); + + // This is an app unit offset to add when converting view coordinates to + // widget coordinates. It is the offset in view coordinates from widget + // origin (unlike views, widgets can't extend above or to the left of their + // origin) to view origin expressed in appunits of this. + nsPoint ViewToWidgetOffset() const { return mViewToWidgetOffset; } + // nsIWidgetListener mozilla::PresShell* GetPresShell() override; nsView* GetView() override { return this; } @@ -313,6 +321,8 @@ class nsView final : public nsIWidgetListener { nsIFrame* mFrame; // relative to parent, but in our appunits nsRect mDimBounds; + // in our appunits + nsPoint mViewToWidgetOffset; bool mWidgetIsTopLevel; bool mForcedRepaint; bool mNeedsWindowPropertiesSync; diff --git a/view/nsViewManager.cpp b/view/nsViewManager.cpp @@ -531,6 +531,18 @@ void nsViewManager::ResizeView(nsView* aView, const nsRect& aRect) { // because layout will change it back again if necessary. } +LayoutDeviceIntRect nsViewManager::ViewToWidget(nsView* aView, + const nsRect& aRect) const { + NS_ASSERTION(aView->GetViewManager() == this, "wrong view manager"); + + // account for the view's origin not lining up with the widget's + nsRect rect = aRect + aView->ViewToWidgetOffset(); + + // finally, convert to device coordinates. + return LayoutDeviceIntRect::FromUnknownRect( + rect.ToOutsidePixels(AppUnitsPerDevPixel())); +} + void nsViewManager::IsPainting(bool& aIsPainting) { aIsPainting = IsPainting(); } diff --git a/view/nsViewManager.h b/view/nsViewManager.h @@ -204,6 +204,13 @@ class nsViewManager final { MOZ_CAN_RUN_SCRIPT void Refresh(nsView* aView, const LayoutDeviceIntRegion& aRegion); + /** + * Intersects aRect with aView's bounds and then transforms it from aView's + * coordinate system to the coordinate system of the widget attached to + * aView. + */ + LayoutDeviceIntRect ViewToWidget(nsView* aView, const nsRect& aRect) const; + MOZ_CAN_RUN_SCRIPT_BOUNDARY void DoSetWindowDimensions(nscoord aWidth, nscoord aHeight); bool ShouldDelayResize() const;