tor-browser

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

commit d81a1a074fa7c0a4ebc538d329ad8f35cd3d8c85
parent bd2ca4efdc8ef0e379fd98e170b4b254bf6ed05f
Author: Emilio Cobos Álvarez <emilio@crisal.io>
Date:   Fri, 10 Oct 2025 09:33:10 +0000

Bug 1993570 - Introduce nsIWidget::Get{,Popup}Frame. r=layout-reviewers,dshin

And use it instead of manually using views.

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

Diffstat:
Mdom/events/ContentEventHandler.cpp | 4+---
Mgfx/layers/apz/util/APZCCallbackHelper.cpp | 76+++++++++++++++++++++++++++++++++-------------------------------------------
Mgfx/layers/apz/util/ChromeProcessController.cpp | 19++++---------------
Mlayout/base/nsLayoutUtils.cpp | 2+-
Mlayout/xul/moz.build | 1+
Mwidget/gtk/nsWindow.cpp | 42+++++++++++++++---------------------------
Mwidget/gtk/nsWindow.h | 1-
Mwidget/nsBaseWidget.cpp | 17+++++++++++++++++
Mwidget/nsIWidget.h | 7++++++-
Mwidget/windows/nsWindow.cpp | 23+++++++++--------------
10 files changed, 87 insertions(+), 105 deletions(-)

