Bug 1273137 - Add the missing main-thread target confirmation for drag blocks. r=rbarker
authorKartikaya Gupta <kgupta@mozilla.com>
Tue, 07 Jun 2016 11:07:55 -0400
changeset 300957 b72ab182dd554343b504a771e535214de53b5d6f
parent 300956 2bc047b037a0e143475e821429bf15333af7cbc7
child 300958 aa3e7ff72452492a9c739018c3a30d156db6ac5c
push id19599
push usercbook@mozilla.com
push dateWed, 08 Jun 2016 10:16:21 +0000
treeherderfx-team@81f4cc3f6f4c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrbarker
bugs1273137
milestone50.0a1
Bug 1273137 - Add the missing main-thread target confirmation for drag blocks. r=rbarker This patch also cleans up some inconsistencies in the conditions under which the main thread would respond to wheel and mouse events. With this patch applied, the main-thread notifications are only sent if the input block id is nonzero, which indicates the APZ actually processed the input event and added it to an input block. MozReview-Commit-ID: GBlgj6whi5T
dom/ipc/TabChild.cpp
gfx/layers/apz/util/APZCCallbackHelper.cpp
gfx/layers/apz/util/APZEventState.cpp
widget/nsBaseWidget.cpp
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -1904,53 +1904,63 @@ TabChild::RecvSynthMouseMoveEvent(const 
   return RecvRealMouseButtonEvent(aEvent, aGuid, aInputBlockId);
 }
 
 bool
 TabChild::RecvRealMouseButtonEvent(const WidgetMouseEvent& aEvent,
                                    const ScrollableLayerGuid& aGuid,
                                    const uint64_t& aInputBlockId)
 {
+  if (aInputBlockId) {
+    MOZ_ASSERT(aEvent.mFlags.mHandledByAPZ);
+    nsCOMPtr<nsIDocument> document(GetDocument());
+    APZCCallbackHelper::SendSetTargetAPZCNotification(
+      mPuppetWidget, document, aEvent, aGuid, aInputBlockId);
+  }
+
   nsEventStatus unused;
   InputAPZContext context(aGuid, aInputBlockId, unused);
 
   WidgetMouseEvent localEvent(aEvent);
   localEvent.mWidget = mPuppetWidget;
   APZCCallbackHelper::ApplyCallbackTransform(localEvent, aGuid,
       mPuppetWidget->GetDefaultScale());
   APZCCallbackHelper::DispatchWidgetEvent(localEvent);
 
-  if (aEvent.mFlags.mHandledByAPZ) {
+  if (aInputBlockId) {
+    MOZ_ASSERT(aEvent.mFlags.mHandledByAPZ);
     mAPZEventState->ProcessMouseEvent(aEvent, aGuid, aInputBlockId);
   }
   return true;
 }
 
 bool
 TabChild::RecvMouseWheelEvent(const WidgetWheelEvent& aEvent,
                               const ScrollableLayerGuid& aGuid,
                               const uint64_t& aInputBlockId)
 {
-  if (aEvent.mFlags.mHandledByAPZ) {
+  if (aInputBlockId) {
+    MOZ_ASSERT(aEvent.mFlags.mHandledByAPZ);
     nsCOMPtr<nsIDocument> document(GetDocument());
     APZCCallbackHelper::SendSetTargetAPZCNotification(
       mPuppetWidget, document, aEvent, aGuid, aInputBlockId);
   }
 
   WidgetWheelEvent localEvent(aEvent);
   localEvent.mWidget = mPuppetWidget;
   APZCCallbackHelper::ApplyCallbackTransform(localEvent, aGuid,
       mPuppetWidget->GetDefaultScale());
   APZCCallbackHelper::DispatchWidgetEvent(localEvent);
 
   if (localEvent.mCanTriggerSwipe) {
     SendRespondStartSwipeEvent(aInputBlockId, localEvent.TriggersSwipe());
   }
 
-  if (aEvent.mFlags.mHandledByAPZ) {
+  if (aInputBlockId) {
+    MOZ_ASSERT(aEvent.mFlags.mHandledByAPZ);
     mAPZEventState->ProcessWheelEvent(localEvent, aGuid, aInputBlockId);
   }
   return true;
 }
 
 bool
 TabChild::RecvMouseScrollTestEvent(const uint64_t& aLayersId,
                                    const FrameMetrics::ViewID& aScrollId, const nsString& aEvent)
--- a/gfx/layers/apz/util/APZCCallbackHelper.cpp
+++ b/gfx/layers/apz/util/APZCCallbackHelper.cpp
@@ -757,16 +757,19 @@ APZCCallbackHelper::SendSetTargetAPZCNot
       if (const WidgetTouchEvent* touchEvent = aEvent.AsTouchEvent()) {
         for (size_t i = 0; i < touchEvent->mTouches.Length(); i++) {
           waitForRefresh |= PrepareForSetTargetAPZCNotification(aWidget, aGuid,
               rootFrame, touchEvent->mTouches[i]->mRefPoint, &targets);
         }
       } else if (const WidgetWheelEvent* wheelEvent = aEvent.AsWheelEvent()) {
         waitForRefresh = PrepareForSetTargetAPZCNotification(aWidget, aGuid,
             rootFrame, wheelEvent->mRefPoint, &targets);
+      } else if (const WidgetMouseEvent* mouseEvent = aEvent.AsMouseEvent()) {
+        waitForRefresh = PrepareForSetTargetAPZCNotification(aWidget, aGuid,
+            rootFrame, mouseEvent->mRefPoint, &targets);
       }
       // TODO: Do other types of events need to be handled?
 
       if (!targets.IsEmpty()) {
         SendSetTargetAPZCNotificationHelper(
           aWidget,
           shell,
           aInputBlockId,
--- a/gfx/layers/apz/util/APZEventState.cpp
+++ b/gfx/layers/apz/util/APZEventState.cpp
@@ -354,18 +354,21 @@ APZEventState::ProcessWheelEvent(const W
   mContentReceivedInputBlockCallback(aGuid, aInputBlockId, defaultPrevented);
 }
 
 void
 APZEventState::ProcessMouseEvent(const WidgetMouseEvent& aEvent,
                                  const ScrollableLayerGuid& aGuid,
                                  uint64_t aInputBlockId)
 {
-  // If we get here and the input block has not been confirmed then
-  // no scrollbar reacted to the event thus APZC should ignore this block.
+  // If we get here and the drag block has not been confirmed by the code in
+  // nsSliderFrame, then no scrollbar reacted to the event thus APZC will
+  // ignore this drag block. We can send defaultPrevented as either true or
+  // false, it doesn't matter, because APZ won't have the scrollbar metrics
+  // anyway, and will know to drop the block.
   bool defaultPrevented = false;
   mContentReceivedInputBlockCallback(aGuid, aInputBlockId, defaultPrevented);
 }
 
 void
 APZEventState::ProcessAPZStateChange(const nsCOMPtr<nsIDocument>& aDocument,
                                      ViewID aViewId,
                                      APZStateChange aChange,
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -1097,25 +1097,27 @@ nsBaseWidget::ProcessUntransformedAPZEve
               mSetAllowedTouchBehaviorCallback);
         }
         APZCCallbackHelper::SendSetTargetAPZCNotification(this, GetDocument(),
             *(original->AsTouchEvent()), aGuid, aInputBlockId);
       }
       mAPZEventState->ProcessTouchEvent(*touchEvent, aGuid, aInputBlockId,
           aApzResponse, status);
     } else if (WidgetWheelEvent* wheelEvent = aEvent->AsWheelEvent()) {
-      if (wheelEvent->mFlags.mHandledByAPZ) {
-        APZCCallbackHelper::SendSetTargetAPZCNotification(this, GetDocument(),
-            *(original->AsWheelEvent()), aGuid, aInputBlockId);
-        if (wheelEvent->mCanTriggerSwipe) {
-          ReportSwipeStarted(aInputBlockId, wheelEvent->TriggersSwipe());
-        }
-        mAPZEventState->ProcessWheelEvent(*wheelEvent, aGuid, aInputBlockId);
+      MOZ_ASSERT(wheelEvent->mFlags.mHandledByAPZ);
+      APZCCallbackHelper::SendSetTargetAPZCNotification(this, GetDocument(),
+          *(original->AsWheelEvent()), aGuid, aInputBlockId);
+      if (wheelEvent->mCanTriggerSwipe) {
+        ReportSwipeStarted(aInputBlockId, wheelEvent->TriggersSwipe());
       }
+      mAPZEventState->ProcessWheelEvent(*wheelEvent, aGuid, aInputBlockId);
     } else if (WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent()) {
+      MOZ_ASSERT(mouseEvent->mFlags.mHandledByAPZ);
+      APZCCallbackHelper::SendSetTargetAPZCNotification(this, GetDocument(),
+          *(original->AsMouseEvent()), aGuid, aInputBlockId);
       mAPZEventState->ProcessMouseEvent(*mouseEvent, aGuid, aInputBlockId);
     }
   }
 
   return status;
 }
 
 class DispatchWheelEventOnMainThread : public Runnable