Bug 1137009 - Do not persist xul window attributes when in fullscreen. r=enndeakin, a=lizzard
authorXidorn Quan <quanxunzhen@gmail.com>
Thu, 22 Oct 2015 11:08:35 +1100
changeset 298248 e74341409f6531e556fee406d6a0fe2e8b66ef1c
parent 298247 6ace689f3a6c82350837d8cfd87dfa8a50960141
child 298249 e964dd4baeb916d0db9e1409ea2575df35868810
push id962
push userjlund@mozilla.com
push dateFri, 04 Dec 2015 23:28:54 +0000
treeherdermozilla-release@23a2d286e80f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersenndeakin, lizzard
bugs1137009
milestone43.0a2
Bug 1137009 - Do not persist xul window attributes when in fullscreen. r=enndeakin, a=lizzard
dom/xul/XULDocument.cpp
xpfe/appshell/nsXULWindow.cpp
--- a/dom/xul/XULDocument.cpp
+++ b/dom/xul/XULDocument.cpp
@@ -915,16 +915,33 @@ XULDocument::AttributeWillChange(nsIDocu
     // See if we need to update our ref map.
     if (aAttribute == nsGkAtoms::ref) {
         // Might not need this, but be safe for now.
         nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
         RemoveElementFromRefMap(aElement);
     }
 }
 