diff --git a/dom/events/ContentEventHandler.cpp b/dom/events/ContentEventHandler.cpp @@ -2974,9 +2974,7 @@ nsresult ContentEventHandler::OnQueryCharacterAtPoint( // a popup but the rootFrame is the document root. if (rootWidget != aEvent->mWidget) { MOZ_ASSERT(aEvent->mWidget, "The event must have the widget"); - nsView* view = nsView::GetViewFor(aEvent->mWidget); - NS_ENSURE_TRUE(view, NS_ERROR_FAILURE); - rootFrame = view->GetFrame(); + rootFrame = aEvent->mWidget->GetFrame(); NS_ENSURE_TRUE(rootFrame, NS_ERROR_FAILURE); rootWidget = rootFrame->GetNearestWidget(); NS_ENSURE_TRUE(rootWidget, NS_ERROR_FAILURE); diff --git a/gfx/layers/apz/util/APZCCallbackHelper.cpp b/gfx/layers/apz/util/APZCCallbackHelper.cpp @@ -33,6 +33,7 @@ #include "mozilla/dom/Document.h" #include "nsIInterfaceRequestorUtils.h" #include "nsLayoutUtils.h" +#include "nsMenuPopupFrame.h" #include "nsPrintfCString.h" #include "nsPIDOMWindow.h" #include "nsRefreshDriver.h" @@ -644,20 +645,14 @@ static dom::Element* GetDisplayportElementFor( static dom::Element* GetRootElementFor(nsIWidget* aWidget) { // This returns the root element that ChromeProcessController sets the // displayport on during initialization. - if (nsView* view = nsView::GetViewFor(aWidget)) { - if (aWidget->GetWindowType() == widget::WindowType::Popup) { - MOZ_ASSERT(view->GetFrame() && view->GetFrame()->IsMenuPopupFrame() && - view->GetFrame()->GetContent() && - view->GetFrame()->GetContent()->IsElement()); - return view->GetFrame()->GetContent()->AsElement(); - } - - if (PresShell* presShell = view->GetPresShell()) { - MOZ_ASSERT(presShell->GetDocument()); - return presShell->GetDocument()->GetDocumentElement(); - } + auto* frame = aWidget->GetFrame(); + if (!frame) { + return nullptr; } - return nullptr; + if (frame->IsMenuPopupFrame()) { + return frame->GetContent()->AsElement(); + } + return frame->PresContext()->Document()->GetDocumentElement(); } namespace { @@ -809,15 +804,11 @@ void DisplayportSetListener::OnPostRefresh() { nsIFrame* GetRootFrameForWidget(const nsIWidget* aWidget, const PresShell* aPresShell) { - if (aWidget->GetWindowType() == widget::WindowType::Popup) { + if (auto* popup = aWidget->GetPopupFrame()) { // In the case where the widget is popup window and uses APZ, the widget // frame (i.e. menu popup frame) is the reference frame used for building // the display list for hit-testing inside the popup. - MOZ_ASSERT(aWidget->AsyncPanZoomEnabled()); - if (nsView* view = nsView::GetViewFor(aWidget)) { - MOZ_ASSERT(view->GetFrame() && view->GetFrame()->IsMenuPopupFrame()); - return view->GetFrame(); - } + return popup; } return aPresShell->GetRootFrame(); @@ -983,31 +974,30 @@ void APZCCallbackHelper::CancelAutoscroll( void APZCCallbackHelper::NotifyScaleGestureComplete( const nsCOMPtr<nsIWidget>& aWidget, float aScale) { MOZ_ASSERT(NS_IsMainThread()); - - if (nsView* view = nsView::GetViewFor(aWidget)) { - if (PresShell* presShell = view->GetPresShell()) { - dom::Document* doc = presShell->GetDocument(); - MOZ_ASSERT(doc); - if (nsPIDOMWindowInner* win = doc->GetInnerWindow()) { - dom::AutoJSAPI jsapi; - if (!jsapi.Init(win)) { - return; - } - - JSContext* cx = jsapi.cx(); - JS::Rooted<JS::Value> detail(cx, JS::Float32Value(aScale)); - RefPtr<dom::CustomEvent> event = - NS_NewDOMCustomEvent(doc, nullptr, nullptr); - event->InitCustomEvent(cx, u"MozScaleGestureComplete"_ns, - /* CanBubble */ true, - /* Cancelable */ false, detail); - event->SetTrusted(true); - auto* dispatcher = new AsyncEventDispatcher(doc, event.forget(), - ChromeOnlyDispatch::eYes); - dispatcher->PostDOMEvent(); - } - } + nsIFrame* frame = aWidget->GetFrame(); + if (!frame) { + return; + } + dom::Document* doc = frame->PresShell()->GetDocument(); + MOZ_ASSERT(doc); + nsPIDOMWindowInner* win = doc->GetInnerWindow(); + if (!win) { + return; + } + dom::AutoJSAPI jsapi; + if (!jsapi.Init(win)) { + return; } + JSContext* cx = jsapi.cx(); + JS::Rooted<JS::Value> detail(cx, JS::Float32Value(aScale)); + RefPtr<dom::CustomEvent> event = NS_NewDOMCustomEvent(doc, nullptr, nullptr); + event->InitCustomEvent(cx, u"MozScaleGestureComplete"_ns, + /* CanBubble */ true, + /* Cancelable */ false, detail); + event->SetTrusted(true); + auto* dispatcher = + new AsyncEventDispatcher(doc, event.forget(), ChromeOnlyDispatch::eYes); + dispatcher->PostDOMEvent(); } /* static */ diff --git a/gfx/layers/apz/util/ChromeProcessController.cpp b/gfx/layers/apz/util/ChromeProcessController.cpp @@ -113,10 +113,8 @@ PresShell* ChromeProcessController::GetPresShell() const { if (!mWidget) { return nullptr; } - if (nsView* view = nsView::GetViewFor(mWidget)) { - return view->GetPresShell(); - } - return nullptr; + auto* frame = mWidget->GetFrame(); + return frame ? frame->PresShell() : nullptr; } dom::Document* ChromeProcessController::GetRootDocument() const { @@ -148,7 +146,7 @@ void ChromeProcessController::HandleDoubleTap( MOZ_ASSERT(mUIThread->IsOnCurrentThread()); RefPtr<dom::Document> document = GetRootContentDocument(aGuid.mScrollId); - if (!document.get()) { + if (!document) { return; } @@ -375,14 +373,5 @@ void ChromeProcessController::NotifyScaleGestureComplete( } nsIFrame* ChromeProcessController::GetWidgetFrame() const { - if (!mWidget) { - return nullptr; - } - - nsView* view = nsView::GetViewFor(mWidget); - if (!view) { - return nullptr; - } - - return view->GetFrame(); + return mWidget ? mWidget->GetFrame() : nullptr; } diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp @@ -1602,7 +1602,7 @@ nsIFrame* nsLayoutUtils::GetPopupFrameForPoint( continue; } if (aFlags & GetPopupFrameForPointFlags::OnlyReturnFramesWithWidgets) { - if (!popup->GetView() || !popup->GetView()->HasWidget()) { + if (!popup->GetWidget()) { continue; } } diff --git a/layout/xul/moz.build b/layout/xul/moz.build @@ -15,6 +15,7 @@ if CONFIG["ENABLE_TESTS"]: EXPORTS += [ "nsIPopupContainer.h", "nsIScrollbarMediator.h", + "nsMenuPopupFrame.h", "nsXULPopupManager.h", "nsXULTooltipListener.h", ] diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp @@ -1199,10 +1199,6 @@ bool nsWindow::IsWaylandPopup() const { return GdkIsWaylandDisplay() && IsPopup(); } -static nsMenuPopupFrame* GetMenuPopupFrame(nsIFrame* aFrame) { - return do_QueryFrame(aFrame); -} - void nsWindow::AppendPopupToHierarchyList(nsWindow* aToplevelWindow) { mWaylandToplevel = aToplevelWindow; @@ -1597,7 +1593,7 @@ void nsWindow::WaylandPopupHierarchyCalculatePositions() { (int)(popup->mBounds.height / FractionalScaleFactor())); #ifdef MOZ_LOGGING if (LOG_ENABLED()) { - if (nsMenuPopupFrame* popupFrame = GetMenuPopupFrame(GetFrame())) { + if (nsMenuPopupFrame* popupFrame = GetPopupFrame()) { auto r = LayoutDeviceRect::FromAppUnitsRounded( popupFrame->GetRect(), popupFrame->PresContext()->AppUnitsPerDevPixel()); @@ -1634,7 +1630,7 @@ void nsWindow::WaylandPopupHierarchyCalculatePositions() { } bool nsWindow::WaylandPopupIsContextMenu() { - nsMenuPopupFrame* popupFrame = GetMenuPopupFrame(GetFrame()); + nsMenuPopupFrame* popupFrame = GetPopupFrame(); if (!popupFrame) { return false; } @@ -1642,7 +1638,7 @@ bool nsWindow::WaylandPopupIsContextMenu() { } bool nsWindow::WaylandPopupIsPermanent() { - nsMenuPopupFrame* popupFrame = GetMenuPopupFrame(GetFrame()); + nsMenuPopupFrame* popupFrame = GetPopupFrame(); if (!popupFrame) { // We can always hide popups without frames. return false; @@ -1651,7 +1647,7 @@ bool nsWindow::WaylandPopupIsPermanent() { } bool nsWindow::WaylandPopupIsAnchored() { - nsMenuPopupFrame* popupFrame = GetMenuPopupFrame(GetFrame()); + nsMenuPopupFrame* popupFrame = GetPopupFrame(); if (!popupFrame) { // We can always hide popups without frames. return false; @@ -1660,10 +1656,10 @@ bool nsWindow::WaylandPopupIsAnchored() { } bool nsWindow::IsWidgetOverflowWindow() { - if (this->GetFrame() && this->GetFrame()->GetContent()->GetID()) { - nsCString nodeId; - this->GetFrame()->GetContent()->GetID()->ToUTF8String(nodeId); - return nodeId.Equals("widget-overflow"); + if (auto* frame = GetPopupFrame()) { + if (nsAtom* id = frame->GetContent()->GetID()) { + return id->Equals(u"widget-overflow"_ns); + } } return false; } @@ -1760,7 +1756,7 @@ bool nsWindow::WaylandPopupConfigure() { } // Don't track popups without frame - nsMenuPopupFrame* popupFrame = GetMenuPopupFrame(GetFrame()); + nsMenuPopupFrame* popupFrame = GetPopupFrame(); if (!popupFrame) { return false; } @@ -1839,7 +1835,7 @@ bool nsWindow::IsInPopupHierarchy() { void nsWindow::AddWindowToPopupHierarchy() { LOG("nsWindow::AddWindowToPopupHierarchy\n"); - if (!GetFrame()) { + if (!GetPopupFrame()) { LOG(" Window without frame cannot be added as popup!\n"); return; } @@ -2038,7 +2034,7 @@ void nsWindow::WaylandPopupPropagateChangesToLayout(bool aMove, bool aResize) { if (aResize) { LOG(" needSizeUpdate\n"); - if (nsMenuPopupFrame* popupFrame = GetMenuPopupFrame(GetFrame())) { + if (nsMenuPopupFrame* popupFrame = GetPopupFrame()) { RefPtr<PresShell> presShell = popupFrame->PresShell(); presShell->FrameNeedsReflow(popupFrame, IntrinsicDirty::None, NS_FRAME_IS_DIRTY); @@ -2171,7 +2167,7 @@ static GdkGravity PopupAlignmentToGdkGravity(int8_t aAlignment) { } bool nsWindow::IsPopupDirectionRTL() { - nsMenuPopupFrame* popupFrame = GetMenuPopupFrame(GetFrame()); + nsMenuPopupFrame* popupFrame = GetPopupFrame(); return popupFrame && popupFrame->IsDirectionRTL(); } @@ -2483,7 +2479,7 @@ const nsWindow::WaylandPopupMoveToRectParams nsWindow::WaylandPopupGetPositionFromLayout() { LOG("nsWindow::WaylandPopupGetPositionFromLayout\n"); - nsMenuPopupFrame* popupFrame = GetMenuPopupFrame(GetFrame()); + nsMenuPopupFrame* popupFrame = GetPopupFrame(); const bool isTopContextMenu = mPopupContextMenu && !mPopupAnchored; const bool isRTL = popupFrame->IsDirectionRTL(); @@ -2630,7 +2626,7 @@ bool nsWindow::WaylandPopupCheckAndGetAnchor(GdkRectangle* aPopupAnchor, LOG("nsWindow::WaylandPopupCheckAndGetAnchor"); GdkWindow* gdkWindow = GetToplevelGdkWindow(); - nsMenuPopupFrame* popupFrame = GetMenuPopupFrame(GetFrame()); + nsMenuPopupFrame* popupFrame = GetPopupFrame(); if (!gdkWindow || !popupFrame) { LOG(" can't use move-to-rect due missing gdkWindow or popupFrame"); return false; @@ -9735,14 +9731,6 @@ static nsIFrame* FindTitlebarFrame(nsIFrame* aFrame) { return nullptr; } -nsIFrame* nsWindow::GetFrame() const { - nsView* view = nsView::GetViewFor(this); - if (!view) { - return nullptr; - } - return view->GetFrame(); -} - void nsWindow::UpdateMozWindowActive() { // Update activation state for the :-moz-window-inactive pseudoclass. // Normally, this follows focus; we override it here to follow @@ -10034,7 +10022,7 @@ void nsWindow::SetDragSource(GdkDragContext* aSourceDragContext) { mSourceDragContext = aSourceDragContext; if (IsPopup() && (widget::GdkIsWaylandDisplay() || widget::IsXWaylandProtocol())) { - if (auto* menuPopupFrame = GetMenuPopupFrame(GetFrame())) { + if (auto* menuPopupFrame = GetPopupFrame()) { menuPopupFrame->SetIsDragSource(!!aSourceDragContext); } } diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h @@ -341,7 +341,6 @@ class nsWindow final : public nsBaseWidget { GdkWindow* GetGdkWindow() const { return mGdkWindow; }; GdkWindow* GetToplevelGdkWindow() const; GtkWidget* GetGtkWidget() const { return mShell; } - nsIFrame* GetFrame() const; nsWindow* GetEffectiveParent(); bool IsDestroyed() const { return mIsDestroyed; } bool IsPopup() const; diff --git a/widget/nsBaseWidget.cpp b/widget/nsBaseWidget.cpp @@ -74,6 +74,7 @@ #include "nsIScreenManager.h" #include "nsISimpleEnumerator.h" #include "nsIWidgetListener.h" +#include "nsMenuPopupFrame.h" #include "nsRefPtrHashtable.h" #include "nsServiceManagerUtils.h" #include "nsWidgetsCID.h" @@ -446,6 +447,22 @@ void nsIWidget::RemoveAllChildren() { } } +nsIFrame* nsIWidget::GetFrame() const { + if (nsView* view = nsView::GetViewFor(this)) { + return view->GetFrame(); + } + return nullptr; +} + +nsMenuPopupFrame* nsIWidget::GetPopupFrame() const { + if (mWindowType != WindowType::Popup) { + return nullptr; + } + auto* frame = GetFrame(); + MOZ_ASSERT_IF(frame, frame->IsMenuPopupFrame()); + return do_QueryFrame(frame); +} + void nsBaseWidget::DynamicToolbarOffsetChanged( mozilla::ScreenIntCoord aOffset) { if (mCompositorBridgeChild) { diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h @@ -48,7 +48,7 @@ class nsIBidiKeyboard; class nsIRollupListener; class nsIContent; -class ViewWrapper; +class nsMenuPopupFrame; class nsIRunnable; namespace mozilla { @@ -2038,6 +2038,11 @@ class nsIWidget : public nsISupports { static already_AddRefed<nsIBidiKeyboard> CreateBidiKeyboard(); + // If this is a popup, returns the associated frame if any. + nsMenuPopupFrame* GetPopupFrame() const; + // Returns the frame currently associated to this widget. + nsIFrame* GetFrame() const; + /** * Like GetDefaultScale, but taking into account only the system settings * and ignoring Gecko preferences. diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp @@ -80,6 +80,7 @@ #include "mozilla/widget/WinEventObserver.h" #include "mozilla/widget/WinMessages.h" #include "nsLookAndFeel.h" +#include "nsMenuPopupFrame.h" #include "nsWindow.h" #include "nsWindowTaskbarConcealer.h" #include "nsAppRunner.h" @@ -7209,20 +7210,14 @@ a11y::LocalAccessible* nsWindow::GetAccessible() { } // In case of popup window return a popup accessible. - nsView* view = nsView::GetViewFor(this); - if (view) { - nsIFrame* frame = view->GetFrame(); - if (frame && nsLayoutUtils::IsPopup(frame)) { - nsAccessibilityService* accService = GetOrCreateAccService(); - if (accService) { - a11y::DocAccessible* docAcc = - GetAccService()->GetDocAccessible(frame->PresShell()); - if (docAcc) { - NS_LOG_WMGETOBJECT( - this, mWnd, - docAcc->GetAccessibleOrDescendant(frame->GetContent())); - return docAcc->GetAccessibleOrDescendant(frame->GetContent()); - } + if (auto* frame = GetPopupFrame()) { + if (nsAccessibilityService* accService = GetOrCreateAccService()) { + a11y::DocAccessible* docAcc = + accService->GetDocAccessible(frame->PresShell()); + if (docAcc) { + NS_LOG_WMGETOBJECT( + this, mWnd, docAcc->GetAccessibleOrDescendant(frame->GetContent())); + return docAcc->GetAccessibleOrDescendant(frame->GetContent()); } } }