uint64_t InputQueue::InjectNewTouchBlock(AsyncPanZoomController* aTarget) { TouchBlockState* block = StartNewTouchBlock(aTarget, /* aTargetConfirmed = */ true, /* aCopyPropertiesFromCurrent = */ true); INPQ_LOG("injecting new touch block %p with id %" PRIu64 " and target %p\n", block, block->GetBlockId(), aTarget); ScheduleMainThreadTimeout(aTarget, block->GetBlockId()); return block->GetBlockId(); }
void GestureEventListener::CreateMaxTapTimeoutTask() { mLastTapInput = mLastTouchInput; TouchBlockState* block = mAsyncPanZoomController->GetInputQueue()->CurrentTouchBlock(); RefPtr<CancelableRunnable> task = NewRunnableMethod(this, &GestureEventListener::HandleInputTimeoutMaxTap, block->IsDuringFastFling()); mMaxTapTimeoutTask = task; mAsyncPanZoomController->PostDelayedTask( task.forget(), MAX_TAP_TIME); }
TouchBlockState* InputQueue::StartNewTouchBlock(const RefPtr<AsyncPanZoomController>& aTarget, bool aTargetConfirmed, bool aCopyPropertiesFromCurrent) { TouchBlockState* newBlock = new TouchBlockState(aTarget, aTargetConfirmed, mTouchCounter); if (aCopyPropertiesFromCurrent) { newBlock->CopyPropertiesFrom(*CurrentTouchBlock()); } SweepDepletedBlocks(); // Add the new block to the queue. mInputBlockQueue.AppendElement(newBlock); return newBlock; }
void TouchBlockState::CopyPropertiesFrom(const TouchBlockState& aOther) { TBS_LOG("%p copying properties from %p\n", this, &aOther); if (gfxPrefs::TouchActionEnabled()) { MOZ_ASSERT(aOther.mAllowedTouchBehaviorSet || aOther.IsContentResponseTimerExpired()); SetAllowedTouchBehaviors(aOther.mAllowedTouchBehaviors); } mTransformToApzc = aOther.mTransformToApzc; }
TouchBlockState* InputQueue::StartNewTouchBlock(const RefPtr<AsyncPanZoomController>& aTarget, bool aTargetConfirmed, bool aCopyPropertiesFromCurrent) { TouchBlockState* newBlock = new TouchBlockState(aTarget, aTargetConfirmed, 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()); } mActiveTouchBlock = newBlock; return newBlock; }
void InputQueue::SetAllowedTouchBehavior(uint64_t aInputBlockId, const nsTArray<TouchBehaviorFlags>& aBehaviors) { APZThreadUtils::AssertOnControllerThread(); INPQ_LOG("got allowed touch behaviours; block=%" PRIu64 "\n", aInputBlockId); bool success = false; for (size_t i = 0; i < mInputBlockQueue.Length(); i++) { if (mInputBlockQueue[i]->GetBlockId() == aInputBlockId) { TouchBlockState *block = mInputBlockQueue[i]->AsTouchBlock(); if (block) { success = block->SetAllowedTouchBehaviors(aBehaviors); } else { NS_WARNING("input block is not a touch block"); } break; } } if (success) { ProcessInputBlocks(); } }
nsEventStatus InputQueue::ReceiveTouchInput(const RefPtr<AsyncPanZoomController>& aTarget, bool aTargetConfirmed, 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; } else if (!mInputBlockQueue.IsEmpty() && CurrentBlock()->AsTouchBlock()) { haveBehaviors = CurrentTouchBlock()->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 |= CurrentTouchBlock()->IsContentResponseTimerExpired(); } block = StartNewTouchBlock(aTarget, aTargetConfirmed, false); INPQ_LOG("started new touch block %p for target %p\n", block, 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 (block == CurrentBlock() && aEvent.mTouches.Length() == 1 && block->GetOverscrollHandoffChain()->HasFastFlungApzc() && haveBehaviors) { // If we're already in a fast fling, and a single finger goes down, then // we want special handling for the touch event, because it shouldn't get // delivered to content. Note that we don't set this flag when going // from a fast fling to a pinch state (i.e. second finger goes down while // the first finger is moving). block->SetDuringFastFling(); block->SetConfirmedTargetApzc(aTarget); if (gfxPrefs::TouchActionEnabled()) { block->SetAllowedTouchBehaviors(currentBehaviors); } INPQ_LOG("block %p tagged as fast-motion\n", block); } CancelAnimationsForNewBlock(block); MaybeRequestContentResponse(aTarget, block); } else { if (!mInputBlockQueue.IsEmpty()) { block = mInputBlockQueue.LastElement().get()->AsTouchBlock(); } if (!block) { NS_WARNING("Received a non-start touch event while no touch blocks active!"); return nsEventStatus_eIgnore; } INPQ_LOG("received new event in block %p\n", block); } if (aOutInputBlockId) { *aOutInputBlockId = block->GetBlockId(); } // Note that the |aTarget| the APZCTM sent us may contradict the confirmed // target set on the block. In this case the confirmed target (which may be // null) should take priority. This is equivalent to just always using the // target (confirmed or not) from the block. RefPtr<AsyncPanZoomController> target = block->GetTargetApzc(); nsEventStatus result = nsEventStatus_eIgnore; // XXX calling ArePointerEventsConsumable on |target| may be wrong here if // 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 (block->IsDuringFastFling()) { INPQ_LOG("dropping event due to block %p being in fast motion\n", block); result = nsEventStatus_eConsumeNoDefault; } else if (target && target->ArePointerEventsConsumable(block, aEvent.AsMultiTouchInput().mTouches.Length())) { result = nsEventStatus_eConsumeDoDefault; } if (!MaybeHandleCurrentBlock(block, aEvent)) { block->AddEvent(aEvent.AsMultiTouchInput()); } return result; }