+static bool
+ShouldPersistAttribute(Element* aElement, nsIAtom* aAttribute)
+{
+    if (aElement->IsXULElement(nsGkAtoms::window)) {
+        // The following attributes of xul:window should be handled in
+        // nsXULWindow::SavePersistentAttributes instead of here.
+        if (aAttribute == nsGkAtoms::screenX ||
+            aAttribute == nsGkAtoms::screenY ||
+            aAttribute == nsGkAtoms::width ||
+            aAttribute == nsGkAtoms::height ||
+            aAttribute == nsGkAtoms::sizemode) {
+            return false;
+        }
+    }
+    return true;
+}
+
 void
 XULDocument::AttributeChanged(nsIDocument* aDocument,
                               Element* aElement, int32_t aNameSpaceID,
                               nsIAtom* aAttribute, int32_t aModType,
                               const nsAttrValue* aOldValue)
 {
     NS_ASSERTION(aDocument == this, "unexpected doc");
 
@@ -994,24 +1011,24 @@ XULDocument::AttributeChanged(nsIDocumen
     bool listener, resolved;
     CheckBroadcasterHookup(aElement, &listener, &resolved);
 
     // See if there is anything we need to persist in the localstore.
     //
     // XXX Namespace handling broken :-(
     nsAutoString persist;
     aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::persist, persist);
-    if (!persist.IsEmpty()) {
+    // Persistence of attributes of xul:window is handled in nsXULWindow.
+    if (ShouldPersistAttribute(aElement, aAttribute) && !persist.IsEmpty() &&
         // XXXldb This should check that it's a token, not just a substring.
-        if (persist.Find(nsDependentAtomString(aAttribute)) >= 0) {
-            nsContentUtils::AddScriptRunner(NS_NewRunnableMethodWithArgs
-              <nsIContent*, int32_t, nsIAtom*>
-              (this, &XULDocument::DoPersist, aElement, kNameSpaceID_None,
-               aAttribute));
-        }
+        persist.Find(nsDependentAtomString(aAttribute)) >= 0) {
+        nsContentUtils::AddScriptRunner(NS_NewRunnableMethodWithArgs
+            <nsIContent*, int32_t, nsIAtom*>
+            (this, &XULDocument::DoPersist, aElement, kNameSpaceID_None,
+            aAttribute));
     }
 }
 
 void
 XULDocument::ContentAppended(nsIDocument* aDocument,
                              nsIContent* aContainer,
                              nsIContent* aFirstNewContent,
                              int32_t aNewIndexInContainer)
--- a/xpfe/appshell/nsXULWindow.cpp
+++ b/xpfe/appshell/nsXULWindow.cpp
@@ -1442,16 +1442,21 @@ NS_IMETHODIMP nsXULWindow::SavePersisten
 
   nsAutoString   persistString;
   docShellElement->GetAttribute(PERSIST_ATTRIBUTE, persistString);
   if (persistString.IsEmpty()) { // quick check which sometimes helps
     mPersistentAttributesDirty = 0;
     return NS_OK;
   }
 
+  bool isFullscreen = false;
+  if (nsPIDOMWindow* domWindow = mDocShell->GetWindow()) {
+    domWindow->GetFullScreen(&isFullscreen);
+  }
+
   // get our size, position and mode to persist
   nsIntRect rect;
   bool gotRestoredBounds = NS_SUCCEEDED(mWindow->GetRestoredBounds(rect));
 
   CSSToLayoutDeviceScale scale = mWindow->GetDefaultScale();
 
   // make our position relative to our parent, if any
   nsCOMPtr<nsIBaseWindow> parent(do_QueryReferent(mParentWindow));
@@ -1469,75 +1474,83 @@ NS_IMETHODIMP nsXULWindow::SavePersisten
   nsCOMPtr<nsIDOMXULDocument> ownerXULDoc;
 
   // fetch docShellElement's ID and XUL owner document
   ownerXULDoc = do_QueryInterface(docShellElement->OwnerDoc());
   if (docShellElement->IsXULElement()) {
     docShellElement->GetId(windowElementId);
   }
 
+  bool shouldPersist = !isFullscreen && ownerXULDoc;
   ErrorResult rv;
   // (only for size elements which are persisted)
   if ((mPersistentAttributesDirty & PAD_POSITION) && gotRestoredBounds) {
     if (persistString.Find("screenX") >= 0) {
       PR_snprintf(sizeBuf, sizeof(sizeBuf), "%d", NSToIntRound(rect.x / scale.scale));
       sizeString.AssignWithConversion(sizeBuf);
       docShellElement->SetAttribute(SCREENX_ATTRIBUTE, sizeString, rv);
-      if (ownerXULDoc) // force persistence in case the value didn't change
+      if (shouldPersist) {
         ownerXULDoc->Persist(windowElementId, SCREENX_ATTRIBUTE);
+      }
     }
     if (persistString.Find("screenY") >= 0) {
       PR_snprintf(sizeBuf, sizeof(sizeBuf), "%d", NSToIntRound(rect.y / scale.scale));
       sizeString.AssignWithConversion(sizeBuf);
       docShellElement->SetAttribute(SCREENY_ATTRIBUTE, sizeString, rv);
-      if (ownerXULDoc)
+      if (shouldPersist) {
         ownerXULDoc->Persist(windowElementId, SCREENY_ATTRIBUTE);
+      }
     }
   }
 
   if ((mPersistentAttributesDirty & PAD_SIZE) && gotRestoredBounds) {
     if (persistString.Find("width") >= 0) {
       PR_snprintf(sizeBuf, sizeof(sizeBuf), "%d", NSToIntRound(rect.width / scale.scale));
       sizeString.AssignWithConversion(sizeBuf);
       docShellElement->SetAttribute(WIDTH_ATTRIBUTE, sizeString, rv);
-      if (ownerXULDoc)
+      if (shouldPersist) {
         ownerXULDoc->Persist(windowElementId, WIDTH_ATTRIBUTE);
+      }
     }
     if (persistString.Find("height") >= 0) {
       PR_snprintf(sizeBuf, sizeof(sizeBuf), "%d", NSToIntRound(rect.height / scale.scale));
       sizeString.AssignWithConversion(sizeBuf);
       docShellElement->SetAttribute(HEIGHT_ATTRIBUTE, sizeString, rv);
-      if (ownerXULDoc)
+      if (shouldPersist) {
         ownerXULDoc->Persist(windowElementId, HEIGHT_ATTRIBUTE);
+      }
     }
   }
 
   if (mPersistentAttributesDirty & PAD_MISC) {
     nsSizeMode sizeMode = mWindow->SizeMode();
 
     if (sizeMode != nsSizeMode_Minimized) {
       if (sizeMode == nsSizeMode_Maximized)
         sizeString.Assign(SIZEMODE_MAXIMIZED);
       else if (sizeMode == nsSizeMode_Fullscreen)
         sizeString.Assign(SIZEMODE_FULLSCREEN);
       else
         sizeString.Assign(SIZEMODE_NORMAL);
       docShellElement->SetAttribute(MODE_ATTRIBUTE, sizeString, rv);
-      if (ownerXULDoc && persistString.Find("sizemode") >= 0)
+      if (shouldPersist && persistString.Find("sizemode") >= 0) {
         ownerXULDoc->Persist(windowElementId, MODE_ATTRIBUTE);
+      }
     }
     if (persistString.Find("zlevel") >= 0) {
       uint32_t zLevel;
       nsCOMPtr<nsIWindowMediator> mediator(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
       if (mediator) {
         mediator->GetZLevel(this, &zLevel);
         PR_snprintf(sizeBuf, sizeof(sizeBuf), "%lu", (unsigned long)zLevel);
         sizeString.AssignWithConversion(sizeBuf);
         docShellElement->SetAttribute(ZLEVEL_ATTRIBUTE, sizeString, rv);
-        ownerXULDoc->Persist(windowElementId, ZLEVEL_ATTRIBUTE);
+        if (shouldPersist) {
+          ownerXULDoc->Persist(windowElementId, ZLEVEL_ATTRIBUTE);
+        }
       }
     }
   }
 
   mPersistentAttributesDirty = 0;
   return NS_OK;
 }