commit ae9c84efa945f0fbbae86b5a91a36772cbe3e646
parent 3b9fd7d6dbf2f8bc0a428887a0611a66ebcbf0bd
Author: Emilio Cobos Álvarez <emilio@crisal.io>
Date: Fri, 14 Nov 2025 02:11:08 +0000
Bug 1999867 - Remove some more nsView usage outside of view. r=tnikkel,layout-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D272383
Diffstat:
14 files changed, 161 insertions(+), 355 deletions(-)
diff --git a/gfx/layers/ipc/SharedSurfacesChild.cpp b/gfx/layers/ipc/SharedSurfacesChild.cpp
@@ -480,8 +480,7 @@ void SharedSurfacesAnimation::HoldSurfaceForRecycling(
// in nsIWidget that does this for us but there isn't yet.
static nsIWidgetListener* GetPaintWidgetListener(nsIWidget* aWidget) {
if (auto* attached = aWidget->GetAttachedWidgetListener()) {
- if (attached->GetView() &&
- attached->GetView()->IsPrimaryFramePaintSuppressed()) {
+ if (attached->IsPaintSuppressed()) {
if (auto* previouslyAttached =
aWidget->GetPreviouslyAttachedWidgetListener()) {
return previouslyAttached;
diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp
@@ -5748,97 +5748,6 @@ static nsMenuPopupFrame* FindPopupFrame(nsPresContext* aRootPresContext,
nsLayoutUtils::GetPopupFrameForPointFlags::OnlyReturnFramesWithWidgets);
}
-/*
- * This finds the first view with a frame that contains the given point in a
- * postorder traversal of the view tree, assuming that the point is not in a
- * floating view. It assumes that only floating views extend outside the bounds
- * of their parents.
- *
- * This methods should only be called if FindPopupFrame returns null.
- *
- * aPt is relative aRelativeToView with the viewport type
- * aRelativeToViewportType. aRelativeToView will always have a frame. If aView
- * has a frame then aRelativeToView will be aView. (The reason aRelativeToView
- * and aView are separate is because we need to traverse into views without
- * frames (ie the inner view of a subdocument frame) but we can only easily
- * transform between views using TransformPoint which takes frames.)
- */
-static nsView* FindViewContaining(nsView* aRelativeToView,
- ViewportType aRelativeToViewportType,
- nsView* aView, nsPoint aPt) {
- MOZ_ASSERT(aRelativeToView->GetFrame());
-
- nsIFrame* frame = aView->GetFrame();
- if (frame) {
- if (!frame->PresShell()->IsActive() ||
- !frame->IsVisibleConsideringAncestors(
- nsIFrame::VISIBILITY_CROSS_CHROME_CONTENT_BOUNDARY)) {
- return nullptr;
- }
-
- // We start out in visual coords and then if we cross the zoom boundary we
- // become in layout coords. The zoom boundary always occurs in a document
- // with IsRootContentDocumentCrossProcess. The root view of such a document
- // is outside the zoom boundary and any child view must be inside the zoom
- // boundary because we only create views for certain kinds of frames and
- // none of them can be between the root frame and the zoom boundary.
- bool crossingZoomBoundary = false;
- if (aRelativeToViewportType == ViewportType::Visual) {
- if (nsIFrame* f = aRelativeToView->GetFrame();
- f && f->PresContext()->IsRootContentDocumentCrossProcess()) {
- crossingZoomBoundary = true;
- }
- }
-
- ViewportType nextRelativeToViewportType = aRelativeToViewportType;
- if (crossingZoomBoundary) {
- nextRelativeToViewportType = ViewportType::Layout;
- }
-
- nsLayoutUtils::TransformResult result = nsLayoutUtils::TransformPoint(
- RelativeTo{aRelativeToView->GetFrame(), aRelativeToViewportType},
- RelativeTo{frame, nextRelativeToViewportType}, aPt);
- if (result != nsLayoutUtils::TRANSFORM_SUCCEEDED) {
- return nullptr;
- }
-
- // Even though aPt is in visual coordinates until we cross the zoom boundary
- // it is valid to compare it to view coords (which are in layout coords)
- // because visual coords are the same as layout coords for every view
- // outside of the zoom boundary except for the root view of the root content
- // document.
- // For the root view of the root content document, its bounds don't
- // actually correspond to what is visible when we have a
- // MobileViewportManager. So we skip the hit test. This is okay because the
- // point has already been hit test: 1) if we are the root view in the
- // process then the point comes from a real mouse event so it must have been
- // over our widget, or 2) if we are the root of a subdocument then
- // hittesting against the view of the subdocument frame that contains us
- // already happened and succeeded before getting here.
- if (!crossingZoomBoundary) {
- if (!aView->GetBounds().Contains(aPt)) {
- return nullptr;
- }
- }
-
- aRelativeToView = aView;
- aRelativeToViewportType = nextRelativeToViewportType;
- }
-
- return frame ? aView : nullptr;
-}
-
-static BrowserBridgeChild* GetChildBrowser(nsView* aView) {
- if (!aView) {
- return nullptr;
- }
- nsIFrame* frame = aView->GetFrame();
- if (!frame || !frame->GetContent()) {
- return nullptr;
- }
- return BrowserBridgeChild::GetFrom(frame->GetContent());
-}
-
void PresShell::ProcessSynthMouseMoveEvent(bool aFromScroll) {
auto forgetMouseMove = MakeScopeExit([&]() {
// Must be safe to refer `this` without grabbing it with a RefPtr since this
@@ -5954,34 +5863,25 @@ void PresShell::ProcessSynthMouseOrPointerMoveEvent(
RefPtr<BrowserBridgeChild> bbc;
// We either dispatch the event to a popup, or a view.
- nsMenuPopupFrame* popupFrame = nullptr;
- if (rootView->GetFrame()) {
- popupFrame = FindPopupFrame(mPresContext, rootView->GetWidget(),
- LayoutDeviceIntPoint::FromAppUnitsToNearest(
- aPointerInfo.mLastRefPointInRootDoc, APD));
- if (popupFrame) {
- pointShell = popupFrame->PresShell();
- widget = popupFrame->GetWidget();
- widgetAPD = popupFrame->PresContext()->AppUnitsPerDevPixel();
- refpoint = aPointerInfo.mLastRefPointInRootDoc;
- DebugOnly<nsLayoutUtils::TransformResult> result =
- nsLayoutUtils::TransformPoint(
- RelativeTo{rootView->GetFrame(), ViewportType::Visual},
- RelativeTo{popupFrame, ViewportType::Layout}, refpoint);
- MOZ_ASSERT(result == nsLayoutUtils::TRANSFORM_SUCCEEDED);
- }
+ nsMenuPopupFrame* popupFrame =
+ FindPopupFrame(mPresContext, rootView->GetWidget(),
+ LayoutDeviceIntPoint::FromAppUnitsToNearest(
+ aPointerInfo.mLastRefPointInRootDoc, APD));
+ if (popupFrame) {
+ pointShell = popupFrame->PresShell();
+ widget = popupFrame->GetWidget();
+ widgetAPD = popupFrame->PresContext()->AppUnitsPerDevPixel();
+ refpoint = aPointerInfo.mLastRefPointInRootDoc;
+ DebugOnly<nsLayoutUtils::TransformResult> result =
+ nsLayoutUtils::TransformPoint(
+ RelativeTo{rootView->GetFrame(), ViewportType::Visual},
+ RelativeTo{popupFrame, ViewportType::Layout}, refpoint);
+ MOZ_ASSERT(result == nsLayoutUtils::TRANSFORM_SUCCEEDED);
}
if (!widget) {
widget = rootView->GetWidget();
widgetAPD = APD;
- nsView* pointView = rootView;
- if (rootView->GetFrame()) {
- pointView = FindViewContaining(rootView, ViewportType::Visual, rootView,
- aPointerInfo.mLastRefPointInRootDoc);
- }
- // pointView can be null in situations related to mouse capture
- pointShell = (pointView ? pointView : rootView)->GetPresShell();
- bbc = GetChildBrowser(pointView);
+ pointShell = this;
refpoint = aPointerInfo.mLastRefPointInRootDoc;
}
NS_ASSERTION(widget, "view should have a widget here");
@@ -6018,41 +5918,20 @@ void PresShell::ProcessSynthMouseOrPointerMoveEvent(
event.pointerId = aPointerId;
event.mModifiers = PresShell::GetCurrentModifiers();
- if (bbc) {
- // If we have a BrowserBridgeChild, we're going to be dispatching this
- // mouse event into an OOP iframe of the current document if and only if
- // we're synthesizing a mouse move.
- // FIXME: We may need to dispatch ePointerMove in the OOP iframe too.
- // However, it may require to change the active pointer state in both this
- // process and the OOP iframe process too. Therefore, we will fire
- // ePointerMove as a preceding pointer event of the synthesized eMouseMove
- // in PointerEventHandler::DispatchPointerFromMouseOrTouch().
- if (aMoveMessage == eMouseMove) {
- event.mLayersId = bbc->GetLayersId();
- event.convertToPointer = true;
- bbc->SendDispatchSynthesizedMouseEvent(event);
- }
- return;
- }
-
- if (pointShell) {
- // Since this gets run in a refresh tick there isn't an InputAPZContext on
- // the stack from the nsIWidget. We need to simulate one with at least
- // the correct target guid, so that the correct callback transform gets
- // applied if this event goes to a child process. The input block id is set
- // to 0 because this is a synthetic event which doesn't really belong to any
- // input block. Same for the APZ response field.
- InputAPZContext apzContext(aPointerInfo.mLastTargetGuid, 0,
- nsEventStatus_eIgnore);
- AUTO_PROFILER_MARKER_DOCSHELL("DispatchSynthMouseOrPointerMove", GRAPHICS,
- pointShell->GetPresContext()->GetDocShell());
- nsEventStatus status = nsEventStatus_eIgnore;
- if (popupFrame) {
- pointShell->HandleEvent(popupFrame, &event, false, &status);
- } else {
- RefPtr<nsViewManager> viewManager = rootView->GetViewManager();
- viewManager->DispatchEvent(&event, rootView, &status);
- }
+ MOZ_ASSERT(pointShell);
+ // Since this gets run in a refresh tick there isn't an InputAPZContext on
+ // the stack from the nsIWidget. We need to simulate one with at least
+ // the correct target guid, so that the correct callback transform gets
+ // applied if this event goes to a child process. The input block id is set
+ // to 0 because this is a synthetic event which doesn't really belong to any
+ // input block. Same for the APZ response field.
+ InputAPZContext apzContext(aPointerInfo.mLastTargetGuid, 0,
+ nsEventStatus_eIgnore);
+ AUTO_PROFILER_MARKER_DOCSHELL("DispatchSynthMouseOrPointerMove", GRAPHICS,
+ pointShell->GetPresContext()->GetDocShell());
+ nsEventStatus status = nsEventStatus_eIgnore;
+ if (auto* eventFrame = popupFrame ? popupFrame : GetRootFrame()) {
+ pointShell->HandleEvent(eventFrame, &event, false, &status);
}
}
@@ -12328,6 +12207,13 @@ void PresShell::ResetVisualViewportSize() {
}
}
+void PresShell::SetNeedsWindowPropertiesSync() {
+ mNeedsWindowPropertiesSync = true;
+ if (mViewManager) {
+ mViewManager->PostPendingUpdate();
+ }
+}
+
bool PresShell::SetVisualViewportOffset(const nsPoint& aScrollOffset,
const nsPoint& aPrevLayoutScrollPos) {
nsPoint newOffset = aScrollOffset;
@@ -12603,15 +12489,12 @@ PresShell::WindowSizeConstraints PresShell::GetWindowSizeConstraints() {
return {minSize, maxSize};
}
-void PresShell::SyncWindowProperties(bool aSync) {
- if (XRE_IsContentProcess()) {
+void PresShell::SyncWindowProperties() {
+ if (!mNeedsWindowPropertiesSync || XRE_IsContentProcess()) {
return;
}
- nsView* view = mViewManager->GetRootView();
- if (!view || !view->HasWidget()) {
- return;
- }
+ mNeedsWindowPropertiesSync = false;
RefPtr pc = mPresContext;
if (!pc) {
@@ -12623,11 +12506,6 @@ void PresShell::SyncWindowProperties(bool aSync) {
return;
}
- if (!aSync) {
- view->SetNeedsWindowPropertiesSync();
- return;
- }
-
nsIFrame* rootFrame = FrameConstructor()->GetRootElementStyleFrame();
if (!rootFrame) {
return;
diff --git a/layout/base/PresShell.h b/layout/base/PresShell.h
@@ -1276,7 +1276,7 @@ class PresShell final : public nsStubDocumentObserver,
return mNeedLayoutFlush || mNeedStyleFlush;
}
- void SyncWindowProperties(bool aSync);
+ void SyncWindowProperties();
struct WindowSizeConstraints {
nsSize mMinSize;
nsSize mMaxSize;
@@ -1550,6 +1550,7 @@ class PresShell final : public nsStubDocumentObserver,
void SetVisualViewportSize(nscoord aWidth, nscoord aHeight);
void ResetVisualViewportSize();
bool IsVisualViewportSizeSet() { return mVisualViewportSizeSet; }
+ void SetNeedsWindowPropertiesSync();
nsSize GetVisualViewportSize() {
NS_ASSERTION(mVisualViewportSizeSet,
"asking for visual viewport size when its not set?");
@@ -3390,6 +3391,9 @@ class PresShell final : public nsStubDocumentObserver,
// True if a style flush might not be a no-op
bool mNeedStyleFlush : 1;
+ // Whether we need to sync window properties.
+ bool mNeedsWindowPropertiesSync : 1 = false;
+
// True if there are throttled animations that would be processed when
// performing a flush with mFlushAnimations == true.
bool mNeedThrottledAnimationFlush : 1;
diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp
@@ -2670,7 +2670,7 @@ ViewportFrame* nsCSSFrameConstructor::ConstructRootFrame() {
// Bind the viewport frame to the root view
if (nsView* rootView = mPresShell->GetViewManager()->GetRootView()) {
viewportFrame->SetView(rootView);
- rootView->SetNeedsWindowPropertiesSync();
+ mPresShell->SetNeedsWindowPropertiesSync();
}
// Make it an absolute container for fixed-pos elements
diff --git a/layout/generic/nsIFrame.cpp b/layout/generic/nsIFrame.cpp
@@ -1260,7 +1260,7 @@ void nsIFrame::DidSetComputedStyle(ComputedStyle* aOldComputedStyle) {
const bool isRootElementStyle = Style()->IsRootElementStyle();
if (isRootElementStyle) {
- PresShell()->SyncWindowProperties(/* aSync = */ false);
+ PresShell()->SetNeedsWindowPropertiesSync();
}
const nsStyleImageLayers* oldLayers =
diff --git a/view/nsView.cpp b/view/nsView.cpp
@@ -33,8 +33,7 @@ nsView::nsView(nsViewManager* aViewManager)
: mViewManager(aViewManager),
mFrame(nullptr),
mWidgetIsTopLevel(false),
- mForcedRepaint(false),
- mNeedsWindowPropertiesSync(false) {
+ mForcedRepaint(false) {
MOZ_COUNT_CTOR(nsView);
// Views should be transparent by default. Not being transparent is
@@ -108,20 +107,6 @@ void nsView::DestroyWidget() {
}
}
-nsView* nsView::GetViewFor(const nsIWidget* aWidget) {
- MOZ_ASSERT(aWidget, "null widget ptr");
-
- nsIWidgetListener* listener = aWidget->GetWidgetListener();
- if (listener) {
- if (nsView* view = listener->GetView()) {
- return view;
- }
- }
-
- listener = aWidget->GetAttachedWidgetListener();
- return listener ? listener->GetView() : nullptr;
-}
-
void nsView::Destroy() {
this->~nsView();
mozWritePoison(this, sizeof(*this));
@@ -193,19 +178,12 @@ LayoutDeviceIntRect nsView::CalcWidgetBounds(
void nsView::SetDimensions(const nsRect& aRect) { mDimBounds = aRect; }
-void nsView::SetNeedsWindowPropertiesSync() {
- mNeedsWindowPropertiesSync = true;
- if (mViewManager) {
- mViewManager->PostPendingUpdate();
- }
-}
-
// Attach to a top level widget and start receiving mirrored events.
void nsView::AttachToTopLevelWidget(nsIWidget* aWidget) {
MOZ_ASSERT(aWidget, "null widget ptr");
#ifdef DEBUG
nsIWidgetListener* parentListener = aWidget->GetWidgetListener();
- MOZ_ASSERT(!parentListener || !parentListener->GetView(),
+ MOZ_ASSERT(!parentListener || parentListener->GetAppWindow(),
"Expect a top level widget");
MOZ_ASSERT(!parentListener || !parentListener->GetAsMenuPopupFrame(),
"Expect a top level widget");
@@ -278,9 +256,9 @@ void nsView::AttachWidgetEventHandler(nsIWidget* aWidget) {
}
void nsView::DetachWidgetEventHandler(nsIWidget* aWidget) {
- NS_ASSERTION(!aWidget->GetWidgetListener() ||
- aWidget->GetWidgetListener()->GetView() == this,
- "Wrong view");
+ NS_ASSERTION(
+ !aWidget->GetWidgetListener() || aWidget->GetWidgetListener() == this,
+ "Wrong view");
aWidget->SetWidgetListener(nullptr);
}
@@ -418,11 +396,9 @@ void nsView::WillPaintWindow(nsIWidget* aWidget) {
}
bool nsView::PaintWindow(nsIWidget* aWidget, LayoutDeviceIntRegion aRegion) {
- NS_ASSERTION(this == nsView::GetViewFor(aWidget), "wrong view for widget?");
-
RefPtr<nsViewManager> vm = mViewManager;
- bool result = vm->PaintWindow(aWidget, aRegion);
- return result;
+ vm->Refresh(this, aRegion);
+ return true;
}
void nsView::DidPaintWindow() {
@@ -461,19 +437,23 @@ nsEventStatus nsView::HandleEvent(WidgetGUIEvent* aEvent,
MOZ_ASSERT(aEvent->mWidget, "null widget ptr");
nsEventStatus result = nsEventStatus_eIgnore;
- nsView* view;
- if (aUseAttachedEvents) {
- nsIWidgetListener* listener = aEvent->mWidget->GetAttachedWidgetListener();
- view = listener ? listener->GetView() : nullptr;
- } else {
- view = GetViewFor(aEvent->mWidget);
+ auto* listener = [&]() -> nsIWidgetListener* {
+ if (!aUseAttachedEvents) {
+ if (auto* l = aEvent->mWidget->GetWidgetListener()) {
+ return l;
+ }
+ }
+ return aEvent->mWidget->GetAttachedWidgetListener();
+ }();
+ if (NS_WARN_IF(!listener)) {
+ return result;
}
-
- if (view) {
- RefPtr<nsViewManager> vm = view->GetViewManager();
- vm->DispatchEvent(aEvent, view, &result);
+ nsViewManager::MaybeUpdateLastUserEventTime(aEvent);
+ if (RefPtr<PresShell> ps = listener->GetPresShell()) {
+ if (nsIFrame* root = ps->GetRootFrame()) {
+ ps->HandleEvent(root, aEvent, false, &result);
+ }
}
-
return result;
}
@@ -507,7 +487,7 @@ void nsView::SafeAreaInsetsChanged(
});
}
-bool nsView::IsPrimaryFramePaintSuppressed() {
+bool nsView::IsPrimaryFramePaintSuppressed() const {
return StaticPrefs::layout_show_previous_page() && mFrame &&
mFrame->PresShell()->IsPaintingSuppressed();
}
diff --git a/view/nsView.h b/view/nsView.h
@@ -126,13 +126,6 @@ class nsView final : public nsIWidgetListener {
nsViewManager* GetViewManager() const { return mViewManager; }
/**
- * Find the view for the given widget, if there is one.
- * @return the view the widget belongs to, or null if the widget doesn't
- * belong to any view.
- */
- static nsView* GetViewFor(const nsIWidget* aWidget);
-
- /**
* Destroy the view.
*
* The view destroys its child views, and destroys and releases its
@@ -255,6 +248,9 @@ class nsView final : public nsIWidgetListener {
// nsIWidgetListener
mozilla::PresShell* GetPresShell() override;
nsView* GetView() override { return this; }
+ bool IsPaintSuppressed() const override {
+ return IsPrimaryFramePaintSuppressed();
+ }
bool WindowResized(nsIWidget* aWidget, int32_t aWidth,
int32_t aHeight) override;
#ifdef MOZ_WIDGET_ANDROID
@@ -280,7 +276,7 @@ class nsView final : public nsIWidgetListener {
virtual ~nsView();
- bool IsPrimaryFramePaintSuppressed();
+ bool IsPrimaryFramePaintSuppressed() const;
private:
explicit nsView(nsViewManager* = nullptr);
@@ -314,7 +310,6 @@ class nsView final : public nsIWidgetListener {
nsRect mDimBounds;
bool mWidgetIsTopLevel;
bool mForcedRepaint;
- bool mNeedsWindowPropertiesSync;
bool mIsDirty = false;
};
diff --git a/view/nsViewManager.cpp b/view/nsViewManager.cpp
@@ -241,18 +241,10 @@ void nsViewManager::ProcessPendingUpdatesForView(nsView* aView,
RefPtr<PresShell> rootPresShell = mPresShell;
AutoTArray<nsCOMPtr<nsIWidget>, 1> widgets;
aView->GetViewManager()->ProcessPendingUpdatesRecurse(aView, widgets);
- for (uint32_t i = 0; i < widgets.Length(); ++i) {
- nsView* view = nsView::GetViewFor(widgets[i]);
- if (!view) {
- continue;
- }
- if (view->mNeedsWindowPropertiesSync) {
- view->mNeedsWindowPropertiesSync = false;
- if (nsViewManager* vm = view->GetViewManager()) {
- if (PresShell* presShell = vm->GetPresShell()) {
- presShell->SyncWindowProperties(/* aSync */ true);
- }
- }
+ for (nsIWidget* widget : widgets) {
+ MOZ_ASSERT(widget->IsTopLevelWidget());
+ if (RefPtr ps = widget->GetPresShell()) {
+ ps->SyncWindowProperties();
}
}
if (rootPresShell->GetViewManager() != this) {
@@ -262,9 +254,9 @@ void nsViewManager::ProcessPendingUpdatesForView(nsView* aView,
nsAutoScriptBlocker scriptBlocker;
SetPainting(true);
for (nsIWidget* widget : widgets) {
- if (nsView* view = nsView::GetViewFor(widget)) {
- RefPtr<nsViewManager> viewManager = view->GetViewManager();
- viewManager->ProcessPendingUpdatesPaint(MOZ_KnownLive(widget));
+ if (RefPtr ps = widget->GetPresShell()) {
+ RefPtr vm = ps->GetViewManager();
+ vm->ProcessPendingUpdatesPaint(MOZ_KnownLive(widget));
}
}
SetPainting(false);
@@ -283,47 +275,46 @@ void nsViewManager::ProcessPendingUpdatesRecurse(
}
void nsViewManager::ProcessPendingUpdatesPaint(nsIWidget* aWidget) {
- if (aWidget->NeedsPaint()) {
- // If an ancestor widget was hidden and then shown, we could
- // have a delayed resize to handle.
- if (mDelayedResize != nsSize(NSCOORD_NONE, NSCOORD_NONE) && mPresShell &&
- mPresShell->IsVisible()) {
- FlushDelayedResize();
- }
- nsView* view = nsView::GetViewFor(aWidget);
- if (!view) {
- NS_ERROR("FlushDelayedResize destroyed the nsView?");
- return;
- }
+ if (!aWidget->NeedsPaint()) {
+ return;
+ }
+ // If an ancestor widget was hidden and then shown, we could
+ // have a delayed resize to handle.
+ if (mDelayedResize != nsSize(NSCOORD_NONE, NSCOORD_NONE) && mPresShell &&
+ mPresShell->IsVisible()) {
+ FlushDelayedResize();
+ }
+
+ if (!mRootView || !mPresShell) {
+ NS_ERROR("FlushDelayedResize destroyed the view?");
+ return;
+ }
- nsIWidgetListener* previousListener =
- aWidget->GetPreviouslyAttachedWidgetListener();
+ nsIWidgetListener* previousListener =
+ aWidget->GetPreviouslyAttachedWidgetListener();
- if (previousListener && previousListener != view &&
- view->IsPrimaryFramePaintSuppressed()) {
- return;
- }
+ if (previousListener && previousListener != mRootView &&
+ mRootView->IsPrimaryFramePaintSuppressed()) {
+ return;
+ }
- if (RefPtr<PresShell> presShell = mPresShell) {
+ RefPtr ps = mPresShell;
#ifdef MOZ_DUMP_PAINTING
- if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
- printf_stderr(
- "---- PAINT START ----PresShell(%p), nsView(%p), nsIWidget(%p)\n",
- presShell.get(), view, aWidget);
- }
+ if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
+ printf_stderr("---- PAINT START ----PresShell(%p), nsIWidget(%p)\n",
+ ps.get(), aWidget);
+ }
#endif
- presShell->PaintAndRequestComposite(
- view->GetFrame(), aWidget->GetWindowRenderer(), PaintFlags::None);
- view->SetForcedRepaint(false);
+ ps->PaintAndRequestComposite(ps->GetRootFrame(), aWidget->GetWindowRenderer(),
+ PaintFlags::None);
+ mRootView->SetForcedRepaint(false);
#ifdef MOZ_DUMP_PAINTING
- if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
- printf_stderr("---- PAINT END ----\n");
- }
-#endif
- }
+ if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
+ printf_stderr("---- PAINT END ----\n");
}
+#endif
}
void nsViewManager::PostPendingUpdate() {
@@ -336,35 +327,19 @@ void nsViewManager::PostPendingUpdate() {
}
void nsViewManager::WillPaintWindow(nsIWidget* aWidget) {
- if (aWidget) {
- nsView* view = nsView::GetViewFor(aWidget);
- WindowRenderer* renderer = aWidget->GetWindowRenderer();
- if (view &&
- (view->ForcedRepaint() || !renderer->NeedsWidgetInvalidation())) {
- ProcessPendingUpdates();
- // Re-get the view pointer here since the ProcessPendingUpdates might have
- // destroyed it during CallWillPaintOnObservers.
- view = nsView::GetViewFor(aWidget);
- if (view) {
- view->SetForcedRepaint(false);
- }
- }
- }
-}
-
-bool nsViewManager::PaintWindow(nsIWidget* aWidget,
- const LayoutDeviceIntRegion& aRegion) {
if (!aWidget) {
- return false;
+ return;
}
- // Get the view pointer here since NS_WILL_PAINT might have
- // destroyed it during CallWillPaintOnObservers (bug 378273).
- nsView* view = nsView::GetViewFor(aWidget);
- if (view && !aRegion.IsEmpty()) {
- Refresh(view, aRegion);
+ WindowRenderer* renderer = aWidget->GetWindowRenderer();
+ if (mRootView &&
+ (mRootView->ForcedRepaint() || !renderer->NeedsWidgetInvalidation())) {
+ ProcessPendingUpdates();
+ // Re-get the view pointer here since the ProcessPendingUpdates might have
+ // destroyed it during CallWillPaintOnObservers.
+ if (mRootView) {
+ mRootView->SetForcedRepaint(false);
+ }
}
-
- return true;
}
void nsViewManager::DidPaintWindow() {
@@ -373,10 +348,7 @@ void nsViewManager::DidPaintWindow() {
}
}
-void nsViewManager::DispatchEvent(WidgetGUIEvent* aEvent, nsView* aView,
- nsEventStatus* aStatus) {
- AUTO_PROFILER_LABEL("nsViewManager::DispatchEvent", OTHER);
-
+void nsViewManager::MaybeUpdateLastUserEventTime(WidgetGUIEvent* aEvent) {
WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
if ((mouseEvent &&
// Ignore mouse events that we synthesize.
@@ -389,20 +361,6 @@ void nsViewManager::DispatchEvent(WidgetGUIEvent* aEvent, nsView* aView,
aEvent->HasKeyEventMessage() || aEvent->HasIMEEventMessage()) {
gLastUserEventTime = PR_IntervalToMicroseconds(PR_IntervalNow());
}
-
- // Find the view whose coordinates system we're in.
- // If the view has no frame, look for a view that does.
- if (nsIFrame* frame = aView->GetFrame()) {
- // Hold a refcount to the presshell. The continued existence of the
- // presshell will delay deletion of this view hierarchy should the event
- // want to cause its destruction in, say, some JavaScript event handler.
- if (RefPtr<PresShell> presShell = aView->GetViewManager()->GetPresShell()) {
- presShell->HandleEvent(frame, aEvent, false, aStatus);
- return;
- }
- }
-
- *aStatus = nsEventStatus_eIgnore;
}
void nsViewManager::ResizeView(nsView* aView, const nsRect& aRect) {
diff --git a/view/nsViewManager.h b/view/nsViewManager.h
@@ -82,18 +82,6 @@ class nsViewManager final {
void FlushDelayedResize();
/**
- * Called to dispatch an event to the appropriate view. Often called
- * as a result of receiving a mouse or keyboard event from the widget
- * event system.
- * @param aEvent event to dispatch
- * @param aViewTarget dispatch the event to this view
- * @param aStatus event handling status
- */
- MOZ_CAN_RUN_SCRIPT
- void DispatchEvent(mozilla::WidgetGUIEvent* aEvent, nsView* aViewTarget,
- nsEventStatus* aStatus);
-
- /**
* Resize a view. In addition to setting the width and height, you can
* set the x and y of its bounds relative to its position. Negative x and y
* will let the view extend above and to the left of the (0,0) point in its
@@ -130,6 +118,7 @@ class nsViewManager final {
* saves the time of the last user event.
*/
static uint32_t GetLastUserEventTime() { return gLastUserEventTime; }
+ static void MaybeUpdateLastUserEventTime(mozilla::WidgetGUIEvent*);
/**
* Flush the accumulated dirty region to the widget and update widget
@@ -142,6 +131,10 @@ class nsViewManager final {
*/
MOZ_CAN_RUN_SCRIPT void UpdateWidgetGeometry();
+ // Call this when you need to let the viewmanager know that it now has
+ // pending updates.
+ void PostPendingUpdate();
+
private:
static uint32_t gLastUserEventTime;
@@ -182,10 +175,6 @@ class nsViewManager final {
bool PaintWindow(nsIWidget* aWidget, const LayoutDeviceIntRegion& aRegion);
MOZ_CAN_RUN_SCRIPT void DidPaintWindow();
- // Call this when you need to let the viewmanager know that it now has
- // pending updates.
- void PostPendingUpdate();
-
mozilla::PresShell* mPresShell;
// The size for a resize that we delayed until the root view becomes
diff --git a/widget/PuppetWidget.cpp b/widget/PuppetWidget.cpp
@@ -995,7 +995,7 @@ nsIWidgetListener* PuppetWidget::GetCurrentWidgetListener() {
return mAttachedWidgetListener;
}
- if (mAttachedWidgetListener->GetView()->IsPrimaryFramePaintSuppressed()) {
+ if (mAttachedWidgetListener->IsPaintSuppressed()) {
return mPreviouslyAttachedWidgetListener;
}
diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp
@@ -569,7 +569,9 @@ void nsWindow::DispatchActivateEvent(void) {
DispatchActivateEventAccessible();
#endif // ACCESSIBILITY
- if (mWidgetListener) mWidgetListener->WindowActivated();
+ if (mWidgetListener) {
+ mWidgetListener->WindowActivated();
+ }
}
void nsWindow::DispatchDeactivateEvent() {
@@ -5721,10 +5723,8 @@ void nsWindow::OnWindowStateEvent(GtkWidget* aWidget,
void nsWindow::OnDPIChanged() {
// Update menu's font size etc.
// This affects style / layout because it affects system font sizes.
- if (mWidgetListener) {
- if (PresShell* presShell = mWidgetListener->GetPresShell()) {
- presShell->BackingScaleFactorChanged();
- }
+ if (PresShell* presShell = GetPresShell()) {
+ presShell->BackingScaleFactorChanged();
}
NotifyAPZOfDPIChange();
}
@@ -5800,10 +5800,8 @@ void nsWindow::RefreshScale(bool aRefreshScreen, bool aForceRefresh) {
RecomputeBounds(/* MayChangeCsdMargin */ true, /* ScaleChanged*/ true);
- if (mWidgetListener) {
- if (PresShell* presShell = mWidgetListener->GetPresShell()) {
- presShell->BackingScaleFactorChanged();
- }
+ if (PresShell* presShell = GetPresShell()) {
+ presShell->BackingScaleFactorChanged();
}
if (mCursor.IsCustom()) {
@@ -9920,11 +9918,7 @@ void nsWindow::UpdateMozWindowActive() {
void nsWindow::ForceTitlebarRedraw() {
MOZ_ASSERT(mDrawInTitlebar, "We should not redraw invisible titlebar.");
-
- if (!mWidgetListener) {
- return;
- }
- PresShell* ps = mWidgetListener->GetPresShell();
+ PresShell* ps = GetPresShell();
if (!ps) {
return;
}
@@ -9932,7 +9926,6 @@ void nsWindow::ForceTitlebarRedraw() {
if (!frame) {
return;
}
-
frame = FindTitlebarFrame(frame);
if (frame) {
nsIContent* content = frame->GetContent();
diff --git a/widget/nsIWidget.cpp b/widget/nsIWidget.cpp
@@ -491,8 +491,8 @@ nsIFrame* nsIWidget::GetFrame() const {
if (auto* popup = GetPopupFrame()) {
return popup;
}
- if (nsView* view = nsView::GetViewFor(this)) {
- return view->GetFrame();
+ if (auto* ps = GetPresShell()) {
+ return ps->GetRootFrame();
}
return nullptr;
}
@@ -2017,6 +2017,20 @@ nsIWidget::TextEventDispatcher* nsIWidget::GetTextEventDispatcher() {
return mTextEventDispatcher;
}
+PresShell* nsIWidget::GetPresShell() const {
+ if (mWidgetListener) {
+ if (auto* ps = mWidgetListener->GetPresShell()) {
+ return ps;
+ }
+ }
+ if (mAttachedWidgetListener) {
+ if (auto* ps = mAttachedWidgetListener->GetPresShell()) {
+ return ps;
+ }
+ }
+ return nullptr;
+}
+
void* nsIWidget::GetPseudoIMEContext() {
TextEventDispatcher* dispatcher = GetTextEventDispatcher();
if (!dispatcher) {
diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h
@@ -2269,6 +2269,9 @@ class nsIWidget : public nsSupportsWeakReference {
*/
TextEventDispatcher* GetTextEventDispatcher();
+ // Gets the pres shell this widget is managed by.
+ mozilla::PresShell* GetPresShell() const;
+
/**
* GetNativeTextEventDispatcherListener() returns a
* TextEventDispatcherListener instance which is used when the widget
diff --git a/widget/nsIWidgetListener.h b/widget/nsIWidgetListener.h
@@ -34,25 +34,15 @@ enum nsSizeMode {
nsSizeMode_Invalid
};
-/**
- * different types of (top-level) window z-level positioning
- */
-enum nsWindowZ {
- nsWindowZTop = 0, // on top
- nsWindowZBottom, // on bottom
- nsWindowZRelative // just below some specified widget
-};
-
class nsIWidgetListener {
public:
/**
* If this listener is for an nsIAppWindow, return it. If this is null, then
- * this is likely a listener for a view, which can be determined using
- * GetView. If both methods return null, this will be an nsWebBrowser.
+ * this is likely a listener for a popup or a pres shell.
*/
virtual nsIAppWindow* GetAppWindow() { return nullptr; }
- /** If this listener is for an nsView, return it. */
+ /** If this listener is for a view, return it. */
virtual nsView* GetView() { return nullptr; }
/** If this listener is for an nsMenuPopupFrame, return it. */
@@ -163,6 +153,9 @@ class nsIWidgetListener {
*/
virtual bool ShouldNotBeVisible() { return false; }
+ /** Returns true if painting should be suppressed for this listener */
+ virtual bool IsPaintSuppressed() const { return false; }
+
/** Handle an event. */
virtual nsEventStatus HandleEvent(mozilla::WidgetGUIEvent* aEvent,
bool aUseAttachedEvents) {