Bug 1193062 - Add PanGestureBlockState. r=kats

--HG--
extra : commitid : BVMuP4An1li
extra : rebase_source : fb55de2fbe3f7abcbd068c46b047046150cc5c8b
extra : histedit_source : 8a287e3ff2a0099e9ab8794cffb93dbfe0ef89d9
This commit is contained in:
Markus Stange 2015-08-26 11:42:12 -04:00
Родитель 6d1e1e95c1
Коммит 395b5b7beb
6 изменённых файлов: 217 добавлений и 6 удалений

Просмотреть файл

@ -3155,6 +3155,12 @@ AsyncPanZoomController::CurrentTouchBlock()
return GetInputQueue()->CurrentTouchBlock();
}
PanGestureBlockState*
AsyncPanZoomController::CurrentPanGestureBlock()
{
return GetInputQueue()->CurrentPanGestureBlock();
}
void
AsyncPanZoomController::ResetInputState()
{

Просмотреть файл

@ -49,6 +49,7 @@ class AsyncPanZoomAnimation;
class FlingAnimation;
class InputBlockState;
class TouchBlockState;
class PanGestureBlockState;
class OverscrollHandoffChain;
class StateChangeNotificationBlocker;
@ -832,6 +833,7 @@ private:
TouchBlockState* CurrentTouchBlock();
bool HasReadyTouchBlock();
PanGestureBlockState* CurrentPanGestureBlock();
/* ===================================================================
* The functions and members in this section are used to manage

Просмотреть файл

@ -421,6 +421,103 @@ WheelBlockState::EndTransaction()
mTransactionEnded = true;
}
PanGestureBlockState::PanGestureBlockState(const nsRefPtr<AsyncPanZoomController>& aTargetApzc,
bool aTargetConfirmed,
const PanGestureInput& aInitialEvent)
: CancelableBlockState(aTargetApzc, aTargetConfirmed)
, mInterrupted(false)
{
if (aTargetConfirmed) {
// 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.
nsRefPtr<AsyncPanZoomController> apzc =
mOverscrollHandoffChain->FindFirstScrollable(aInitialEvent);
if (apzc && apzc != GetTargetApzc()) {
UpdateTargetApzc(apzc);
}
}
}
bool
PanGestureBlockState::SetConfirmedTargetApzc(const nsRefPtr<AsyncPanZoomController>& aTargetApzc)
{
// The APZC that we find via APZCCallbackHelpers may not be the same APZC
// ESM or OverscrollHandoff would have computed. Make sure we get the right
// one by looking for the first apzc the next pending event can scroll.
nsRefPtr<AsyncPanZoomController> apzc = aTargetApzc;
if (apzc && mEvents.Length() > 0) {
const PanGestureInput& event = mEvents.ElementAt(0);
nsRefPtr<AsyncPanZoomController> scrollableApzc =
apzc->BuildOverscrollHandoffChain()->FindFirstScrollable(event);
if (scrollableApzc) {
apzc = scrollableApzc;
}
}
InputBlockState::SetConfirmedTargetApzc(apzc);
return true;
}
void
PanGestureBlockState::AddEvent(const PanGestureInput& aEvent)
{
mEvents.AppendElement(aEvent);
}
bool
PanGestureBlockState::HasEvents() const
{
return !mEvents.IsEmpty();
}
void
PanGestureBlockState::DropEvents()
{
TBS_LOG("%p dropping %" PRIuSIZE " events\n", this, mEvents.Length());
mEvents.Clear();
}
void
PanGestureBlockState::HandleEvents()
{
while (HasEvents()) {
TBS_LOG("%p returning first of %" PRIuSIZE " events\n", this, mEvents.Length());
PanGestureInput event = mEvents[0];
mEvents.RemoveElementAt(0);
DispatchEvent(event);
}
}
bool
PanGestureBlockState::MustStayActive()
{
return !mInterrupted;
}
const char*
PanGestureBlockState::Type()
{
return "pan gesture";
}
bool
PanGestureBlockState::SetContentResponse(bool aPreventDefault)
{
if (aPreventDefault) {
mInterrupted = true;
}
return CancelableBlockState::SetContentResponse(aPreventDefault);
}
bool
PanGestureBlockState::AllowScrollHandoff() const
{
return false;
}
TouchBlockState::TouchBlockState(const nsRefPtr<AsyncPanZoomController>& aTargetApzc,
bool aTargetConfirmed, TouchCounter& aCounter)
: CancelableBlockState(aTargetApzc, aTargetConfirmed)

Просмотреть файл

@ -20,6 +20,7 @@ class OverscrollHandoffChain;
class CancelableBlockState;
class TouchBlockState;
class WheelBlockState;
class PanGestureBlockState;
/**
* A base class that stores state common to various input blocks.
@ -85,6 +86,9 @@ public:
virtual WheelBlockState *AsWheelBlock() {
return nullptr;
}
virtual PanGestureBlockState *AsPanGestureBlock() {
return nullptr;
}
/**
* Record whether or not content cancelled this block of events.
@ -247,6 +251,42 @@ private:
bool mTransactionEnded;
};
/**
* A single block of pan gesture events.
*/
class PanGestureBlockState : public CancelableBlockState
{
public:
PanGestureBlockState(const nsRefPtr<AsyncPanZoomController>& aTargetApzc,
bool aTargetConfirmed,
const PanGestureInput& aEvent);
bool SetContentResponse(bool aPreventDefault) override;
bool HasEvents() const override;
void DropEvents() override;
void HandleEvents() override;
bool MustStayActive() override;
const char* Type() override;
bool SetConfirmedTargetApzc(const nsRefPtr<AsyncPanZoomController>& aTargetApzc) override;
void AddEvent(const PanGestureInput& aEvent);
PanGestureBlockState *AsPanGestureBlock() override {
return this;
}
/**
* @return Whether or not overscrolling is prevented for this block.
*/
bool AllowScrollHandoff() const;
bool WasInterrupted() const { return mInterrupted; }
private:
nsTArray<PanGestureInput> mEvents;
bool mInterrupted;
};
/**
* This class represents a single touch block. A touch block is
* a set of touch events that can be cancelled by web content via

Просмотреть файл

@ -45,6 +45,11 @@ InputQueue::ReceiveInputEvent(const nsRefPtr<AsyncPanZoomController>& aTarget,
return ReceiveScrollWheelInput(aTarget, aTargetConfirmed, event, aOutInputBlockId);
}
case PANGESTURE_INPUT: {
const PanGestureInput& event = aEvent.AsPanGestureInput();
return ReceivePanGestureInput(aTarget, aTargetConfirmed, 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.
@ -209,6 +214,56 @@ InputQueue::ReceiveScrollWheelInput(const nsRefPtr<AsyncPanZoomController>& aTar
return nsEventStatus_eConsumeDoDefault;
}
nsEventStatus
InputQueue::ReceivePanGestureInput(const nsRefPtr<AsyncPanZoomController>& aTarget,
bool aTargetConfirmed,
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;
}
PanGestureBlockState* block = nullptr;
if (!mInputBlockQueue.IsEmpty() &&
aEvent.mType != PanGestureInput::PANGESTURE_START) {
block = mInputBlockQueue.LastElement()->AsPanGestureBlock();
}
if (!block || block->WasInterrupted()) {
if (aEvent.mType != PanGestureInput::PANGESTURE_START) {
// Only PANGESTURE_START events are allowed to start a new pan gesture block.
return nsEventStatus_eConsumeDoDefault;
}
block = new PanGestureBlockState(aTarget, aTargetConfirmed, aEvent);
INPQ_LOG("started new pan gesture block %p for target %p\n", block, aTarget.get());
SweepDepletedBlocks();
mInputBlockQueue.AppendElement(block);
CancelAnimationsForNewBlock(block);
MaybeRequestContentResponse(aTarget, block);
} else {
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, which is what
// MaybeHandleCurrentBlock() does.
if (!MaybeHandleCurrentBlock(block, aEvent)) {
block->AddEvent(aEvent.AsPanGestureInput());
}
return nsEventStatus_eConsumeDoDefault;
}
void
InputQueue::CancelAnimationsForNewBlock(CancelableBlockState* aBlock)
{
@ -321,6 +376,14 @@ InputQueue::CurrentWheelBlock() const
return block;
}
PanGestureBlockState*
InputQueue::CurrentPanGestureBlock() const
{
PanGestureBlockState* block = CurrentBlock()->AsPanGestureBlock();
MOZ_ASSERT(block);
return block;
}
WheelBlockState*
InputQueue::GetCurrentWheelTransaction() const
{

Просмотреть файл

@ -23,6 +23,7 @@ class AsyncPanZoomController;
class CancelableBlockState;
class TouchBlockState;
class WheelBlockState;
class PanGestureBlockState;
/**
* This class stores incoming input events, separated into "input blocks", until
@ -80,15 +81,13 @@ public:
*/
CancelableBlockState* CurrentBlock() const;
/**
* Returns the current pending input block as a touch block. It must only be
* called if the current pending block is a touch block.
* Returns the current pending input block as a specific kind of block.
* These methods must only be called if the current pending block is of the
* requested type.
*/
TouchBlockState* CurrentTouchBlock() const;
/**
* Returns the current pending input block as a wheel block. It must only be
* called if the current pending block is a wheel block.
*/
WheelBlockState* CurrentWheelBlock() const;
PanGestureBlockState* CurrentPanGestureBlock() const;
/**
* Returns true iff the pending block at the head of the queue is ready for
* handling.
@ -131,6 +130,10 @@ private:
bool aTargetConfirmed,
const ScrollWheelInput& aEvent,
uint64_t* aOutInputBlockId);
nsEventStatus ReceivePanGestureInput(const nsRefPtr<AsyncPanZoomController>& aTarget,
bool aTargetConfirmed,
const PanGestureInput& aEvent,
uint64_t* aOutInputBlockId);
/**
* Remove any blocks that are inactive - not ready, and having no events.