Bug 1156160 - Update carets when document becomes visible. r=mtseng
☠☠ backed out by 7d0ff0aae0a0 ☠ ☠
authorTing-Yu Lin <tlin@mozilla.com>
Fri, 25 Nov 2016 17:51:40 +0800
changeset 324897 079ee7b41c3a5c33e1608c01ebaf17751f41d5f9
parent 324896 315a93b13ee0a6763e5650323943f9cc95d7c2a6
child 324898 eef68eeb10c627989f5a16624a9abd147db33271
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewersmtseng
bugs1156160
milestone53.0a1
Bug 1156160 - Update carets when document becomes visible. r=mtseng When the user switches back to a tab which has the selection highlight on the document, call UpdateCarets() to bring the carets back. MozReview-Commit-ID: LxNoNRl4FHZ
layout/base/AccessibleCaretEventHub.cpp
layout/base/AccessibleCaretEventHub.h
layout/base/AccessibleCaretManager.cpp
layout/base/AccessibleCaretManager.h
--- a/layout/base/AccessibleCaretEventHub.cpp
+++ b/layout/base/AccessibleCaretEventHub.cpp
@@ -27,17 +27,18 @@ namespace mozilla {
 #undef AC_LOG
 #define AC_LOG(message, ...)                                                   \
   AC_LOG_BASE("AccessibleCaretEventHub (%p): " message, this, ##__VA_ARGS__);
 
 #undef AC_LOGV
 #define AC_LOGV(message, ...)                                                  \
   AC_LOGV_BASE("AccessibleCaretEventHub (%p): " message, this, ##__VA_ARGS__);
 
-NS_IMPL_ISUPPORTS(AccessibleCaretEventHub, nsIReflowObserver, nsIScrollObserver,
+NS_IMPL_ISUPPORTS(AccessibleCaretEventHub,
+                  nsIDocumentActivity, nsIReflowObserver, nsIScrollObserver,
                   nsISelectionListener, nsISupportsWeakReference);
 
 // -----------------------------------------------------------------------------
 // NoActionState
 //
 class AccessibleCaretEventHub::NoActionState
   : public AccessibleCaretEventHub::State
 {
@@ -428,16 +429,22 @@ AccessibleCaretEventHub::Init()
     return;
   }
 
   docShell->AddWeakReflowObserver(this);
   docShell->AddWeakScrollObserver(this);
 
   mDocShell = static_cast<nsDocShell*>(docShell);
 
+  nsIDocument* doc = mPresShell->GetDocument();
+  if (doc) {
+    doc->RegisterActivityObserver(
+      NS_ISUPPORTS_CAST(nsIDocumentActivity*, this));
+  }
+
   if (sUseLongTapInjector) {
     mLongTapInjectorTimer = do_CreateInstance("@mozilla.org/timer;1");
   }
 
   mScrollEndInjectorTimer = do_CreateInstance("@mozilla.org/timer;1");
 
   mManager = MakeUnique<AccessibleCaretManager>(mPresShell);
 
@@ -452,16 +459,22 @@ AccessibleCaretEventHub::Terminate()
   }
 
   RefPtr<nsDocShell> docShell(mDocShell.get());
   if (docShell) {
     docShell->RemoveWeakReflowObserver(this);
     docShell->RemoveWeakScrollObserver(this);
   }
 
+  nsIDocument* doc = mPresShell->GetDocument();
+  if (doc) {
+    doc->UnregisterActivityObserver(
+      NS_ISUPPORTS_CAST(nsIDocumentActivity*, this));
+  }
+
   if (mLongTapInjectorTimer) {
     mLongTapInjectorTimer->Cancel();
   }
 
   if (mScrollEndInjectorTimer) {
     mScrollEndInjectorTimer->Cancel();
   }
 
@@ -697,16 +710,35 @@ NS_IMETHODIMP
 AccessibleCaretEventHub::ReflowInterruptible(DOMHighResTimeStamp aStart,
                                              DOMHighResTimeStamp aEnd)
 {
   // Defer the error checking to Reflow().
   return Reflow(aStart, aEnd);
 }
 
 void
+AccessibleCaretEventHub::NotifyOwnerDocumentActivityChanged()
+{
+  if (!mInitialized) {
+    return;
+  }
+
+  MOZ_ASSERT(mRefCnt.get() > 1, "Expect caller holds us as well!");
+
+  nsIDocument* doc = mPresShell->GetDocument();
+  if (!doc) {
+    return;
+  }
+
+  if (!doc->Hidden()) {
+    mManager->OnDocumentVisible();
+  }
+}
+
+void
 AccessibleCaretEventHub::AsyncPanZoomStarted()
 {
   if (!mInitialized) {
     return;
   }
 
   MOZ_ASSERT(mRefCnt.get() > 1, "Expect caller holds us as well!");
 
--- a/layout/base/AccessibleCaretEventHub.h
+++ b/layout/base/AccessibleCaretEventHub.h
@@ -6,16 +6,17 @@
 
 #ifndef AccessibleCaretEventHub_h
 #define AccessibleCaretEventHub_h
 
 #include "mozilla/EventForwards.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/WeakPtr.h"
 #include "nsCOMPtr.h"
+#include "nsIDocumentActivity.h"
 #include "nsIFrame.h"
 #include "nsIReflowObserver.h"
 #include "nsIScrollObserver.h"
 #include "nsISelectionListener.h"
 #include "nsPoint.h"
 #include "mozilla/RefPtr.h"
 #include "nsWeakReference.h"
 
@@ -55,32 +56,35 @@ class WidgetTouchEvent;
 // State transition diagram:
 // http://hg.mozilla.org/mozilla-central/raw-file/default/layout/base/doc/AccessibleCaretEventHubStates.png
 // Source code of the diagram:
 // http://hg.mozilla.org/mozilla-central/file/default/layout/base/doc/AccessibleCaretEventHubStates.dot
 //
 // Please see the wiki page for more information.
 // https://wiki.mozilla.org/AccessibleCaret
 //
-class AccessibleCaretEventHub : public nsIReflowObserver,
-                                public nsIScrollObserver,
-                                public nsISelectionListener,
-                                public nsSupportsWeakReference
+class AccessibleCaretEventHub
+  : public nsIDocumentActivity
+  , public nsIReflowObserver
+  , public nsIScrollObserver
+  , public nsISelectionListener
+  , public nsSupportsWeakReference
 {
 public:
   explicit AccessibleCaretEventHub(nsIPresShell* aPresShell);
   void Init();
   void Terminate();
 
   nsEventStatus HandleEvent(WidgetEvent* aEvent);
 
   // Call this function to notify the blur event happened.
   void NotifyBlur(bool aIsLeavingDocument);
 
   NS_DECL_ISUPPORTS
+  NS_DECL_NSIDOCUMENTACTIVITY
   NS_DECL_NSIREFLOWOBSERVER
   NS_DECL_NSISELECTIONLISTENER
 
   // Override nsIScrollObserver methods.
   virtual void ScrollPositionChanged() override;
   virtual void AsyncPanZoomStarted() override;
   virtual void AsyncPanZoomStopped() override;
 
--- a/layout/base/AccessibleCaretManager.cpp
+++ b/layout/base/AccessibleCaretManager.cpp
@@ -747,16 +747,23 @@ AccessibleCaretManager::OnKeyboardEvent(
 void
 AccessibleCaretManager::OnFrameReconstruction()
 {
   mFirstCaret->EnsureApzAware();
   mSecondCaret->EnsureApzAware();
 }
 
 void
+AccessibleCaretManager::OnDocumentVisible()
+{
+  AC_LOG("%s: UpdateCarets()", __FUNCTION__);
+  UpdateCarets();
+}
+
+void
 AccessibleCaretManager::SetLastInputSource(uint16_t aInputSource)
 {
   mLastInputSource = aInputSource;
 }
 
 Selection*
 AccessibleCaretManager::GetSelection() const
 {
--- a/layout/base/AccessibleCaretManager.h
+++ b/layout/base/AccessibleCaretManager.h
@@ -98,16 +98,20 @@ public:
                                       int16_t aReason);
   // Handle key event.
   virtual void OnKeyboardEvent();
 
   // The canvas frame holding the accessible caret anonymous content elements
   // was reconstructed, resulting in the content elements getting cloned.
   virtual void OnFrameReconstruction();
 
+  // Called by AccessibleCaretEventHub to inform us that the document
+  // becomes visible.
+  virtual void OnDocumentVisible();
+
   // Update the manager with the last input source that was observed. This
   // is used in part to determine if the carets should be shown or hidden.
   void SetLastInputSource(uint16_t aInputSource);
 
 protected:
   // This enum representing the number of AccessibleCarets on the screen.
   enum class CaretMode : uint8_t {
     // No caret on the screen.