diff --git a/gfx/layers/apz/src/InputBlockState.cpp b/gfx/layers/apz/src/InputBlockState.cpp index e8587c103c82..26fb6f859d76 100644 --- a/gfx/layers/apz/src/InputBlockState.cpp +++ b/gfx/layers/apz/src/InputBlockState.cpp @@ -13,6 +13,7 @@ #include "mozilla/Telemetry.h" // for Telemetry #include "mozilla/layers/APZCTreeManager.h" // for AllowedTouchBehavior #include "OverscrollHandoffState.h" +#include "QueuedInput.h" #define TBS_LOG(...) // #define TBS_LOG(...) printf_stderr("TBS: " __VA_ARGS__) @@ -307,18 +308,28 @@ DragBlockState::HasEvents() const } void -DragBlockState::DropEvents() +DragBlockState::DropEvents(nsTArray>* aQueued) { TBS_LOG("%p dropping %" PRIuSIZE " events\n", this, mEvents.Length()); + MOZ_ASSERT(aQueued->Length() >= mEvents.Length()); + for (size_t i = 0; i < mEvents.Length(); i++) { + MOZ_ASSERT(aQueued->ElementAt(i)->Block() == this); + MOZ_ASSERT(aQueued->ElementAt(i)->Input()->mInputType == mEvents[i].mInputType); + } + aQueued->RemoveElementsAt(0, mEvents.Length()); mEvents.Clear(); } void -DragBlockState::HandleEvents() +DragBlockState::HandleEvents(nsTArray>* aQueued) { while (HasEvents()) { TBS_LOG("%p returning first of %" PRIuSIZE " events\n", this, mEvents.Length()); MouseInput event = mEvents[0]; + MOZ_ASSERT(aQueued->Length() > 0); + MOZ_ASSERT(aQueued->ElementAt(0)->Block() == this); + MOZ_ASSERT(aQueued->ElementAt(0)->Input()->mInputType == event.mInputType); + aQueued->RemoveElementAt(0); mEvents.RemoveElementAt(0); DispatchEvent(event); } @@ -446,18 +457,28 @@ WheelBlockState::HasEvents() const } void -WheelBlockState::DropEvents() +WheelBlockState::DropEvents(nsTArray>* aQueued) { TBS_LOG("%p dropping %" PRIuSIZE " events\n", this, mEvents.Length()); + MOZ_ASSERT(aQueued->Length() >= mEvents.Length()); + for (size_t i = 0; i < mEvents.Length(); i++) { + MOZ_ASSERT(aQueued->ElementAt(i)->Block() == this); + MOZ_ASSERT(aQueued->ElementAt(i)->Input()->mInputType == mEvents[i].mInputType); + } + aQueued->RemoveElementsAt(0, mEvents.Length()); mEvents.Clear(); } void -WheelBlockState::HandleEvents() +WheelBlockState::HandleEvents(nsTArray>* aQueued) { while (HasEvents()) { TBS_LOG("%p returning first of %" PRIuSIZE " events\n", this, mEvents.Length()); ScrollWheelInput event = mEvents[0]; + MOZ_ASSERT(aQueued->Length() > 0); + MOZ_ASSERT(aQueued->ElementAt(0)->Block() == this); + MOZ_ASSERT(aQueued->ElementAt(0)->Input()->mInputType == event.mInputType); + aQueued->RemoveElementAt(0); mEvents.RemoveElementAt(0); DispatchEvent(event); } @@ -656,18 +677,28 @@ PanGestureBlockState::HasEvents() const } void -PanGestureBlockState::DropEvents() +PanGestureBlockState::DropEvents(nsTArray>* aQueued) { TBS_LOG("%p dropping %" PRIuSIZE " events\n", this, mEvents.Length()); + MOZ_ASSERT(aQueued->Length() >= mEvents.Length()); + for (size_t i = 0; i < mEvents.Length(); i++) { + MOZ_ASSERT(aQueued->ElementAt(i)->Block() == this); + MOZ_ASSERT(aQueued->ElementAt(i)->Input()->mInputType == mEvents[i].mInputType); + } + aQueued->RemoveElementsAt(0, mEvents.Length()); mEvents.Clear(); } void -PanGestureBlockState::HandleEvents() +PanGestureBlockState::HandleEvents(nsTArray>* aQueued) { while (HasEvents()) { TBS_LOG("%p returning first of %" PRIuSIZE " events\n", this, mEvents.Length()); PanGestureInput event = mEvents[0]; + MOZ_ASSERT(aQueued->Length() > 0); + MOZ_ASSERT(aQueued->ElementAt(0)->Block() == this); + MOZ_ASSERT(aQueued->ElementAt(0)->Input()->mInputType == event.mInputType); + aQueued->RemoveElementAt(0); mEvents.RemoveElementAt(0); DispatchEvent(event); } @@ -857,18 +888,28 @@ TouchBlockState::Type() } void -TouchBlockState::DropEvents() +TouchBlockState::DropEvents(nsTArray>* aQueued) { TBS_LOG("%p dropping %" PRIuSIZE " events\n", this, mEvents.Length()); + MOZ_ASSERT(aQueued->Length() >= mEvents.Length()); + for (size_t i = 0; i < mEvents.Length(); i++) { + MOZ_ASSERT(aQueued->ElementAt(i)->Block() == this); + MOZ_ASSERT(aQueued->ElementAt(i)->Input()->mInputType == mEvents[i].mInputType); + } + aQueued->RemoveElementsAt(0, mEvents.Length()); mEvents.Clear(); } void -TouchBlockState::HandleEvents() +TouchBlockState::HandleEvents(nsTArray>* aQueued) { while (HasEvents()) { TBS_LOG("%p returning first of %" PRIuSIZE " events\n", this, mEvents.Length()); MultiTouchInput event = mEvents[0]; + MOZ_ASSERT(aQueued->Length() > 0); + MOZ_ASSERT(aQueued->ElementAt(0)->Block() == this); + MOZ_ASSERT(aQueued->ElementAt(0)->Input()->mInputType == event.mInputType); + aQueued->RemoveElementAt(0); mEvents.RemoveElementAt(0); DispatchEvent(event); } diff --git a/gfx/layers/apz/src/InputBlockState.h b/gfx/layers/apz/src/InputBlockState.h index 5862723d4f48..124904cec843 100644 --- a/gfx/layers/apz/src/InputBlockState.h +++ b/gfx/layers/apz/src/InputBlockState.h @@ -197,13 +197,13 @@ public: /** * Throw away all the events in this input block. */ - virtual void DropEvents() = 0; + virtual void DropEvents(nsTArray>* aQueued) = 0; /** * Process all events using this input block's target apzc, leaving this * block depleted. This input block's apzc must not be nullptr. */ - virtual void HandleEvents() = 0; + virtual void HandleEvents(nsTArray>* aQueued) = 0; /** * Return true if this input block must stay active if it would otherwise @@ -235,8 +235,8 @@ public: bool SetContentResponse(bool aPreventDefault) override; bool HasEvents() const override; - void DropEvents() override; - void HandleEvents() override; + void DropEvents(nsTArray>* aQueued) override; + void HandleEvents(nsTArray>* aQueued) override; bool MustStayActive() override; const char* Type() override; bool SetConfirmedTargetApzc(const RefPtr& aTargetApzc, @@ -320,8 +320,8 @@ public: const MouseInput& aEvent); bool HasEvents() const override; - void DropEvents() override; - void HandleEvents() override; + void DropEvents(nsTArray>* aQueued) override; + void HandleEvents(nsTArray>* aQueued) override; bool MustStayActive() override; const char* Type() override; @@ -357,8 +357,8 @@ public: bool HasReceivedAllContentNotifications() const override; bool IsReadyForHandling() const override; bool HasEvents() const override; - void DropEvents() override; - void HandleEvents() override; + void DropEvents(nsTArray>* aQueued) override; + void HandleEvents(nsTArray>* aQueued) override; bool MustStayActive() override; const char* Type() override; bool SetConfirmedTargetApzc(const RefPtr& aTargetApzc, @@ -507,8 +507,8 @@ public: uint32_t GetActiveTouchCount() const; bool HasEvents() const override; - void DropEvents() override; - void HandleEvents() override; + void DropEvents(nsTArray>* aQueued) override; + void HandleEvents(nsTArray>* aQueued) override; void DispatchEvent(const InputData& aEvent) const override; bool MustStayActive() override; const char* Type() override; diff --git a/gfx/layers/apz/src/InputQueue.cpp b/gfx/layers/apz/src/InputQueue.cpp index 616eede0ca5b..2e1a8a23730a 100644 --- a/gfx/layers/apz/src/InputQueue.cpp +++ b/gfx/layers/apz/src/InputQueue.cpp @@ -26,6 +26,7 @@ InputQueue::InputQueue() InputQueue::~InputQueue() { mInputBlockQueue.Clear(); + mQueuedInputs.Clear(); } nsEventStatus @@ -174,6 +175,7 @@ InputQueue::ReceiveTouchInput(const RefPtr& aTarget, } if (!MaybeHandleCurrentBlock(block, aEvent)) { block->AddEvent(aEvent.AsMultiTouchInput()); + mQueuedInputs.AppendElement(MakeUnique(aEvent.AsMultiTouchInput(), *block)); } return result; } @@ -233,6 +235,7 @@ InputQueue::ReceiveMouseInput(const RefPtr& aTarget, if (!MaybeHandleCurrentBlock(block, aEvent)) { block->AddEvent(aEvent.AsMouseInput()); + mQueuedInputs.AppendElement(MakeUnique(aEvent.AsMouseInput(), *block)); } if (DragTracker::EndsDrag(aEvent)) { @@ -295,6 +298,7 @@ InputQueue::ReceiveScrollWheelInput(const RefPtr& aTarge // MaybeHandleCurrentBlock() does. if (!MaybeHandleCurrentBlock(block, event)) { block->AddEvent(event); + mQueuedInputs.AppendElement(MakeUnique(event, *block)); } return nsEventStatus_eConsumeDoDefault; @@ -379,6 +383,7 @@ InputQueue::ReceivePanGestureInput(const RefPtr& aTarget // MaybeHandleCurrentBlock() does. if (!MaybeHandleCurrentBlock(block, event)) { block->AddEvent(event.AsPanGestureInput()); + mQueuedInputs.AppendElement(MakeUnique(event.AsPanGestureInput(), *block)); } return result; @@ -702,15 +707,15 @@ InputQueue::ProcessInputBlocks() { // target may be null here if the initial target was unconfirmed and then // we later got a confirmed null target. in that case drop the events. if (!target) { - curBlock->DropEvents(); + curBlock->DropEvents(&mQueuedInputs); } else if (curBlock->IsDefaultPrevented()) { - curBlock->DropEvents(); + curBlock->DropEvents(&mQueuedInputs); if (curBlock->AsTouchBlock()) { target->ResetTouchInputState(); } } else { UpdateActiveApzc(curBlock->GetTargetApzc()); - curBlock->HandleEvents(); + curBlock->HandleEvents(&mQueuedInputs); } MOZ_ASSERT(!curBlock->HasEvents()); @@ -760,6 +765,7 @@ InputQueue::Clear() APZThreadUtils::AssertOnControllerThread(); mInputBlockQueue.Clear(); + mQueuedInputs.Clear(); mActiveTouchBlock = nullptr; mActiveWheelBlock = nullptr; mActiveDragBlock = nullptr; diff --git a/gfx/layers/apz/src/QueuedInput.cpp b/gfx/layers/apz/src/QueuedInput.cpp index 0f63a82d835c..21dd8e1b4e75 100644 --- a/gfx/layers/apz/src/QueuedInput.cpp +++ b/gfx/layers/apz/src/QueuedInput.cpp @@ -38,5 +38,17 @@ QueuedInput::QueuedInput(const PanGestureInput& aInput, PanGestureBlockState& aB { } +InputData* +QueuedInput::Input() +{ + return mInput.get(); +} + +CancelableBlockState* +QueuedInput::Block() +{ + return mBlock.get(); +} + } // namespace layers } // namespace mozilla diff --git a/gfx/layers/apz/src/QueuedInput.h b/gfx/layers/apz/src/QueuedInput.h index 1c9183f3d1ab..68dfbc3c5acb 100644 --- a/gfx/layers/apz/src/QueuedInput.h +++ b/gfx/layers/apz/src/QueuedInput.h @@ -39,6 +39,9 @@ public: QueuedInput(const MouseInput& aInput, DragBlockState& aBlock); QueuedInput(const PanGestureInput& aInput, PanGestureBlockState& aBlock); + InputData* Input(); + CancelableBlockState* Block(); + private: // A copy of the input event that is provided to the constructor. This must // be non-null, and is owned by this QueuedInput instance (hence the