commit 9e968791de7c2f4e698f3615837a5cface05f81e
parent cf235be01ad475c5c2eb606abf0d944aa53451cc
Author: agoloman <agoloman@mozilla.com>
Date: Tue, 25 Nov 2025 16:43:43 +0200
Revert "Bug 2000626 - Clean up more now dead view / viewmanager code. r=jwatt" for causing build bustages @rules.mk.
This reverts commit 469bf3153dd42d48b021ebc92e345e074af714dc.
Diffstat:
4 files changed, 94 insertions(+), 9 deletions(-)
diff --git a/view/nsView.cpp b/view/nsView.cpp
@@ -27,8 +27,14 @@
using namespace mozilla;
using namespace mozilla::widget;
-nsView::nsView(nsViewManager* aViewManager) : mViewManager(aViewManager) {
+nsView::nsView(nsViewManager* aViewManager)
+ : mViewManager(aViewManager), mForcedRepaint(false) {
MOZ_COUNT_CTOR(nsView);
+
+ // Views should be transparent by default. Not being transparent is
+ // a promise that the view will paint all its pixels opaquely. Views
+ // should make this promise explicitly by calling
+ // SetViewContentTransparency.
}
nsView::~nsView() {
@@ -48,10 +54,27 @@ nsView::~nsView() {
}
// Destroy and release the widget
- DetachWidget();
+ DestroyWidget();
}
-void nsView::DetachWidget() {
+class DestroyWidgetRunnable : public Runnable {
+ public:
+ NS_DECL_NSIRUNNABLE
+
+ explicit DestroyWidgetRunnable(nsIWidget* aWidget)
+ : mozilla::Runnable("DestroyWidgetRunnable"), mWidget(aWidget) {}
+
+ private:
+ nsCOMPtr<nsIWidget> mWidget;
+};
+
+NS_IMETHODIMP DestroyWidgetRunnable::Run() {
+ mWidget->Destroy();
+ mWidget = nullptr;
+ return NS_OK;
+}
+
+void nsView::DestroyWidget() {
if (mWindow) {
// If we are not attached to a base window, we're going to tear down our
// widget here. However, if we're attached to somebody elses widget, we
@@ -137,7 +160,14 @@ PresShell* nsView::GetPresShell() { return GetViewManager()->GetPresShell(); }
bool nsView::WindowResized(nsIWidget* aWidget, int32_t aWidth,
int32_t aHeight) {
- PresShell* ps = GetPresShell();
+ // The root view may not be set if this is the resize associated with
+ // window creation
+ SetForcedRepaint(true);
+ if (this != mViewManager->GetRootView()) {
+ return false;
+ }
+
+ PresShell* ps = mViewManager->GetPresShell();
if (!ps) {
return false;
}
@@ -247,7 +277,7 @@ void nsView::DidPaintWindow() {
void nsView::DidCompositeWindow(mozilla::layers::TransactionId aTransactionId,
const TimeStamp& aCompositeStart,
const TimeStamp& aCompositeEnd) {
- PresShell* presShell = GetPresShell();
+ PresShell* presShell = mViewManager->GetPresShell();
if (!presShell) {
return;
}
@@ -279,7 +309,7 @@ nsEventStatus nsView::HandleEvent(WidgetGUIEvent* aEvent) {
void nsView::SafeAreaInsetsChanged(
const LayoutDeviceIntMargin& aSafeAreaInsets) {
- PresShell* presShell = GetPresShell();
+ PresShell* presShell = mViewManager->GetPresShell();
if (!presShell) {
return;
}
@@ -311,7 +341,7 @@ bool nsView::IsPrimaryFramePaintSuppressed() const {
void nsView::CallOnAllRemoteChildren(
const std::function<CallState(dom::BrowserParent*)>& aCallback) {
- PresShell* presShell = GetPresShell();
+ PresShell* presShell = mViewManager->GetPresShell();
if (!presShell) {
return;
}
diff --git a/view/nsView.h b/view/nsView.h
@@ -142,8 +142,12 @@ class nsView final : public nsIWidgetListener {
*/
nsSize GetSize() const { return mSize; }
- // Stops listening to mWidget and clears it.
- void DetachWidget();
+ /**
+ * Destroys the associated widget for this view. If this method is
+ * not called explicitly, the widget when be destroyed when its
+ * view gets destroyed.
+ */
+ void DestroyWidget();
/**
* Attach/detach a top level widget from this view. When attached, the view
@@ -173,6 +177,10 @@ class nsView final : public nsIWidgetListener {
*/
bool HasWidget() const { return mWindow != nullptr; }
+ void SetForcedRepaint(bool aForceRepaint) { mForcedRepaint = aForceRepaint; }
+
+ void SetNeedsWindowPropertiesSync();
+
#ifdef DEBUG
/**
* Output debug info to FILE
@@ -218,6 +226,8 @@ class nsView final : public nsIWidgetListener {
private:
explicit nsView(nsViewManager* = nullptr);
+ bool ForcedRepaint() { return mForcedRepaint; }
+
void SetSize(const nsSize& aSize) { mSize = aSize; }
void CallOnAllRemoteChildren(
@@ -228,6 +238,7 @@ class nsView final : public nsIWidgetListener {
nsCOMPtr<nsIWidget> mWindow;
nsCOMPtr<nsIWidget> mPreviousWindow;
nsSize mSize;
+ bool mForcedRepaint;
bool mIsDirty = false;
};
diff --git a/view/nsViewManager.cpp b/view/nsViewManager.cpp
@@ -150,6 +150,25 @@ void nsViewManager::FlushDelayedResize() {
}
}
+nsViewManager* nsViewManager::RootViewManager() const {
+ const auto* cur = this;
+ while (auto* parent = cur->GetParentViewManager()) {
+ cur = parent;
+ }
+ return const_cast<nsViewManager*>(cur);
+}
+
+nsViewManager* nsViewManager::GetParentViewManager() const {
+ if (!mPresShell) {
+ return nullptr;
+ }
+ auto* pc = mPresShell->GetPresContext();
+ if (auto* parent = pc->GetParentPresContext()) {
+ return parent->PresShell()->GetViewManager();
+ }
+ return nullptr;
+}
+
void nsViewManager::PaintWindow(nsIWidget* aWidget) {
RefPtr ps = mPresShell;
if (!ps) {
diff --git a/view/nsViewManager.h b/view/nsViewManager.h
@@ -37,6 +37,14 @@ class nsViewManager final {
nsViewManager();
/**
+ * Initialize the ViewManager
+ * Note: this instance does not hold a reference to the presshell
+ * because it holds a reference to this instance.
+ * @result The result of the initialization, NS_OK if no errors
+ */
+ nsresult Init();
+
+ /**
* Create an ordinary view
* @param aSize initial size for view
* XXX We should eliminate this parameter; you can set the bounds
@@ -100,12 +108,29 @@ class nsViewManager final {
static uint32_t GetLastUserEventTime() { return gLastUserEventTime; }
static void MaybeUpdateLastUserEventTime(mozilla::WidgetGUIEvent*);
+ /**
+ * Flush the accumulated dirty region to the widget and update widget
+ * geometry.
+ */
+ MOZ_CAN_RUN_SCRIPT void ProcessPendingUpdates();
+
private:
static uint32_t gLastUserEventTime;
+ /**
+ * Call WillPaint() on all view observers under this vm root.
+ */
+ MOZ_CAN_RUN_SCRIPT_BOUNDARY void CallWillPaintOnObservers();
+ static void CollectVMsForWillPaint(nsView* aView, nsViewManager* aParentVM,
+ nsTArray<RefPtr<nsViewManager>>& aVMs);
+
MOZ_CAN_RUN_SCRIPT_BOUNDARY void DoSetWindowDimensions(const nsSize&);
bool ShouldDelayResize() const;
+ nsViewManager* RootViewManager() const;
+ nsViewManager* GetParentViewManager() const;
+ bool IsRootVM() const { return !GetParentViewManager(); }
+
MOZ_CAN_RUN_SCRIPT void WillPaintWindow(nsIWidget* aWidget);
MOZ_CAN_RUN_SCRIPT void PaintWindow(nsIWidget* aWidget);
MOZ_CAN_RUN_SCRIPT void DidPaintWindow();