Bug 1142437 - Better deal with delayed state change notifications from APZ. r=botond
authorKartikaya Gupta <kgupta@mozilla.com>
Thu, 19 Mar 2015 06:54:34 -0400
changeset 234426 2e62677019c784cafcac81ae904800951c2b619e
parent 234425 83c5d1c58506ab886d898b1b649d64d2eaad5a80
child 234427 dd58b992baf89898ec73f4a36b22e6e6502373cc
push id57132
push userkgupta@mozilla.com
push dateThu, 19 Mar 2015 10:54:50 +0000
treeherdermozilla-inbound@2e62677019c7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbotond
bugs1142437
milestone39.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 1142437 - Better deal with delayed state change notifications from APZ. r=botond
gfx/layers/apz/util/APZEventState.cpp
gfx/layers/apz/util/ActiveElementManager.cpp
gfx/layers/apz/util/ActiveElementManager.h
--- a/gfx/layers/apz/util/APZEventState.cpp
+++ b/gfx/layers/apz/util/APZEventState.cpp
@@ -277,17 +277,17 @@ APZEventState::ProcessTouchEvent(const W
 
   case NS_TOUCH_END:
     if (isTouchPrevented) {
       mTouchEndCancelled = true;
       mEndTouchIsClick = false;
     }
     // fall through
   case NS_TOUCH_CANCEL:
-    mActiveElementManager->HandleTouchEnd(mEndTouchIsClick);
+    mActiveElementManager->HandleTouchEndEvent(mEndTouchIsClick);
     // fall through
   case NS_TOUCH_MOVE: {
     SendPendingTouchPreventedResponse(isTouchPrevented, aGuid);
     break;
   }
 
   default:
     NS_WARNING("Unknown touch event type");
@@ -360,16 +360,17 @@ APZEventState::ProcessAPZStateChange(con
   case APZStateChange::StartPanning:
   {
     mActiveElementManager->HandlePanStart();
     break;
   }
   case APZStateChange::EndTouch:
   {
     mEndTouchIsClick = aArg;
+    mActiveElementManager->HandleTouchEnd();
     break;
   }
   default:
     // APZStateChange has a 'sentinel' value, and the compiler complains
     // if an enumerator is not handled and there is no 'default' case.
     break;
   }
 }
--- a/gfx/layers/apz/util/ActiveElementManager.cpp
+++ b/gfx/layers/apz/util/ActiveElementManager.cpp
@@ -104,19 +104,19 @@ ActiveElementManager::HandlePanStart()
 
   // The user started to pan, so we don't want mTarget to be :active.
   // Make it not :active, and clear any pending task to make it :active.
   CancelTask();
   ResetActive();
 }
 
 void
-ActiveElementManager::HandleTouchEnd(bool aWasClick)
+ActiveElementManager::HandleTouchEndEvent(bool aWasClick)
 {
-  AEM_LOG("Touch end, aWasClick: %d\n", aWasClick);
+  AEM_LOG("Touch end event, aWasClick: %d\n", aWasClick);
 
   // If the touch was a click, make mTarget :active right away.
   // nsEventStateManager will reset the active element when processing
   // the mouse-down event generated by the click.
   CancelTask();
   if (aWasClick) {
     SetActive(mTarget);
   } else {
@@ -124,16 +124,23 @@ ActiveElementManager::HandleTouchEnd(boo
     // so we set the element active right away. Now it turns out the
     // action was not a click so we need to reset the active element.
     ResetActive();
   }
 
   ResetTouchBlockState();
 }
 
+void
+ActiveElementManager::HandleTouchEnd()
+{
+  AEM_LOG("Touch end, clearing pan state\n");
+  mCanBePanSet = false;
+}
+
 bool
 ActiveElementManager::ActiveElementUsesStyle() const
 {
   return mActiveElementUsesStyle;
 }
 
 static nsPresContext*
 GetPresContextFor(nsIContent* aContent)
--- a/gfx/layers/apz/util/ActiveElementManager.h
+++ b/gfx/layers/apz/util/ActiveElementManager.h
@@ -28,36 +28,42 @@ class ActiveElementManager {
   ~ActiveElementManager();
 public:
   NS_INLINE_DECL_REFCOUNTING(ActiveElementManager)
 
   ActiveElementManager();
 
   /**
    * Specify the target of a touch. Typically this should be called right
-   * before HandleTouchStart(), but we give callers the flexibility to specify
-   * the target later if they don't know it at the time they call
-   * HandleTouchStart().
+   * after HandleTouchStart(), but in cases where the APZ needs to wait for
+   * a content response the HandleTouchStart() may be delayed, in which case
+   * this function can be called first.
    * |aTarget| may be nullptr.
    */
   void SetTargetElement(dom::EventTarget* aTarget);
   /**
-   * Handle a touch-start event.
+   * Handle a touch-start state notification from APZ. This notification
+   * may be delayed until after touch listeners have responded to the APZ.
    * @param aCanBePan whether the touch can be a pan
    */
   void HandleTouchStart(bool aCanBePan);
   /**
    * Handle the start of panning.
    */
   void HandlePanStart();
   /**
    * Handle a touch-end or touch-cancel event.
    * @param aWasClick whether the touch was a click
    */
-  void HandleTouchEnd(bool aWasClick);
+  void HandleTouchEndEvent(bool aWasClick);
+  /**
+   * Handle a touch-end state notification from APZ. This notification may be
+   * delayed until after touch listeners have responded to the APZ.
+   */
+  void HandleTouchEnd();
   /**
    * @return true iff the currently active element (or one of its ancestors)
    * actually had a style for the :active pseudo-class. The currently active
    * element is the root element if no other elements are active.
    */
   bool ActiveElementUsesStyle() const;
 private:
   /**