Bug 1234049 - Ensure we always invalidate new PresShells that are created for an inactive DocShell upon reactivating them. r=smaug
authorGeorge Wright <george@mozilla.com>
Wed, 13 Jan 2016 17:00:15 -0500
changeset 322131 51a497ce4ca0baf2db0404b6978a47b5cc6809fc
parent 322130 ce2807f90fcb5b9eb81b999fc3c4296950f1df1b
child 322132 4ab387eaa48bd267c605cd3746089da79b91dbdd
push id9530
push userdmitchell@mozilla.com
push dateFri, 15 Jan 2016 19:42:24 +0000
reviewerssmaug
bugs1234049
milestone46.0a1
Bug 1234049 - Ensure we always invalidate new PresShells that are created for an inactive DocShell upon reactivating them. r=smaug
layout/base/nsPresShell.cpp
layout/base/nsPresShell.h
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -740,16 +740,17 @@ PresShell::PresShell()
   mReflowCountMgr->SetPresContext(mPresContext);
   mReflowCountMgr->SetPresShell(this);
 #endif
   mLoadBegin = TimeStamp::Now();
 
   mSelectionFlags = nsISelectionDisplay::DISPLAY_TEXT | nsISelectionDisplay::DISPLAY_IMAGES;
   mIsThemeSupportDisabled = false;
   mIsActive = true;
+  mIsHidden = false;
   // FIXME/bug 735029: find a better solution to this problem
 #if defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_ANDROID_APZ)
   // The java pan/zoom code uses this to mean approximately "request a
   // reset of pan/zoom state" which doesn't necessarily correspond
   // with the first paint of content.
   mIsFirstPaint = false;
 #else
   mIsFirstPaint = true;
@@ -10398,16 +10399,20 @@ void PresShell::QueryIsActive()
       }
     }
   }
 
   nsCOMPtr<nsIDocShell> docshell(do_QueryInterface(container));
   if (docshell) {
     bool isActive;
     nsresult rv = docshell->GetIsActive(&isActive);
+    // Even though in theory the docshell here could be "Inactive and
+    // Foreground", thus implying aIsHidden=false for SetIsActive(),
+    // this is a newly created PresShell so we'd like to invalidate anyway
+    // upon being made active to ensure that the contents get painted.
     if (NS_SUCCEEDED(rv))
       SetIsActive(isActive);
   }
 }
 
 // Helper for propagating mIsActive changes to external resources
 static bool
 SetExternalResourceIsActive(nsIDocument* aDocument, void* aClosure)
@@ -10435,16 +10440,21 @@ SetPluginIsActive(nsISupports* aSupports
 }
 
 nsresult
 PresShell::SetIsActive(bool aIsActive, bool aIsHidden)
 {
   NS_PRECONDITION(mDocument, "should only be called with a document");
 
   mIsActive = aIsActive;
+
+  // Keep track of whether we've called TabChild::MakeHidden() or not.
+  // This can still be true even if aIsHidden is false.
+  mIsHidden |= aIsHidden;
+
   nsPresContext* presContext = GetPresContext();
   if (presContext &&
       presContext->RefreshDriver()->PresContext() == presContext) {
     presContext->RefreshDriver()->SetThrottled(!mIsActive);
   }
 
   // Propagate state-change to my resource documents' PresShells
   mDocument->EnumerateExternalResources(SetExternalResourceIsActive,
@@ -10474,20 +10484,24 @@ PresShell::SetIsActive(bool aIsActive, b
   // is problematic when those layers uselessly hold on to precious
   // resources like directly texturable memory.
   //
   // PresShell::SetIsActive() is the first C++ entry point at which we
   // (i) know that our parent process wants our content to be hidden;
   // and (ii) has easy access to the TabChild.  So we use this
   // notification to signal the TabChild to drop its layer tree and
   // stop trying to repaint.
-  if (aIsHidden) {
+  if (mIsHidden) {
     if (TabChild* tab = TabChild::GetFrom(this)) {
       if (aIsActive) {
         tab->MakeVisible();
+        // The only time we should set this to false is when
+        // TabChild::MakeVisible() is called.
+        mIsHidden = false;
+
         if (!mIsZombie) {
           if (nsIFrame* root = mFrameConstructor->GetRootFrame()) {
             FrameLayerBuilder::InvalidateAllLayersForFrame(
               nsLayoutUtils::GetDisplayRootFrame(root));
             root->SchedulePaint();
           }
         }
       } else {
--- a/layout/base/nsPresShell.h
+++ b/layout/base/nsPresShell.h
@@ -489,16 +489,18 @@ protected:
   }
 
 
   void SetRenderingState(const RenderingState& aState);
 
   friend class nsPresShellEventCB;
 
   bool mCaretEnabled;
+
+  bool mIsHidden;
 #ifdef DEBUG
   nsStyleSet* CloneStyleSet(nsStyleSet* aSet);
   bool VerifyIncrementalReflow();
   bool mInVerifyReflow;
   void ShowEventTargetDebug();
 #endif
 
   void RecordStyleSheetChange(mozilla::CSSStyleSheet* aStyleSheet);