Bug 1425573 - Introduce a TargetConfirmationFlags struct. r=kats draft
authorBotond Ballo <botond@mozilla.com>
Fri, 16 Feb 2018 20:03:51 -0500
changeset 758063 6826899367d19decbb6da0b3d25f32758c46dcec
parent 757991 3904c3f9314fd040828c5f1cf1fcc86fd8adfe3e
child 758064 8451db019c2ef3d8f028108e0b2a23b01418cc54
push id99941
push userbballo@mozilla.com
push dateWed, 21 Feb 2018 21:04:27 +0000
reviewerskats
bugs1425573
milestone60.0a1
Bug 1425573 - Introduce a TargetConfirmationFlags struct. r=kats The struct initially stores just one flag, mTargetConfirmed, but is introduced with the intention of expanding it to store additional ones. MozReview-Commit-ID: 88255UvoYYQ
gfx/layers/apz/src/APZCTreeManager.cpp
gfx/layers/apz/src/APZUtils.h
gfx/layers/apz/src/InputBlockState.cpp
gfx/layers/apz/src/InputBlockState.h
gfx/layers/apz/src/InputQueue.cpp
gfx/layers/apz/src/InputQueue.h
gfx/layers/apz/test/gtest/APZTestCommon.h
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -1134,28 +1134,26 @@ APZCTreeManager::ReceiveInputEvent(Input
         if (gfxPrefs::APZTestLoggingEnabled() && mouseInput.mType == MouseInput::MOUSE_HITTEST) {
           ScrollableLayerGuid guid = apzc->GetGuid();
           CompositorBridgeParent::CallWithIndirectShadowTree(guid.mLayersId,
             [&](LayerTreeState& aState) -> void {
               aState.mApzTestData.RecordHitResult(mouseInput.mOrigin, hitResult, guid.mScrollId);
             });
         }
 
-        bool targetConfirmed = (hitResult != CompositorHitTestInfo::eInvisibleToHitTest)
-                            && !(hitResult & CompositorHitTestInfo::eDispatchToContent);
+        TargetConfirmationFlags confFlags{hitResult};
         bool apzDragEnabled = gfxPrefs::APZDragEnabled();
         if (apzDragEnabled && hitScrollbar) {
           // If scrollbar dragging is enabled and we hit a scrollbar, wait
           // for the main-thread confirmation because it contains drag metrics
           // that we need.
-          targetConfirmed = false;
+          confFlags.mTargetConfirmed = false;
         }
         result = mInputQueue->ReceiveInputEvent(
-          apzc, targetConfirmed,
-          mouseInput, aOutInputBlockId);
+          apzc, confFlags, mouseInput, aOutInputBlockId);
 
         // If we're starting an async scrollbar drag
         if (apzDragEnabled && startsDrag && hitScrollbarNode &&
             hitScrollbarNode->IsScrollThumbNode() &&
             hitScrollbarNode->GetScrollThumbData().mIsAsyncDraggable) {
           SetupScrollbarDrag(mouseInput, hitScrollbarNode.get(), apzc.get());
         }
 
