Bug 1273137 - Add the missing main-thread target confirmation for drag blocks. r?rbarker draft
authorKartikaya Gupta <kgupta@mozilla.com>
Tue, 07 Jun 2016 11:07:55 -0400
changeset 376278 693e5679bf7ffde13717cad291f1f2465e4e6477
parent 376277 fa64dcbe31a79412be6fd086a0fa764f792481e1
child 523100 88f10cd0205895c882a7b467d5cdcb081be9506d
push id20521
push userkgupta@mozilla.com
push dateTue, 07 Jun 2016 15:13:57 +0000
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