Bug 1141127 - When inside a slop area around the first touchstart, prevent touchmove events from going to content. r=botond

This commit is contained in:
Kartikaya Gupta 2015-11-04 17:09:52 -05:00
parent 5a5e7f5dd9
commit f52fe38d2a
3 changed files with 48 additions and 4 deletions

View File

@ -103,9 +103,7 @@ CancelableBlockState::SetContentResponse(bool aPreventDefault)
} }
TBS_LOG("%p got content response %d with timer expired %d\n", TBS_LOG("%p got content response %d with timer expired %d\n",
this, aPreventDefault, mContentResponseTimerExpired); this, aPreventDefault, mContentResponseTimerExpired);
if (!mContentResponseTimerExpired) {
mPreventDefault = aPreventDefault; mPreventDefault = aPreventDefault;
}
mContentResponded = true; mContentResponded = true;
return true; return true;
} }
@ -625,6 +623,7 @@ TouchBlockState::TouchBlockState(const RefPtr<AsyncPanZoomController>& aTargetAp
, mAllowedTouchBehaviorSet(false) , mAllowedTouchBehaviorSet(false)
, mDuringFastFling(false) , mDuringFastFling(false)
, mSingleTapOccurred(false) , mSingleTapOccurred(false)
, mInSlop(false)
, mTouchCounter(aCounter) , mTouchCounter(aCounter)
{ {
TBS_LOG("Creating %p\n", this); TBS_LOG("Creating %p\n", this);
@ -831,5 +830,33 @@ TouchBlockState::TouchActionAllowsPanningXY() const
&& (flags & AllowedTouchBehavior::VERTICAL_PAN); && (flags & AllowedTouchBehavior::VERTICAL_PAN);
} }
bool
TouchBlockState::UpdateSlopState(const MultiTouchInput& aInput)
{
if (aInput.mType == MultiTouchInput::MULTITOUCH_START) {
// this is by definition the first event in this block. If it's the first
// touch, then we enter a slop state.
mInSlop = (aInput.mTouches.Length() == 1);
if (mInSlop) {
mSlopOrigin = aInput.mTouches[0].mScreenPoint;
TBS_LOG("%p entering slop with origin %s\n", this, Stringify(mSlopOrigin).c_str());
}
return false;
}
if (mInSlop) {
bool stayInSlop = (aInput.mType == MultiTouchInput::MULTITOUCH_MOVE) &&
(aInput.mTouches.Length() == 1) &&
((aInput.mTouches[0].mScreenPoint - mSlopOrigin).Length() <
AsyncPanZoomController::GetTouchStartTolerance());
if (!stayInSlop) {
// we're out of the slop zone, and will stay out for the remainder of
// this block
TBS_LOG("%p exiting slop\n", this);
mInSlop = false;
}
}
return mInSlop;
}
} // namespace layers } // namespace layers
} // namespace mozilla } // namespace mozilla

View File

@ -430,6 +430,16 @@ public:
bool TouchActionAllowsPanningY() const; bool TouchActionAllowsPanningY() const;
bool TouchActionAllowsPanningXY() const; bool TouchActionAllowsPanningXY() const;
/**
* Notifies the input block of an incoming touch event so that the block can
* update its internal slop state. "Slop" refers to the area around the
* initial touchstart where we drop touchmove events so that content doesn't
* see them.
* @return true iff the provided event is a touchmove in the slop area and
* so should not be sent to content.
*/
bool UpdateSlopState(const MultiTouchInput& aInput);
bool HasEvents() const override; bool HasEvents() const override;
void DropEvents() override; void DropEvents() override;
void HandleEvents() override; void HandleEvents() override;
@ -442,6 +452,8 @@ private:
bool mAllowedTouchBehaviorSet; bool mAllowedTouchBehaviorSet;
bool mDuringFastFling; bool mDuringFastFling;
bool mSingleTapOccurred; bool mSingleTapOccurred;
bool mInSlop;
ScreenIntPoint mSlopOrigin;
nsTArray<MultiTouchInput> mEvents; nsTArray<MultiTouchInput> mEvents;
// A reference to the InputQueue's touch counter // A reference to the InputQueue's touch counter
TouchCounter& mTouchCounter; TouchCounter& mTouchCounter;

View File

@ -160,8 +160,13 @@ InputQueue::ReceiveTouchInput(const RefPtr<AsyncPanZoomController>& aTarget,
INPQ_LOG("dropping event due to block %p being in fast motion\n", block); INPQ_LOG("dropping event due to block %p being in fast motion\n", block);
result = nsEventStatus_eConsumeNoDefault; result = nsEventStatus_eConsumeNoDefault;
} else if (target && target->ArePointerEventsConsumable(block, aEvent.AsMultiTouchInput().mTouches.Length())) { } else if (target && target->ArePointerEventsConsumable(block, aEvent.AsMultiTouchInput().mTouches.Length())) {
if (block->UpdateSlopState(aEvent.AsMultiTouchInput())) {
INPQ_LOG("dropping event due to block %p being in slop\n", block);
result = nsEventStatus_eConsumeNoDefault;
} else {
result = nsEventStatus_eConsumeDoDefault; result = nsEventStatus_eConsumeDoDefault;
} }
}
if (!MaybeHandleCurrentBlock(block, aEvent)) { if (!MaybeHandleCurrentBlock(block, aEvent)) {
block->AddEvent(aEvent.AsMultiTouchInput()); block->AddEvent(aEvent.AsMultiTouchInput());
} }