@@ -1218,17 +1216,17 @@ APZCTreeManager::ReceiveInputEvent(Input
           transformToGecko, wheelInput.mOrigin);
 
         if (!untransformedOrigin) {
           return result;
         }
 
         result = mInputQueue->ReceiveInputEvent(
           apzc,
-          /* aTargetConfirmed = */ !(hitResult & CompositorHitTestInfo::eDispatchToContent),
+          TargetConfirmationFlags{hitResult},
           wheelInput, aOutInputBlockId);
 
         // Update the out-parameters so they are what the caller expects.
         apzc->GetGuid(aOutTargetGuid);
         wheelInput.mOrigin = *untransformedOrigin;
       }
       break;
     } case PANGESTURE_INPUT: {
@@ -1270,17 +1268,17 @@ APZCTreeManager::ReceiveInputEvent(Input
             transformToGecko, panInput.mPanDisplacement, panInput.mPanStartPoint);
 
         if (!untransformedStartPoint || !untransformedDisplacement) {
           return result;
         }
 
         result = mInputQueue->ReceiveInputEvent(
             apzc,
-            /* aTargetConfirmed = */ !(hitResult & CompositorHitTestInfo::eDispatchToContent),
+            TargetConfirmationFlags{hitResult},
             panInput, aOutInputBlockId);
 
         // Update the out-parameters so they are what the caller expects.
         apzc->GetGuid(aOutTargetGuid);
         panInput.mPanStartPoint = *untransformedStartPoint;
         panInput.mPanDisplacement = *untransformedDisplacement;
 
         panInput.mOverscrollBehaviorAllowsSwipe =
@@ -1300,17 +1298,17 @@ APZCTreeManager::ReceiveInputEvent(Input
           outTransform, pinchInput.mFocusPoint);
 
         if (!untransformedFocusPoint) {
           return result;
         }
 
         result = mInputQueue->ReceiveInputEvent(
             apzc,
-            /* aTargetConfirmed = */ !(hitResult & CompositorHitTestInfo::eDispatchToContent),
+            TargetConfirmationFlags{hitResult},
             pinchInput, aOutInputBlockId);
 
         // Update the out-parameters so they are what the caller expects.
         apzc->GetGuid(aOutTargetGuid);
         pinchInput.mFocusPoint = *untransformedFocusPoint;
       }
       break;
     } case TAPGESTURE_INPUT: {  // note: no one currently sends these
@@ -1326,17 +1324,17 @@ APZCTreeManager::ReceiveInputEvent(Input
           UntransformBy(outTransform, tapInput.mPoint);
 
         if (!untransformedPoint) {
           return result;
         }
 
         result = mInputQueue->ReceiveInputEvent(
             apzc,
-            /* aTargetConfirmed = */ !(hitResult & CompositorHitTestInfo::eDispatchToContent),
+            TargetConfirmationFlags{hitResult},
             tapInput, aOutInputBlockId);
 
         // Update the out-parameters so they are what the caller expects.
         apzc->GetGuid(aOutTargetGuid);
         tapInput.mPoint = *untransformedPoint;
       }
       break;
     } case KEYBOARD_INPUT: {
@@ -1410,17 +1408,17 @@ APZCTreeManager::ReceiveInputEvent(Input
       keyInput.mAction = action;
 
       APZ_KEY_LOG("Dispatching key input with apzc=%p\n",
                   targetApzc.get());
 
       // Dispatch the event to the input queue.
       result = mInputQueue->ReceiveInputEvent(
           targetApzc,
-          /* aTargetConfirmed = */ true,
+          TargetConfirmationFlags{true},
           keyInput, aOutInputBlockId);
 
       // Any keyboard event that is dispatched to the input queue at this point
       // should have been consumed
       MOZ_ASSERT(result == nsEventStatus_eConsumeDoDefault ||
                  result == nsEventStatus_eConsumeNoDefault);
 
       keyInput.mHandledByAPZ = true;
@@ -1584,17 +1582,17 @@ APZCTreeManager::ProcessTouchInput(Multi
     }
 
     if (mApzcForInputBlock) {
       MOZ_ASSERT(mHitResultForInputBlock != CompositorHitTestInfo::eInvisibleToHitTest);
 
       mApzcForInputBlock->GetGuid(aOutTargetGuid);
       uint64_t inputBlockId = 0;
       result = mInputQueue->ReceiveInputEvent(mApzcForInputBlock,
-          /* aTargetConfirmed = */ !(mHitResultForInputBlock & CompositorHitTestInfo::eDispatchToContent),
+          TargetConfirmationFlags{mHitResultForInputBlock},
           aInput, &inputBlockId);
       if (aOutInputBlockId) {
         *aOutInputBlockId = inputBlockId;
       }
       if (!touchBehaviors.IsEmpty()) {
         mInputQueue->SetAllowedTouchBehavior(inputBlockId, touchBehaviors);
       }
 
@@ -1669,17 +1667,17 @@ APZCTreeManager::ProcessTouchInputForScr
                         aTouchInput.mTimeStamp,
                         aTouchInput.modifiers};
   mouseInput.mHandledByAPZ = true;
 
   // The value of |targetConfirmed| passed to InputQueue::ReceiveInputEvent()
   // only matters for the first event, which creates the drag block. For
   // that event, the correct value is false, since the drag block will, at the
   // earliest, be confirmed in the subsequent SetupScrollbarDrag() call.
-  bool targetConfirmed = false;
+  TargetConfirmationFlags targetConfirmed{false};
 
   nsEventStatus result = mInputQueue->ReceiveInputEvent(mApzcForInputBlock,
       targetConfirmed, mouseInput, aOutInputBlockId);
 
   // |aScrollThumbNode| is non-null iff. this is the event that starts the drag.
   // If so, set up the drag.
   if (aScrollThumbNode) {
     SetupScrollbarDrag(mouseInput, aScrollThumbNode, mApzcForInputBlock.get());
--- a/gfx/layers/apz/src/APZUtils.h
+++ b/gfx/layers/apz/src/APZUtils.h
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_layers_APZUtils_h
 #define mozilla_layers_APZUtils_h
 
 #include <stdint.h>                     // for uint32_t
 #include "LayersTypes.h"
 #include "UnitTransforms.h"
+#include "mozilla/gfx/CompositorHitTestInfo.h"
 #include "mozilla/gfx/Point.h"
 #include "mozilla/EnumSet.h"
 #include "mozilla/FloatingPoint.h"
 
 namespace mozilla {
 namespace layers {
 
 enum CancelAnimationFlags : uint32_t {
@@ -71,12 +72,25 @@ static bool IsZero(const gfx::PointTyped
 // complete async transform.
 inline AsyncTransformMatrix
 CompleteAsyncTransform(const AsyncTransformComponentMatrix& aMatrix)
 {
   return ViewAs<AsyncTransformMatrix>(aMatrix,
       PixelCastJustification::MultipleAsyncTransforms);
 }
 
+struct TargetConfirmationFlags {
+  explicit TargetConfirmationFlags(bool aTargetConfirmed)
+    : mTargetConfirmed(aTargetConfirmed)
+  {}
+
+  explicit TargetConfirmationFlags(gfx::CompositorHitTestInfo aHitTestInfo)
+    : mTargetConfirmed(aHitTestInfo != gfx::CompositorHitTestInfo::eInvisibleToHitTest &&
+                       !(aHitTestInfo & gfx::CompositorHitTestInfo::eDispatchToContent))
+  {}
+
+  bool mTargetConfirmed : 1;
+};
+
 } // namespace layers
 } // namespace mozilla
 
 #endif // mozilla_layers_APZUtils_h
--- a/gfx/layers/apz/src/InputBlockState.cpp
+++ b/gfx/layers/apz/src/InputBlockState.cpp
@@ -18,20 +18,20 @@
 // #define TBS_LOG(...) printf_stderr("TBS: " __VA_ARGS__)
 
 namespace mozilla {
 namespace layers {
 
 static uint64_t sBlockCounter = InputBlockState::NO_BLOCK_ID + 1;
 
 InputBlockState::InputBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
-                                 bool aTargetConfirmed)
+                                 TargetConfirmationFlags aFlags)
   : mTargetApzc(aTargetApzc)
-  , mTargetConfirmed(aTargetConfirmed ? TargetConfirmationState::eConfirmed
-                                      : TargetConfirmationState::eUnconfirmed)
+  , mTargetConfirmed(aFlags.mTargetConfirmed ? TargetConfirmationState::eConfirmed
+                                             : TargetConfirmationState::eUnconfirmed)
   , mBlockId(sBlockCounter++)
   , mTransformToApzc(aTargetApzc->GetTransformToThis())
 {
   // We should never be constructed with a nullptr target.
   MOZ_ASSERT(mTargetApzc);
   mOverscrollHandoffChain = mTargetApzc->BuildOverscrollHandoffChain();
 }
 
@@ -154,18 +154,18 @@ InputBlockState::IsDownchainOfScrolledAp
 
 void
 InputBlockState::DispatchEvent(const InputData& aEvent) const
 {
   GetTargetApzc()->HandleInputEvent(aEvent, mTransformToApzc);
 }
 
 CancelableBlockState::CancelableBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
-                                           bool aTargetConfirmed)
-  : InputBlockState(aTargetApzc, aTargetConfirmed)
+                                           TargetConfirmationFlags aFlags)
+  : InputBlockState(aTargetApzc, aFlags)
   , mPreventDefault(false)
   , mContentResponded(false)
   , mContentResponseTimerExpired(false)
 {
 }
 
 bool
 CancelableBlockState::SetContentResponse(bool aPreventDefault)
@@ -246,19 +246,19 @@ CancelableBlockState::RecordContentRespo
     return;
   }
   mozilla::Telemetry::Accumulate(mozilla::Telemetry::CONTENT_RESPONSE_DURATION,
     (uint32_t)(TimeStamp::Now() - mContentResponseTimer).ToMilliseconds());
   mContentResponseTimer = TimeStamp();
 }
 
 DragBlockState::DragBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
-                               bool aTargetConfirmed,
+                               TargetConfirmationFlags aFlags,
                                const MouseInput& aInitialEvent)
