Bug 1412195 - Track all changes to TabChild active state (r=bevis)
authorBill McCloskey <billm@mozilla.com>
Fri, 27 Oct 2017 16:39:57 -0700
changeset 435958 8d8519a2b6dce407afe3cacd86e30592bcf7fe1b
parent 435957 af490228394eeebd48dcc2c326a9d2bbe369d59a
child 435963 ea2100fcee92171fbb7f5b9a83dda324ed448d48
push id117
push userfmarier@mozilla.com
push dateTue, 28 Nov 2017 20:17:16 +0000
reviewersbevis
bugs1412195
milestone58.0a1
Bug 1412195 - Track all changes to TabChild active state (r=bevis) MozReview-Commit-ID: 7nQjquaM4sQ
docshell/base/nsDocShell.cpp
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -6330,16 +6330,20 @@ nsDocShell::SetIsActive(bool aIsActive)
   // We disallow setting active on chrome docshells.
   if (mItemType == nsIDocShellTreeItem::typeChrome) {
     return NS_ERROR_INVALID_ARG;
   }
 
   // Keep track ourselves.
   mIsActive = aIsActive;
 
+  if (TabChild* tc = TabChild::GetFrom(this)) {
+    tc->OnDocShellActivated(aIsActive);
+  }
+
   // Clear prerender flag if necessary.
   if (mIsPrerendered && aIsActive) {
     MOZ_ASSERT(mPrerenderGlobalHistory.get());
     mIsPrerendered = false;
     nsCOMPtr<IHistory> history = services::GetHistoryService();
     nsresult rv = NS_OK;
     if (history) {
       rv = mPrerenderGlobalHistory->ApplyChanges(history);
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -2664,16 +2664,33 @@ TabChild::RemovePendingDocShellBlocker()
   if (!mPendingDocShellBlockers && mPendingDocShellReceivedMessage) {
     mPendingDocShellReceivedMessage = false;
     InternalSetDocShellIsActive(mPendingDocShellIsActive,
                                 mPendingDocShellPreserveLayers);
   }
 }
 
 void
+TabChild::OnDocShellActivated(bool aIsActive)
+{
+  if (aIsActive) {
+    if (!sActiveTabs) {
+      sActiveTabs = new nsTHashtable<nsPtrHashKey<TabChild>>();
+    }
+    sActiveTabs->PutEntry(this);
+  } else {
+    if (sActiveTabs) {
+      sActiveTabs->RemoveEntry(this);
+      // We don't delete sActiveTabs here when it's empty since that
+      // could cause a lot of churn. Instead, we wait until ~TabChild.
+    }
+  }
+}
+
+void
 TabChild::InternalSetDocShellIsActive(bool aIsActive, bool aPreserveLayers)
 {
   auto clearForcePaint = MakeScopeExit([&] {
     // We might force a paint, or we might already have painted and this is a
     // no-op. In either case, once we exit this scope, we need to alert the
     // ProcessHangMonitor that we've finished responding to what might have
     // been a request to force paint. This is so that the BackgroundHangMonitor
     // for force painting can be made to wait again.
@@ -2708,29 +2725,16 @@ TabChild::InternalSetDocShellIsActive(bo
         return;
       }
     }
 
     docShell->SetIsActive(aIsActive);
   }
 
   if (aIsActive) {
-    if (!sActiveTabs) {
-      sActiveTabs = new nsTHashtable<nsPtrHashKey<TabChild>>();
-    }
-    sActiveTabs->PutEntry(this);
-  } else {
-    if (sActiveTabs) {
-      sActiveTabs->RemoveEntry(this);
-      // We don't delete sActiveTabs here when it's empty since that
-      // could cause a lot of churn. Instead, we wait until ~TabChild.
-    }
-  }
-
-  if (aIsActive) {
     MakeVisible();
 
     if (!docShell) {
       return;
     }
 
     // We don't use TabChildBase::GetPresShell() here because that would create
     // a content viewer if one doesn't exist yet. Creating a content viewer can
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -575,16 +575,18 @@ public:
   /**
    * Signal to this TabChild that it should be made visible:
    * activated widget, retained layer tree, etc.  (Respectively,
    * made not visible.)
    */
   void MakeVisible();
   void MakeHidden();
 
+  void OnDocShellActivated(bool aIsActive);
+
   nsIContentChild* Manager() const { return mManager; }
 
   static inline TabChild*
   GetFrom(nsIDocShell* aDocShell)
   {
     if (!aDocShell) {
       return nullptr;
     }