Bug 1266747 P1 Track the last focus time on the nsIDocument. r=smaug
authorBen Kelly <ben@wanderview.com>
Tue, 28 Feb 2017 22:12:27 -0500
changeset 394240 e1c10d908957278706b77693db36aba785219933
parent 394239 2b4713a7a0825a515e212d9300885648a9e9e975
child 394241 f0ef771861c23b3e4219ec5cb38c8a8b630bd113
push id1468
push userasasaki@mozilla.com
push dateMon, 05 Jun 2017 19:31:07 +0000
treeherdermozilla-release@0641fc6ee9d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1266747
milestone54.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1266747 P1 Track the last focus time on the nsIDocument. r=smaug
dom/base/nsDocument.cpp
dom/base/nsFocusManager.cpp
dom/base/nsIDocument.h
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -3249,16 +3249,31 @@ nsIDocument::HasFocus(ErrorResult& rv) c
       // Yes, we are an ancestor
       return true;
     }
   }
 
   return false;
 }
 
+TimeStamp
+nsIDocument::LastFocusTime() const
+{
+  return mLastFocusTime;
+}
+
+void
+nsIDocument::SetLastFocusTime(const TimeStamp& aFocusTime)
+{
+  MOZ_DIAGNOSTIC_ASSERT(!aFocusTime.IsNull());
+  MOZ_DIAGNOSTIC_ASSERT(mLastFocusTime.IsNull() ||
+                        aFocusTime >= mLastFocusTime);
+  mLastFocusTime = aFocusTime;
+}
+
 NS_IMETHODIMP
 nsDocument::GetReferrer(nsAString& aReferrer)
 {
   nsIDocument::GetReferrer(aReferrer);
   return NS_OK;
 }
 
 void
@@ -4748,16 +4763,24 @@ nsDocument::SetScriptGlobalObject(nsIScr
 #endif
         bool allowDNSPrefetch;
         docShell->GetAllowDNSPrefetch(&allowDNSPrefetch);
         mAllowDNSPrefetch = allowDNSPrefetch;
       }
     }
 
     MaybeRescheduleAnimationFrameNotifications();
+
+    // If we are set in a window that is already focused we should remember this
+    // as the time the document gained focus.
+    bool focused = false;
+    Unused << HasFocus(&focused);
+    if (focused) {
+      SetLastFocusTime(TimeStamp::Now());
+    }
   }
 
   // Remember the pointer to our window (or lack there of), to avoid
   // having to QI every time it's asked for.
   nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(mScriptGlobalObject);
   mWindow = window;
 
   // Now that we know what our window is, we can flush the CSP errors to the
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -3606,16 +3606,27 @@ void
 nsFocusManager::SetFocusedWindowInternal(nsPIDOMWindowOuter* aWindow)
 {
   if (!PointerUnlocker::sActiveUnlocker &&
       nsContentUtils::IsInPointerLockContext(mFocusedWindow) &&
       !nsContentUtils::IsInPointerLockContext(aWindow)) {
     nsCOMPtr<nsIRunnable> runnable = new PointerUnlocker();
     NS_DispatchToCurrentThread(runnable);
   }
+
+  // Update the last focus time on any affected documents
+  if (aWindow && aWindow != mFocusedWindow) {
+    const TimeStamp now(TimeStamp::Now());
+    for (nsIDocument* doc = aWindow->GetExtantDoc();
+         doc;
+         doc = doc->GetParentDocument()) {
+      doc->SetLastFocusTime(now);
+    }
+  }
+
   mFocusedWindow = aWindow;
 }
 
 void
 nsFocusManager::MarkUncollectableForCCGeneration(uint32_t aGeneration)
 {
   if (!sInstance) {
     return;
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -2651,16 +2651,18 @@ public:
   void GetDir(nsAString& aDirection) const;
   void SetDir(const nsAString& aDirection);
   nsPIDOMWindowOuter* GetDefaultView() const
   {
     return GetWindow();
   }
   Element* GetActiveElement();
   bool HasFocus(mozilla::ErrorResult& rv) const;
+  mozilla::TimeStamp LastFocusTime() const;
+  void SetLastFocusTime(const mozilla::TimeStamp& aFocusTime);
   // Event handlers are all on nsINode already
   bool MozSyntheticDocument() const
   {
     return IsSyntheticDocument();
   }
   Element* GetCurrentScript();
   void ReleaseCapture() const;
   virtual void MozSetImageElement(const nsAString& aImageElementId,
@@ -3020,16 +3022,20 @@ protected:
   nsTArray<nsAutoPtr<nsPropertyTable> > mExtraPropertyTables;
 
   // Our cached .children collection
   nsCOMPtr<nsIHTMLCollection> mChildrenCollection;
 
   // container for per-context fonts (downloadable, SVG, etc.)
   RefPtr<mozilla::dom::FontFaceSet> mFontFaceSet;
 
+  // Last time this document or a one of its sub-documents was focused.  If
+  // focus has never occurred then mLastFocusTime.IsNull() will be true.
+  mozilla::TimeStamp mLastFocusTime;
+
   // True if BIDI is enabled.
   bool mBidiEnabled : 1;
   // True if a MathML element has ever been owned by this document.
   bool mMathMLEnabled : 1;
 
   // True if this document is the initial document for a window.  This should
   // basically be true only for documents that exist in newly-opened windows or
   // documents created to satisfy a GetDocument() on a window when there's no