зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1193062 - Add PanGestureBlockState. r=kats
--HG-- extra : commitid : BVMuP4An1li extra : rebase_source : fb55de2fbe3f7abcbd068c46b047046150cc5c8b extra : histedit_source : 8a287e3ff2a0099e9ab8794cffb93dbfe0ef89d9
This commit is contained in:
Родитель
6d1e1e95c1
Коммит
395b5b7beb
|
@ -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.
|
||||
|
|
Загрузка…
Ссылка в новой задаче