-  : CancelableBlockState(aTargetApzc, aTargetConfirmed)
+  : CancelableBlockState(aTargetApzc, aFlags)
   , mReceivedMouseUp(false)
 {
 }
 
 bool
 DragBlockState::HasReceivedMouseUp()
 {
   return mReceivedMouseUp;
@@ -303,25 +303,25 @@ const char*
 DragBlockState::Type()
 {
   return "drag";
 }
 // This is used to track the current wheel transaction.
 static uint64_t sLastWheelBlockId = InputBlockState::NO_BLOCK_ID;
 
 WheelBlockState::WheelBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
-                                 bool aTargetConfirmed,
+                                 TargetConfirmationFlags aFlags,
                                  const ScrollWheelInput& aInitialEvent)
-  : CancelableBlockState(aTargetApzc, aTargetConfirmed)
+  : CancelableBlockState(aTargetApzc, aFlags)
   , mScrollSeriesCounter(0)
   , mTransactionEnded(false)
 {
   sLastWheelBlockId = GetBlockId();
 
-  if (aTargetConfirmed) {
+  if (aFlags.mTargetConfirmed) {
     // Find the nearest APZC in the overscroll handoff chain that is scrollable.
     // If we get a content confirmation later that the apzc is different, then
     // content should have found a scrollable apzc, so we don't need to handle
     // that case.
     RefPtr<AsyncPanZoomController> apzc =
       mOverscrollHandoffChain->FindFirstScrollable(
           aInitialEvent, &mAllowedScrollDirections);
 
@@ -538,23 +538,23 @@ WheelBlockState::AllowScrollHandoff() co
 void
 WheelBlockState::EndTransaction()
 {
   TBS_LOG("%p ending wheel transaction\n", this);
   mTransactionEnded = true;
 }
 
 PanGestureBlockState::PanGestureBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
-                                           bool aTargetConfirmed,
+                                           TargetConfirmationFlags aFlags,
                                            const PanGestureInput& aInitialEvent)
-  : CancelableBlockState(aTargetApzc, aTargetConfirmed)
+  : CancelableBlockState(aTargetApzc, aFlags)
   , mInterrupted(false)
   , mWaitingForContentResponse(false)
 {
-  if (aTargetConfirmed) {
+  if (aFlags.mTargetConfirmed) {
     // Find the nearest APZC in the overscroll handoff chain that is scrollable.
     // If we get a content confirmation later that the apzc is different, then
     // content should have found a scrollable apzc, so we don't need to handle
     // that case.
     RefPtr<AsyncPanZoomController> apzc =
       mOverscrollHandoffChain->FindFirstScrollable(
           aInitialEvent, &mAllowedScrollDirections);
 
@@ -638,18 +638,19 @@ PanGestureBlockState::AllowScrollHandoff
 
 void
 PanGestureBlockState::SetNeedsToWaitForContentResponse(bool aWaitForContentResponse)
 {
   mWaitingForContentResponse = aWaitForContentResponse;
 }
 
 TouchBlockState::TouchBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
-                                 bool aTargetConfirmed, TouchCounter& aCounter)
-  : CancelableBlockState(aTargetApzc, aTargetConfirmed)
+                                 TargetConfirmationFlags aFlags,
+                                 TouchCounter& aCounter)
+  : CancelableBlockState(aTargetApzc, aFlags)
   , mAllowedTouchBehaviorSet(false)
   , mDuringFastFling(false)
   , mSingleTapOccurred(false)
   , mInSlop(false)
   , mTouchCounter(aCounter)
 {
   TBS_LOG("Creating %p\n", this);
   if (!gfxPrefs::TouchActionEnabled()) {
@@ -869,14 +870,14 @@ TouchBlockState::UpdateSlopState(const M
 
 uint32_t
 TouchBlockState::GetActiveTouchCount() const
 {
   return mTouchCounter.GetActiveTouchCount();
 }
 
 KeyboardBlockState::KeyboardBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc)
-  : InputBlockState(aTargetApzc, true)
+  : InputBlockState(aTargetApzc, TargetConfirmationFlags{true})
 {
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/apz/src/InputBlockState.h
+++ b/gfx/layers/apz/src/InputBlockState.h
@@ -45,17 +45,17 @@ public:
   enum class TargetConfirmationState {
     eUnconfirmed,
     eTimedOut,
     eTimedOutAndMainThreadResponded,
     eConfirmed
   };
 
   explicit InputBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
-                           bool aTargetConfirmed);
+                           TargetConfirmationFlags aFlags);
   virtual ~InputBlockState()
   {}
 
   virtual CancelableBlockState* AsCancelableBlock() {
     return nullptr;
   }
   virtual TouchBlockState* AsTouchBlock() {
     return nullptr;
@@ -138,17 +138,17 @@ protected:
  * where web content doesn't respond in time. The mContentResponded
  * and mContentResponseTimerExpired flags indicate which of these scenarios
  * occurred.
  */
 class CancelableBlockState : public InputBlockState
 {
 public:
   CancelableBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
-                       bool aTargetConfirmed);
+                       TargetConfirmationFlags aFlags);
 
   CancelableBlockState* AsCancelableBlock() override {
     return this;
   }
 
   /**
    * Record whether or not content cancelled this block of events.
    * @param aPreventDefault true iff the block is cancelled.
@@ -213,17 +213,17 @@ private:
 
 /**
  * A single block of wheel events.
  */
 class WheelBlockState : public CancelableBlockState
 {
 public:
   WheelBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
-                  bool aTargetConfirmed,
+                  TargetConfirmationFlags aFlags,
                   const ScrollWheelInput& aEvent);
 
   bool SetContentResponse(bool aPreventDefault) override;
   bool MustStayActive() override;
   const char* Type() override;
   bool SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc,
                               TargetConfirmationState aState,
                               InputData* aFirstInput) override;
@@ -297,17 +297,17 @@ private:
 
 /**
  * A block of mouse events that are part of a drag
  */
 class DragBlockState : public CancelableBlockState
 {
 public:
   DragBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
-                 bool aTargetConfirmed,
+                 TargetConfirmationFlags aFlags,
                  const MouseInput& aEvent);
 
   bool MustStayActive() override;
   const char* Type() override;
 
   bool HasReceivedMouseUp();
   void MarkMouseUpReceived();
 
@@ -327,17 +327,17 @@ private:
 
 /**
  * A single block of pan gesture events.
  */
 class PanGestureBlockState : public CancelableBlockState
 {
 public:
   PanGestureBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
-                       bool aTargetConfirmed,
+                       TargetConfirmationFlags aFlags,
                        const PanGestureInput& aEvent);
 
   bool SetContentResponse(bool aPreventDefault) override;
   bool HasReceivedAllContentNotifications() const override;
   bool IsReadyForHandling() const override;
   bool MustStayActive() override;
   const char* Type() override;
   bool SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc,
@@ -387,17 +387,18 @@ private:
  * This also requires running code on the Gecko main thread, and so may
  * be populated with some latency. The mAllowedTouchBehaviorSet and
  * mAllowedTouchBehaviors variables track this information.
  */
 class TouchBlockState : public CancelableBlockState
 {
 public:
   explicit TouchBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
-                           bool aTargetConfirmed, TouchCounter& aTouchCounter);
+                           TargetConfirmationFlags aFlags,
+                           TouchCounter& aTouchCounter);
 
   TouchBlockState *AsTouchBlock() override {
     return this;
   }
 
   /**
    * Set the allowed touch behavior flags for this block.
    * @return false if this block already has these flags set, true if not.
--- a/gfx/layers/apz/src/InputQueue.cpp
+++ b/gfx/layers/apz/src/InputQueue.cpp
@@ -25,62 +25,62 @@ InputQueue::InputQueue()
 }
 
 InputQueue::~InputQueue() {
   mQueuedInputs.Clear();
 }
 
 nsEventStatus
 InputQueue::ReceiveInputEvent(const RefPtr<AsyncPanZoomController>& aTarget,
-                              bool aTargetConfirmed,
+                              TargetConfirmationFlags aFlags,
                               const InputData& aEvent,
                               uint64_t* aOutInputBlockId) {
   APZThreadUtils::AssertOnControllerThread();
 
   switch (aEvent.mInputType) {
     case MULTITOUCH_INPUT: {
       const MultiTouchInput& event = aEvent.AsMultiTouchInput();
-      return ReceiveTouchInput(aTarget, aTargetConfirmed, event, aOutInputBlockId);
+      return ReceiveTouchInput(aTarget, aFlags, event, aOutInputBlockId);
     }
 
     case SCROLLWHEEL_INPUT: {
       const ScrollWheelInput& event = aEvent.AsScrollWheelInput();
-      return ReceiveScrollWheelInput(aTarget, aTargetConfirmed, event, aOutInputBlockId);
+      return ReceiveScrollWheelInput(aTarget, aFlags, event, aOutInputBlockId);
     }
 
     case PANGESTURE_INPUT: {
       const PanGestureInput& event = aEvent.AsPanGestureInput();
-      return ReceivePanGestureInput(aTarget, aTargetConfirmed, event, aOutInputBlockId);
+      return ReceivePanGestureInput(aTarget, aFlags, event, aOutInputBlockId);
     }
 
     case MOUSE_INPUT: {
       const MouseInput& event = aEvent.AsMouseInput();
-      return ReceiveMouseInput(aTarget, aTargetConfirmed, event, aOutInputBlockId);
+      return ReceiveMouseInput(aTarget, aFlags, event, aOutInputBlockId);
     }
 
     case KEYBOARD_INPUT: {
       // Every keyboard input must have a confirmed target
-      MOZ_ASSERT(aTarget && aTargetConfirmed);
+      MOZ_ASSERT(aTarget && aFlags.mTargetConfirmed);
 
       const KeyboardInput& event = aEvent.AsKeyboardInput();
       return ReceiveKeyboardInput(aTarget, event, aOutInputBlockId);
     }
 
     default:
       // The return value for non-touch input is only used by tests, so just pass
       // through the return value for now. This can be changed later if needed.
       // TODO (bug 1098430): we will eventually need to have smarter handling for
       // non-touch events as well.
       return aTarget->HandleInputEvent(aEvent, aTarget->GetTransformToThis());
   }
 }
 
 nsEventStatus
 InputQueue::ReceiveTouchInput(const RefPtr<AsyncPanZoomController>& aTarget,
-                              bool aTargetConfirmed,
+                              TargetConfirmationFlags aFlags,
                               const MultiTouchInput& aEvent,
                               uint64_t* aOutInputBlockId) {
   TouchBlockState* block = nullptr;
   if (aEvent.mType == MultiTouchInput::MULTITOUCH_START) {
     nsTArray<TouchBehaviorFlags> currentBehaviors;
     bool haveBehaviors = false;
     if (!gfxPrefs::TouchActionEnabled()) {
       haveBehaviors = true;
@@ -88,17 +88,17 @@ InputQueue::ReceiveTouchInput(const RefP
       haveBehaviors = mActiveTouchBlock->GetAllowedTouchBehaviors(currentBehaviors);
       // If the behaviours aren't set, but the main-thread response timer on
       // the block is expired we still treat it as though it has behaviors,
       // because in that case we still want to interrupt the fast-fling and
       // use the default behaviours.
       haveBehaviors |= mActiveTouchBlock->IsContentResponseTimerExpired();
     }
 
-    block = StartNewTouchBlock(aTarget, aTargetConfirmed, false);
+    block = StartNewTouchBlock(aTarget, aFlags, false);
     INPQ_LOG("started new touch block %p id %" PRIu64 " for target %p\n",
         block, block->GetBlockId(), aTarget.get());
 
     // XXX using the chain from |block| here may be wrong in cases where the
     // target isn't confirmed and the real target turns out to be something
     // else. For now assume this is rare enough that it's not an issue.
     if (mQueuedInputs.IsEmpty() &&
         aEvent.mTouches.Length() == 1 &&
@@ -163,17 +163,17 @@ InputQueue::ReceiveTouchInput(const RefP
   }
   mQueuedInputs.AppendElement(MakeUnique<QueuedInput>(aEvent, *block));
   ProcessQueue();
   return result;
 }
 
 nsEventStatus
 InputQueue::ReceiveMouseInput(const RefPtr<AsyncPanZoomController>& aTarget,
-                              bool aTargetConfirmed,
+                              TargetConfirmationFlags aFlags,
                               const MouseInput& aEvent,
                               uint64_t* aOutInputBlockId) {
   // On a new mouse down we can have a new target so we must force a new block
   // with a new target.
   bool newBlock = DragTracker::StartsDrag(aEvent);
 
   DragBlockState* block = newBlock ? nullptr : mActiveDragBlock.get();
   if (block && block->HasReceivedMouseUp()) {
@@ -193,17 +193,17 @@ InputQueue::ReceiveMouseInput(const RefP
   if (!newBlock && !block) {
     // This input event is not in a drag block, so we're not doing anything
     // with it, return eIgnore.
     return nsEventStatus_eIgnore;
   }
 
   if (!block) {
     MOZ_ASSERT(newBlock);
-    block = new DragBlockState(aTarget, aTargetConfirmed, aEvent);
+    block = new DragBlockState(aTarget, aFlags, aEvent);
 
     INPQ_LOG("started new drag block %p id %" PRIu64 " for %sconfirmed target %p\n",
         block, block->GetBlockId(), aTargetConfirmed ? "" : "un", aTarget.get());
 
     mActiveDragBlock = block;
 
     CancelAnimationsForNewBlock(block);
     MaybeRequestContentResponse(aTarget, block);
@@ -222,33 +222,33 @@ InputQueue::ReceiveMouseInput(const RefP
 
   // The event is part of a drag block and could potentially cause
   // scrolling, so return DoDefault.
   return nsEventStatus_eConsumeDoDefault;
 }
 
 nsEventStatus
 InputQueue::ReceiveScrollWheelInput(const RefPtr<AsyncPanZoomController>& aTarget,
-                                    bool aTargetConfirmed,
+                                    TargetConfirmationFlags aFlags,
                                     const ScrollWheelInput& aEvent,
                                     uint64_t* aOutInputBlockId) {
   WheelBlockState* block = mActiveWheelBlock.get();
   // If the block is not accepting new events we'll create a new input block
   // (and therefore a new wheel transaction).
   if (block &&
       (!block->ShouldAcceptNewEvent() ||
        block->MaybeTimeout(aEvent)))
   {
     block = nullptr;
   }
 
   MOZ_ASSERT(!block || block->InTransaction());
 
   if (!block) {
-    block = new WheelBlockState(aTarget, aTargetConfirmed, aEvent);
+    block = new WheelBlockState(aTarget, aFlags, aEvent);
     INPQ_LOG("started new scroll wheel block %p id %" PRIu64 " for target %p\n",
         block, block->GetBlockId(), aTarget.get());
 
     mActiveWheelBlock = block;
 
     CancelAnimationsForNewBlock(block, ExcludeWheel);
     MaybeRequestContentResponse(aTarget, block);
   } else {
@@ -324,17 +324,17 @@ CanScrollTargetHorizontally(const PanGes
         horizontalComponent, &allowedScrollDirections);
   return horizontallyScrollableAPZC &&
       horizontallyScrollableAPZC == aBlock->GetTargetApzc() &&
       allowedScrollDirections.contains(ScrollDirection::eHorizontal);
 }
 
 nsEventStatus
 InputQueue::ReceivePanGestureInput(const RefPtr<AsyncPanZoomController>& aTarget,
-                                   bool aTargetConfirmed,
+                                   TargetConfirmationFlags aFlags,
                                    const PanGestureInput& aEvent,
                                    uint64_t* aOutInputBlockId) {
   if (aEvent.mType == PanGestureInput::PANGESTURE_MAYSTART ||
       aEvent.mType == PanGestureInput::PANGESTURE_CANCELLED) {
     // Ignore these events for now.
     return nsEventStatus_eConsumeDoDefault;
   }
 
@@ -350,21 +350,21 @@ InputQueue::ReceivePanGestureInput(const
     if (event.mType != PanGestureInput::PANGESTURE_START) {
       // Only PANGESTURE_START events are allowed to start a new pan gesture
       // block, but we really want to start a new block here, so we magically
       // turn this input into a PANGESTURE_START.
       INPQ_LOG("transmogrifying pan input %d to PANGESTURE_START for new block\n",
           event.mType);
       event.mType = PanGestureInput::PANGESTURE_START;
     }
-    block = new PanGestureBlockState(aTarget, aTargetConfirmed, event);
+    block = new PanGestureBlockState(aTarget, aFlags, event);
     INPQ_LOG("started new pan gesture block %p id %" PRIu64 " for target %p\n",
         block, block->GetBlockId(), aTarget.get());
 
-    if (aTargetConfirmed &&
+    if (aFlags.mTargetConfirmed &&
         event.mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection &&
         !CanScrollTargetHorizontally(event, block)) {
       // This event may trigger a swipe gesture, depending on what our caller
       // wants to do it. We need to suspend handling of this block until we get
       // a content response which will tell us whether to proceed or abort the
       // block.
       block->SetNeedsToWaitForContentResponse(true);
 
@@ -441,30 +441,30 @@ InputQueue::MaybeRequestContentResponse(
     ScheduleMainThreadTimeout(aTarget, aBlock);
   }
 }
 
 uint64_t
 InputQueue::InjectNewTouchBlock(AsyncPanZoomController* aTarget)
 {
   TouchBlockState* block = StartNewTouchBlock(aTarget,
-    /* aTargetConfirmed = */ true,
+    TargetConfirmationFlags{true},
     /* aCopyPropertiesFromCurrent = */ true);
   INPQ_LOG("injecting new touch block %p with id %" PRIu64 " and target %p\n",
     block, block->GetBlockId(), aTarget);
   ScheduleMainThreadTimeout(aTarget, block);
   return block->GetBlockId();
 }
 
 TouchBlockState*
 InputQueue::StartNewTouchBlock(const RefPtr<AsyncPanZoomController>& aTarget,
-                               bool aTargetConfirmed,
+                               TargetConfirmationFlags aFlags,
                                bool aCopyPropertiesFromCurrent)
 {
-  TouchBlockState* newBlock = new TouchBlockState(aTarget, aTargetConfirmed,
+  TouchBlockState* newBlock = new TouchBlockState(aTarget, aFlags,
       mTouchCounter);
   if (aCopyPropertiesFromCurrent) {
     // We should never enter here without a current touch block, because this
     // codepath is invoked from the OnLongPress handler in
     // AsyncPanZoomController, which should bail out if there is no current
     // touch block.
     MOZ_ASSERT(GetCurrentTouchBlock());
     newBlock->CopyPropertiesFrom(*GetCurrentTouchBlock());
--- a/gfx/layers/apz/src/InputQueue.h
+++ b/gfx/layers/apz/src/InputQueue.h
@@ -47,17 +47,17 @@ public:
 
   /**
    * Notifies the InputQueue of a new incoming input event. The APZC that the
    * input event was targeted to should be provided in the |aTarget| parameter.
    * See the documentation on APZCTreeManager::ReceiveInputEvent for info on
    * return values from this function, including |aOutInputBlockId|.
    */
   nsEventStatus ReceiveInputEvent(const RefPtr<AsyncPanZoomController>& aTarget,
-                                  bool aTargetConfirmed,
+                                  TargetConfirmationFlags aFlags,
                                   const InputData& aEvent,
                                   uint64_t* aOutInputBlockId);
   /**
    * This function should be invoked to notify the InputQueue when web content
    * decides whether or not it wants to cancel a block of events. The block
    * id to which this applies should be provided in |aInputBlockId|.
    */
   void ContentReceivedInputBlock(uint64_t aInputBlockId, bool aPreventDefault);
@@ -135,48 +135,48 @@ public:
    * use the provided |aOnScrollbar| to populate that information.
    */
   bool IsDragOnScrollbar(bool aOnScrollbar);
 
 private:
   ~InputQueue();
 
   TouchBlockState* StartNewTouchBlock(const RefPtr<AsyncPanZoomController>& aTarget,
-                                      bool aTargetConfirmed,
+                                      TargetConfirmationFlags aFlags,
                                       bool aCopyPropertiesFromCurrent);
 
   /**
    * If animations are present for the current pending input block, cancel
    * them as soon as possible.
    */
   void CancelAnimationsForNewBlock(InputBlockState* aBlock,
                                    CancelAnimationFlags aExtraFlags = Default);
 
   /**
    * If we need to wait for a content response, schedule that now.
    */
   void MaybeRequestContentResponse(const RefPtr<AsyncPanZoomController>& aTarget,
                                    CancelableBlockState* aBlock);
 
   nsEventStatus ReceiveTouchInput(const RefPtr<AsyncPanZoomController>& aTarget,
-                                  bool aTargetConfirmed,
+                                  TargetConfirmationFlags aFlags,
                                   const MultiTouchInput& aEvent,
                                   uint64_t* aOutInputBlockId);
   nsEventStatus ReceiveMouseInput(const RefPtr<AsyncPanZoomController>& aTarget,
-                                  bool aTargetConfirmed,
+                                  TargetConfirmationFlags aFlags,
                                   const MouseInput& aEvent,
                                   uint64_t* aOutInputBlockId);
   nsEventStatus ReceiveScrollWheelInput(const RefPtr<AsyncPanZoomController>& aTarget,
-                                        bool aTargetConfirmed,
+                                        TargetConfirmationFlags aFlags,
                                         const ScrollWheelInput& aEvent,
                                         uint64_t* aOutInputBlockId);
   nsEventStatus ReceivePanGestureInput(const RefPtr<AsyncPanZoomController>& aTarget,
-                                        bool aTargetConfirmed,
-                                        const PanGestureInput& aEvent,
-                                        uint64_t* aOutInputBlockId);
+                                       TargetConfirmationFlags aFlags,
+                                       const PanGestureInput& aEvent,
+                                       uint64_t* aOutInputBlockId);
   nsEventStatus ReceiveKeyboardInput(const RefPtr<AsyncPanZoomController>& aTarget,
                                      const KeyboardInput& aEvent,
                                      uint64_t* aOutInputBlockId);
 
   /**
    * Helper function that searches mQueuedInputs for the first block matching
    * the given id, and returns it. If |aOutFirstInput| is non-null, it is
    * populated with a pointer to the first input in mQueuedInputs that
--- a/gfx/layers/apz/test/gtest/APZTestCommon.h
+++ b/gfx/layers/apz/test/gtest/APZTestCommon.h
@@ -212,17 +212,17 @@ public:
     // This is a function whose signature matches exactly the ReceiveInputEvent
     // on APZCTreeManager. This allows us to templates for functions like
     // TouchDown, TouchUp, etc so that we can reuse the code for dispatching
     // events into both APZC and APZCTM.
     return ReceiveInputEvent(aEvent, aOutInputBlockId);
   }
 
   nsEventStatus ReceiveInputEvent(const InputData& aEvent, uint64_t* aOutInputBlockId) {
-    return GetInputQueue()->ReceiveInputEvent(this, !mWaitForMainThread, aEvent, aOutInputBlockId);
+    return GetInputQueue()->ReceiveInputEvent(this, TargetConfirmationFlags{!mWaitForMainThread}, aEvent, aOutInputBlockId);
   }
 
   void ContentReceivedInputBlock(uint64_t aInputBlockId, bool aPreventDefault) {
     GetInputQueue()->ContentReceivedInputBlock(aInputBlockId, aPreventDefault);
   }
 
   void ConfirmTarget(uint64_t aInputBlockId) {
     RefPtr<AsyncPanZoomController> target = this;