tor-browser

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

commit ee81313552142c076e7421c8a3949ee9d3c9788f
parent 5c7b1adb9c3f08f3402dc3402cd4ddc959984e5e
Author: Emilio Cobos Álvarez <emilio@crisal.io>
Date:   Sat, 22 Nov 2025 19:52:21 +0000

Bug 2000998 - Move widget bounds to nsMenuPopupFrame. r=tnikkel,layout-reviewers

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

Diffstat:
Mlayout/xul/nsMenuPopupFrame.cpp | 27+++++++++++++++++++++++----
Mview/nsView.cpp | 73-------------------------------------------------------------------------
Mview/nsView.h | 13-------------
3 files changed, 23 insertions(+), 90 deletions(-)

diff --git a/layout/xul/nsMenuPopupFrame.cpp b/layout/xul/nsMenuPopupFrame.cpp @@ -68,6 +68,7 @@ #include "nsXULPopupManager.h" using namespace mozilla; +using namespace mozilla::widget; using mozilla::dom::Document; using mozilla::dom::Element; using mozilla::dom::Event; @@ -339,10 +340,28 @@ void nsMenuPopupFrame::CreateWidget() { } LayoutDeviceIntRect nsMenuPopupFrame::CalcWidgetBounds() const { - return nsView::CalcWidgetBounds( - GetRect(), PresContext()->AppUnitsPerDevPixel(), - PresShell()->GetRootFrame(), nullptr, widget::WindowType::Popup, - nsLayoutUtils::GetFrameTransparency(this, this)); + auto a2d = PresContext()->AppUnitsPerDevPixel(); + nsPoint offset; + nsIWidget* parentWidget = + PresShell()->GetRootFrame()->GetNearestWidget(offset); + // We want the bounds be relative to the parent widget, in appunits + if (parentWidget) { + // put offset into screen coordinates. (based on client area origin) + offset += LayoutDeviceIntPoint::ToAppUnits( + parentWidget->WidgetToScreenOffset(), a2d); + } + int32_t roundTo = + parentWidget ? parentWidget->RoundsWidgetCoordinatesTo() : 1; + auto bounds = GetRect() + offset; + // We use outside pixels for transparent windows if possible, so that we + // don't truncate the contents. For opaque popups, we use nearest pixels + // which prevents having pixels not drawn by the frame. + const auto transparency = nsLayoutUtils::GetFrameTransparency(this, this); + const bool opaque = transparency == TransparencyMode::Opaque; + const auto idealBounds = LayoutDeviceIntRect::FromUnknownRect( + opaque ? bounds.ToNearestPixels(a2d) : bounds.ToOutsidePixels(a2d)); + return nsIWidget::MaybeRoundToDisplayPixels(idealBounds, transparency, + roundTo); } void nsMenuPopupFrame::DestroyWidget() { diff --git a/view/nsView.cpp b/view/nsView.cpp @@ -91,69 +91,6 @@ void nsView::Destroy() { nsView::operator delete(this); } -struct WidgetViewBounds { - nsRect mBounds; - int32_t mRoundTo = 1; -}; - -static WidgetViewBounds CalcWidgetViewBounds(const nsRect& aBounds, - int32_t aAppUnitsPerDevPixel, - nsIFrame* aParentFrame, - nsIWidget* aThisWidget, - WindowType aType) { - nsRect viewBounds(aBounds); - nsIWidget* parentWidget = nullptr; - if (aParentFrame) { - nsPoint offset; - parentWidget = aParentFrame->GetNearestWidget(offset); - // make viewBounds be relative to the parent widget, in appunits - viewBounds += offset; - - if (parentWidget && aType == WindowType::Popup) { - // put offset into screen coordinates. (based on client area origin) - LayoutDeviceIntPoint screenPoint = parentWidget->WidgetToScreenOffset(); - viewBounds += - nsPoint(NSIntPixelsToAppUnits(screenPoint.x, aAppUnitsPerDevPixel), - NSIntPixelsToAppUnits(screenPoint.y, aAppUnitsPerDevPixel)); - } - } - - nsIWidget* widget = parentWidget ? parentWidget : aThisWidget; - int32_t roundTo = widget ? widget->RoundsWidgetCoordinatesTo() : 1; - return {viewBounds, roundTo}; -} - -static LayoutDeviceIntRect WidgetViewBoundsToDevicePixels( - const WidgetViewBounds& aViewBounds, int32_t aAppUnitsPerDevPixel, - WindowType aType, TransparencyMode aTransparency) { - // Compute widget bounds in device pixels - // TODO(emilio): We should probably use outside pixels for transparent - // windows (not just popups) as well. - if (aType != WindowType::Popup) { - return LayoutDeviceIntRect::FromUnknownRect( - aViewBounds.mBounds.ToNearestPixels(aAppUnitsPerDevPixel)); - } - // We use outside pixels for transparent windows if possible, so that we - // don't truncate the contents. For opaque popups, we use nearest pixels - // which prevents having pixels not drawn by the frame. - const bool opaque = aTransparency == TransparencyMode::Opaque; - const auto idealBounds = LayoutDeviceIntRect::FromUnknownRect( - opaque ? aViewBounds.mBounds.ToNearestPixels(aAppUnitsPerDevPixel) - : aViewBounds.mBounds.ToOutsidePixels(aAppUnitsPerDevPixel)); - - return nsIWidget::MaybeRoundToDisplayPixels(idealBounds, aTransparency, - aViewBounds.mRoundTo); -} - -LayoutDeviceIntRect nsView::CalcWidgetBounds( - const nsRect& aBounds, int32_t aAppUnitsPerDevPixel, nsIFrame* aParentFrame, - nsIWidget* aThisWidget, WindowType aType, TransparencyMode aTransparency) { - auto viewBounds = CalcWidgetViewBounds(aBounds, aAppUnitsPerDevPixel, - aParentFrame, aThisWidget, aType); - return WidgetViewBoundsToDevicePixels(viewBounds, aAppUnitsPerDevPixel, aType, - aTransparency); -} - // Attach to a top level widget and start receiving mirrored events. void nsView::AttachToTopLevelWidget(nsIWidget* aWidget) { MOZ_ASSERT(aWidget, "null widget ptr"); @@ -219,12 +156,6 @@ void nsView::List(FILE* out, int32_t aIndent) const { } #endif // DEBUG -bool nsView::IsRoot() const { - NS_ASSERTION(mViewManager != nullptr, - " View manager is null in nsView::IsRoot()"); - return mViewManager->GetRootView() == this; -} - PresShell* nsView::GetPresShell() { return GetViewManager()->GetPresShell(); } bool nsView::WindowResized(nsIWidget* aWidget, int32_t aWidth, @@ -378,10 +309,6 @@ nsEventStatus nsView::HandleEvent(WidgetGUIEvent* aEvent) { void nsView::SafeAreaInsetsChanged( const LayoutDeviceIntMargin& aSafeAreaInsets) { - if (!IsRoot()) { - return; - } - PresShell* presShell = mViewManager->GetPresShell(); if (!presShell) { return; diff --git a/view/nsView.h b/view/nsView.h @@ -192,19 +192,6 @@ class nsView final : public nsIWidgetListener { virtual void List(FILE* out, int32_t aIndent = 0) const; #endif // DEBUG - /** - * @result true iff this is the root view for its view manager - */ - bool IsRoot() const; - - static LayoutDeviceIntRect CalcWidgetBounds( - const nsRect& aBounds, int32_t aAppUnitsPerDevPixel, - nsIFrame* aParentFrame, nsIWidget* aThisWidget, - mozilla::widget::WindowType, mozilla::widget::TransparencyMode); - - LayoutDeviceIntRect CalcWidgetBounds(mozilla::widget::WindowType, - mozilla::widget::TransparencyMode); - // nsIWidgetListener mozilla::PresShell* GetPresShell() override; nsView* GetView() override { return this; }