am 325bd07b
: Add tap/drag touchpad gesture. (DO NOT MERGE)
* commit '325bd07b311f8ba68079000e9fe8afbcc076d7b6': Add tap/drag touchpad gesture. (DO NOT MERGE)
This commit is contained in:
@ -72,9 +72,14 @@ static const float DRAG_MIN_SWITCH_SPEED = 50.0f; // pixels per second
|
|||||||
// The time between down and up must be less than this to be considered a tap.
|
// The time between down and up must be less than this to be considered a tap.
|
||||||
static const nsecs_t TAP_INTERVAL = 150 * 1000000; // 150 ms
|
static const nsecs_t TAP_INTERVAL = 150 * 1000000; // 150 ms
|
||||||
|
|
||||||
|
// Tap drag gesture delay time.
|
||||||
|
// The time between up and the next up must be greater than this to be considered a
|
||||||
|
// drag. Otherwise, the previous tap is finished and a new tap begins.
|
||||||
|
static const nsecs_t TAP_DRAG_INTERVAL = 150 * 1000000; // 150 ms
|
||||||
|
|
||||||
// The distance in pixels that the pointer is allowed to move from initial down
|
// The distance in pixels that the pointer is allowed to move from initial down
|
||||||
// to up and still be called a tap.
|
// to up and still be called a tap.
|
||||||
static const float TAP_SLOP = 5.0f; // 5 pixels
|
static const float TAP_SLOP = 10.0f; // 10 pixels
|
||||||
|
|
||||||
// Time after the first touch points go down to settle on an initial centroid.
|
// Time after the first touch points go down to settle on an initial centroid.
|
||||||
// This is intended to be enough time to handle cases where the user puts down two
|
// This is intended to be enough time to handle cases where the user puts down two
|
||||||
@ -2752,14 +2757,21 @@ void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process touches and virtual keys.
|
TouchResult touchResult;
|
||||||
TouchResult touchResult = consumeOffScreenTouches(when, policyFlags);
|
if (mLastTouch.pointerCount == 0 && mCurrentTouch.pointerCount == 0
|
||||||
if (touchResult == DISPATCH_TOUCH) {
|
&& mLastTouch.buttonState == mCurrentTouch.buttonState) {
|
||||||
suppressSwipeOntoVirtualKeys(when);
|
// Drop spurious syncs.
|
||||||
if (mPointerController != NULL) {
|
touchResult = DROP_STROKE;
|
||||||
dispatchPointerGestures(when, policyFlags);
|
} else {
|
||||||
|
// Process touches and virtual keys.
|
||||||
|
touchResult = consumeOffScreenTouches(when, policyFlags);
|
||||||
|
if (touchResult == DISPATCH_TOUCH) {
|
||||||
|
suppressSwipeOntoVirtualKeys(when);
|
||||||
|
if (mPointerController != NULL) {
|
||||||
|
dispatchPointerGestures(when, policyFlags, false /*isTimeout*/);
|
||||||
|
}
|
||||||
|
dispatchTouches(when, policyFlags);
|
||||||
}
|
}
|
||||||
dispatchTouches(when, policyFlags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy current touch to last touch in preparation for the next cycle.
|
// Copy current touch to last touch in preparation for the next cycle.
|
||||||
@ -2772,6 +2784,12 @@ void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TouchInputMapper::timeoutExpired(nsecs_t when) {
|
||||||
|
if (mPointerController != NULL) {
|
||||||
|
dispatchPointerGestures(when, 0 /*policyFlags*/, true /*isTimeout*/);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches(
|
TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches(
|
||||||
nsecs_t when, uint32_t policyFlags) {
|
nsecs_t when, uint32_t policyFlags) {
|
||||||
int32_t keyEventAction, keyEventFlags;
|
int32_t keyEventAction, keyEventFlags;
|
||||||
@ -3215,7 +3233,8 @@ void TouchInputMapper::prepareTouches(int32_t* outEdgeFlags,
|
|||||||
*outYPrecision = mLocked.orientedYPrecision;
|
*outYPrecision = mLocked.orientedYPrecision;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlags) {
|
void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlags,
|
||||||
|
bool isTimeout) {
|
||||||
// Switch pointer presentation.
|
// Switch pointer presentation.
|
||||||
mPointerController->setPresentation(
|
mPointerController->setPresentation(
|
||||||
mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS
|
mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS
|
||||||
@ -3224,7 +3243,11 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag
|
|||||||
|
|
||||||
// Update current gesture coordinates.
|
// Update current gesture coordinates.
|
||||||
bool cancelPreviousGesture, finishPreviousGesture;
|
bool cancelPreviousGesture, finishPreviousGesture;
|
||||||
preparePointerGestures(when, &cancelPreviousGesture, &finishPreviousGesture);
|
bool sendEvents = preparePointerGestures(when,
|
||||||
|
&cancelPreviousGesture, &finishPreviousGesture, isTimeout);
|
||||||
|
if (!sendEvents) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Show the pointer if needed.
|
// Show the pointer if needed.
|
||||||
if (mPointerGesture.currentGestureMode != PointerGesture::NEUTRAL
|
if (mPointerGesture.currentGestureMode != PointerGesture::NEUTRAL
|
||||||
@ -3237,7 +3260,9 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag
|
|||||||
|
|
||||||
// Update last coordinates of pointers that have moved so that we observe the new
|
// Update last coordinates of pointers that have moved so that we observe the new
|
||||||
// pointer positions at the same time as other pointers that have just gone up.
|
// pointer positions at the same time as other pointers that have just gone up.
|
||||||
bool down = mPointerGesture.currentGestureMode == PointerGesture::CLICK_OR_DRAG
|
bool down = mPointerGesture.currentGestureMode == PointerGesture::TAP
|
||||||
|
|| mPointerGesture.currentGestureMode == PointerGesture::TAP_DRAG
|
||||||
|
|| mPointerGesture.currentGestureMode == PointerGesture::BUTTON_CLICK_OR_DRAG
|
||||||
|| mPointerGesture.currentGestureMode == PointerGesture::PRESS
|
|| mPointerGesture.currentGestureMode == PointerGesture::PRESS
|
||||||
|| mPointerGesture.currentGestureMode == PointerGesture::SWIPE
|
|| mPointerGesture.currentGestureMode == PointerGesture::SWIPE
|
||||||
|| mPointerGesture.currentGestureMode == PointerGesture::FREEFORM;
|
|| mPointerGesture.currentGestureMode == PointerGesture::FREEFORM;
|
||||||
@ -3325,27 +3350,6 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send down and up for a tap.
|
|
||||||
if (mPointerGesture.currentGestureMode == PointerGesture::TAP) {
|
|
||||||
const PointerCoords& coords = mPointerGesture.currentGestureCoords[0];
|
|
||||||
int32_t edgeFlags = calculateEdgeFlagsUsingPointerBounds(mPointerController,
|
|
||||||
coords.getAxisValue(AMOTION_EVENT_AXIS_X),
|
|
||||||
coords.getAxisValue(AMOTION_EVENT_AXIS_Y));
|
|
||||||
nsecs_t downTime = mPointerGesture.downTime = mPointerGesture.tapTime;
|
|
||||||
mPointerGesture.resetTapTime();
|
|
||||||
|
|
||||||
dispatchMotion(downTime, policyFlags, mPointerSource,
|
|
||||||
AMOTION_EVENT_ACTION_DOWN, 0, metaState, edgeFlags,
|
|
||||||
mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
|
|
||||||
mPointerGesture.currentGestureIdBits, -1,
|
|
||||||
0, 0, downTime);
|
|
||||||
dispatchMotion(when, policyFlags, mPointerSource,
|
|
||||||
AMOTION_EVENT_ACTION_UP, 0, metaState, edgeFlags,
|
|
||||||
mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
|
|
||||||
mPointerGesture.currentGestureIdBits, -1,
|
|
||||||
0, 0, downTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send motion events for hover.
|
// Send motion events for hover.
|
||||||
if (mPointerGesture.currentGestureMode == PointerGesture::HOVER) {
|
if (mPointerGesture.currentGestureMode == PointerGesture::HOVER) {
|
||||||
dispatchMotion(when, policyFlags, mPointerSource,
|
dispatchMotion(when, policyFlags, mPointerSource,
|
||||||
@ -3372,13 +3376,49 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TouchInputMapper::preparePointerGestures(nsecs_t when,
|
bool TouchInputMapper::preparePointerGestures(nsecs_t when,
|
||||||
bool* outCancelPreviousGesture, bool* outFinishPreviousGesture) {
|
bool* outCancelPreviousGesture, bool* outFinishPreviousGesture, bool isTimeout) {
|
||||||
*outCancelPreviousGesture = false;
|
*outCancelPreviousGesture = false;
|
||||||
*outFinishPreviousGesture = false;
|
*outFinishPreviousGesture = false;
|
||||||
|
|
||||||
AutoMutex _l(mLock);
|
AutoMutex _l(mLock);
|
||||||
|
|
||||||
|
// Handle TAP timeout.
|
||||||
|
if (isTimeout) {
|
||||||
|
#if DEBUG_GESTURES
|
||||||
|
LOGD("Gestures: Processing timeout");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (mPointerGesture.lastGestureMode == PointerGesture::TAP) {
|
||||||
|
if (when <= mPointerGesture.tapUpTime + TAP_DRAG_INTERVAL) {
|
||||||
|
// The tap/drag timeout has not yet expired.
|
||||||
|
getContext()->requestTimeoutAtTime(mPointerGesture.tapUpTime + TAP_DRAG_INTERVAL);
|
||||||
|
} else {
|
||||||
|
// The tap is finished.
|
||||||
|
#if DEBUG_GESTURES
|
||||||
|
LOGD("Gestures: TAP finished");
|
||||||
|
#endif
|
||||||
|
*outFinishPreviousGesture = true;
|
||||||
|
|
||||||
|
mPointerGesture.activeGestureId = -1;
|
||||||
|
mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL;
|
||||||
|
mPointerGesture.currentGestureIdBits.clear();
|
||||||
|
|
||||||
|
mPointerController->setButtonState(0);
|
||||||
|
|
||||||
|
if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
|
||||||
|
mPointerGesture.spotGesture = PointerControllerInterface::SPOT_GESTURE_NEUTRAL;
|
||||||
|
mPointerGesture.spotIdBits.clear();
|
||||||
|
moveSpotsLocked();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We did not handle this timeout.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Update the velocity tracker.
|
// Update the velocity tracker.
|
||||||
{
|
{
|
||||||
VelocityTracker::Position positions[MAX_POINTERS];
|
VelocityTracker::Position positions[MAX_POINTERS];
|
||||||
@ -3433,7 +3473,7 @@ void TouchInputMapper::preparePointerGestures(nsecs_t when,
|
|||||||
// This is to prevent accidentally entering the hover state and flinging the
|
// This is to prevent accidentally entering the hover state and flinging the
|
||||||
// pointer when finishing a swipe and there is still one pointer left onscreen.
|
// pointer when finishing a swipe and there is still one pointer left onscreen.
|
||||||
isQuietTime = true;
|
isQuietTime = true;
|
||||||
} else if (mPointerGesture.lastGestureMode == PointerGesture::CLICK_OR_DRAG
|
} else if (mPointerGesture.lastGestureMode == PointerGesture::BUTTON_CLICK_OR_DRAG
|
||||||
&& mCurrentTouch.pointerCount >= 2
|
&& mCurrentTouch.pointerCount >= 2
|
||||||
&& !isPointerDown(mCurrentTouch.buttonState)) {
|
&& !isPointerDown(mCurrentTouch.buttonState)) {
|
||||||
// Enter quiet time when releasing the button and there are still two or more
|
// Enter quiet time when releasing the button and there are still two or more
|
||||||
@ -3468,7 +3508,7 @@ void TouchInputMapper::preparePointerGestures(nsecs_t when,
|
|||||||
moveSpotsLocked();
|
moveSpotsLocked();
|
||||||
}
|
}
|
||||||
} else if (isPointerDown(mCurrentTouch.buttonState)) {
|
} else if (isPointerDown(mCurrentTouch.buttonState)) {
|
||||||
// Case 2: Button is pressed. (CLICK_OR_DRAG)
|
// Case 2: Button is pressed. (BUTTON_CLICK_OR_DRAG)
|
||||||
// The pointer follows the active touch point.
|
// The pointer follows the active touch point.
|
||||||
// Emit DOWN, MOVE, UP events at the pointer location.
|
// Emit DOWN, MOVE, UP events at the pointer location.
|
||||||
//
|
//
|
||||||
@ -3482,11 +3522,11 @@ void TouchInputMapper::preparePointerGestures(nsecs_t when,
|
|||||||
// finger to drag then the active pointer should switch to the finger that is
|
// finger to drag then the active pointer should switch to the finger that is
|
||||||
// being dragged.
|
// being dragged.
|
||||||
#if DEBUG_GESTURES
|
#if DEBUG_GESTURES
|
||||||
LOGD("Gestures: CLICK_OR_DRAG activeTouchId=%d, "
|
LOGD("Gestures: BUTTON_CLICK_OR_DRAG activeTouchId=%d, "
|
||||||
"currentTouchPointerCount=%d", activeTouchId, mCurrentTouch.pointerCount);
|
"currentTouchPointerCount=%d", activeTouchId, mCurrentTouch.pointerCount);
|
||||||
#endif
|
#endif
|
||||||
// Reset state when just starting.
|
// Reset state when just starting.
|
||||||
if (mPointerGesture.lastGestureMode != PointerGesture::CLICK_OR_DRAG) {
|
if (mPointerGesture.lastGestureMode != PointerGesture::BUTTON_CLICK_OR_DRAG) {
|
||||||
*outFinishPreviousGesture = true;
|
*outFinishPreviousGesture = true;
|
||||||
mPointerGesture.activeGestureId = 0;
|
mPointerGesture.activeGestureId = 0;
|
||||||
}
|
}
|
||||||
@ -3512,7 +3552,7 @@ void TouchInputMapper::preparePointerGestures(nsecs_t when,
|
|||||||
mPointerGesture.activeTouchId = activeTouchId = bestId;
|
mPointerGesture.activeTouchId = activeTouchId = bestId;
|
||||||
activeTouchChanged = true;
|
activeTouchChanged = true;
|
||||||
#if DEBUG_GESTURES
|
#if DEBUG_GESTURES
|
||||||
LOGD("Gestures: CLICK_OR_DRAG switched pointers, "
|
LOGD("Gestures: BUTTON_CLICK_OR_DRAG switched pointers, "
|
||||||
"bestId=%d, bestSpeed=%0.3f", bestId, bestSpeed);
|
"bestId=%d, bestSpeed=%0.3f", bestId, bestSpeed);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -3538,7 +3578,7 @@ void TouchInputMapper::preparePointerGestures(nsecs_t when,
|
|||||||
float x, y;
|
float x, y;
|
||||||
mPointerController->getPosition(&x, &y);
|
mPointerController->getPosition(&x, &y);
|
||||||
|
|
||||||
mPointerGesture.currentGestureMode = PointerGesture::CLICK_OR_DRAG;
|
mPointerGesture.currentGestureMode = PointerGesture::BUTTON_CLICK_OR_DRAG;
|
||||||
mPointerGesture.currentGestureIdBits.clear();
|
mPointerGesture.currentGestureIdBits.clear();
|
||||||
mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
|
mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
|
||||||
mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
|
mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
|
||||||
@ -3575,11 +3615,12 @@ void TouchInputMapper::preparePointerGestures(nsecs_t when,
|
|||||||
// Case 3. No fingers down and button is not pressed. (NEUTRAL)
|
// Case 3. No fingers down and button is not pressed. (NEUTRAL)
|
||||||
*outFinishPreviousGesture = true;
|
*outFinishPreviousGesture = true;
|
||||||
|
|
||||||
// Watch for taps coming out of HOVER mode.
|
// Watch for taps coming out of HOVER or TAP_DRAG mode.
|
||||||
bool tapped = false;
|
bool tapped = false;
|
||||||
if (mPointerGesture.lastGestureMode == PointerGesture::HOVER
|
if ((mPointerGesture.lastGestureMode == PointerGesture::HOVER
|
||||||
|
|| mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG)
|
||||||
&& mLastTouch.pointerCount == 1) {
|
&& mLastTouch.pointerCount == 1) {
|
||||||
if (when <= mPointerGesture.tapTime + TAP_INTERVAL) {
|
if (when <= mPointerGesture.tapDownTime + TAP_INTERVAL) {
|
||||||
float x, y;
|
float x, y;
|
||||||
mPointerController->getPosition(&x, &y);
|
mPointerController->getPosition(&x, &y);
|
||||||
if (fabs(x - mPointerGesture.tapX) <= TAP_SLOP
|
if (fabs(x - mPointerGesture.tapX) <= TAP_SLOP
|
||||||
@ -3587,6 +3628,10 @@ void TouchInputMapper::preparePointerGestures(nsecs_t when,
|
|||||||
#if DEBUG_GESTURES
|
#if DEBUG_GESTURES
|
||||||
LOGD("Gestures: TAP");
|
LOGD("Gestures: TAP");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
mPointerGesture.tapUpTime = when;
|
||||||
|
getContext()->requestTimeoutAtTime(when + TAP_DRAG_INTERVAL);
|
||||||
|
|
||||||
mPointerGesture.activeGestureId = 0;
|
mPointerGesture.activeGestureId = 0;
|
||||||
mPointerGesture.currentGestureMode = PointerGesture::TAP;
|
mPointerGesture.currentGestureMode = PointerGesture::TAP;
|
||||||
mPointerGesture.currentGestureIdBits.clear();
|
mPointerGesture.currentGestureIdBits.clear();
|
||||||
@ -3603,7 +3648,6 @@ void TouchInputMapper::preparePointerGestures(nsecs_t when,
|
|||||||
AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
|
AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
|
||||||
|
|
||||||
mPointerController->setButtonState(BUTTON_STATE_PRIMARY);
|
mPointerController->setButtonState(BUTTON_STATE_PRIMARY);
|
||||||
mPointerController->setButtonState(0);
|
|
||||||
|
|
||||||
if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
|
if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
|
||||||
mPointerGesture.spotGesture = PointerControllerInterface::SPOT_GESTURE_TAP;
|
mPointerGesture.spotGesture = PointerControllerInterface::SPOT_GESTURE_TAP;
|
||||||
@ -3624,8 +3668,8 @@ void TouchInputMapper::preparePointerGestures(nsecs_t when,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#if DEBUG_GESTURES
|
#if DEBUG_GESTURES
|
||||||
LOGD("Gestures: Not a TAP, delay=%lld",
|
LOGD("Gestures: Not a TAP, %0.3fms since down",
|
||||||
when - mPointerGesture.tapTime);
|
(when - mPointerGesture.tapDownTime) * 0.000001f);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3647,14 +3691,36 @@ void TouchInputMapper::preparePointerGestures(nsecs_t when,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (mCurrentTouch.pointerCount == 1) {
|
} else if (mCurrentTouch.pointerCount == 1) {
|
||||||
// Case 4. Exactly one finger down, button is not pressed. (HOVER)
|
// Case 4. Exactly one finger down, button is not pressed. (HOVER or TAP_DRAG)
|
||||||
// The pointer follows the active touch point.
|
// The pointer follows the active touch point.
|
||||||
// Emit HOVER_MOVE events at the pointer location.
|
// When in HOVER, emit HOVER_MOVE events at the pointer location.
|
||||||
assert(activeTouchId >= 0);
|
// When in TAP_DRAG, emit MOVE events at the pointer location.
|
||||||
|
LOG_ASSERT(activeTouchId >= 0);
|
||||||
|
|
||||||
|
mPointerGesture.currentGestureMode = PointerGesture::HOVER;
|
||||||
|
if (mPointerGesture.lastGestureMode == PointerGesture::TAP) {
|
||||||
|
if (when <= mPointerGesture.tapUpTime + TAP_DRAG_INTERVAL) {
|
||||||
|
float x, y;
|
||||||
|
mPointerController->getPosition(&x, &y);
|
||||||
|
if (fabs(x - mPointerGesture.tapX) <= TAP_SLOP
|
||||||
|
&& fabs(y - mPointerGesture.tapY) <= TAP_SLOP) {
|
||||||
|
mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG;
|
||||||
|
} else {
|
||||||
#if DEBUG_GESTURES
|
#if DEBUG_GESTURES
|
||||||
LOGD("Gestures: HOVER");
|
LOGD("Gestures: Not a TAP_DRAG, deltaX=%f, deltaY=%f",
|
||||||
|
x - mPointerGesture.tapX,
|
||||||
|
y - mPointerGesture.tapY);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
#if DEBUG_GESTURES
|
||||||
|
LOGD("Gestures: Not a TAP_DRAG, %0.3fms time since up",
|
||||||
|
(when - mPointerGesture.tapUpTime) * 0.000001f);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
} else if (mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG) {
|
||||||
|
mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG;
|
||||||
|
}
|
||||||
|
|
||||||
if (mLastTouch.idBits.hasBit(activeTouchId)) {
|
if (mLastTouch.idBits.hasBit(activeTouchId)) {
|
||||||
const PointerData& currentPointer =
|
const PointerData& currentPointer =
|
||||||
@ -3667,35 +3733,49 @@ void TouchInputMapper::preparePointerGestures(nsecs_t when,
|
|||||||
* mLocked.pointerGestureYMovementScale;
|
* mLocked.pointerGestureYMovementScale;
|
||||||
|
|
||||||
// Move the pointer using a relative motion.
|
// Move the pointer using a relative motion.
|
||||||
// When using spots, the hover will occur at the position of the anchor spot.
|
// When using spots, the hover or drag will occur at the position of the anchor spot.
|
||||||
mPointerController->move(deltaX, deltaY);
|
mPointerController->move(deltaX, deltaY);
|
||||||
}
|
}
|
||||||
|
|
||||||
*outFinishPreviousGesture = true;
|
bool down;
|
||||||
mPointerGesture.activeGestureId = 0;
|
if (mPointerGesture.currentGestureMode == PointerGesture::TAP_DRAG) {
|
||||||
|
#if DEBUG_GESTURES
|
||||||
|
LOGD("Gestures: TAP_DRAG");
|
||||||
|
#endif
|
||||||
|
down = true;
|
||||||
|
} else {
|
||||||
|
#if DEBUG_GESTURES
|
||||||
|
LOGD("Gestures: HOVER");
|
||||||
|
#endif
|
||||||
|
*outFinishPreviousGesture = true;
|
||||||
|
mPointerGesture.activeGestureId = 0;
|
||||||
|
down = false;
|
||||||
|
}
|
||||||
|
|
||||||
float x, y;
|
float x, y;
|
||||||
mPointerController->getPosition(&x, &y);
|
mPointerController->getPosition(&x, &y);
|
||||||
|
|
||||||
mPointerGesture.currentGestureMode = PointerGesture::HOVER;
|
|
||||||
mPointerGesture.currentGestureIdBits.clear();
|
mPointerGesture.currentGestureIdBits.clear();
|
||||||
mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
|
mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
|
||||||
mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
|
mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
|
||||||
mPointerGesture.currentGestureCoords[0].clear();
|
mPointerGesture.currentGestureCoords[0].clear();
|
||||||
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
|
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
|
||||||
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
|
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
|
||||||
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 0.0f);
|
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
|
||||||
|
down ? 1.0f : 0.0f);
|
||||||
|
|
||||||
|
mPointerController->setButtonState(down ? BUTTON_STATE_PRIMARY : 0);
|
||||||
|
|
||||||
if (mLastTouch.pointerCount == 0 && mCurrentTouch.pointerCount != 0) {
|
if (mLastTouch.pointerCount == 0 && mCurrentTouch.pointerCount != 0) {
|
||||||
mPointerGesture.tapTime = when;
|
mPointerGesture.resetTap();
|
||||||
|
mPointerGesture.tapDownTime = when;
|
||||||
mPointerGesture.tapX = x;
|
mPointerGesture.tapX = x;
|
||||||
mPointerGesture.tapY = y;
|
mPointerGesture.tapY = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
mPointerController->setButtonState(0);
|
|
||||||
|
|
||||||
if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
|
if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
|
||||||
mPointerGesture.spotGesture = PointerControllerInterface::SPOT_GESTURE_HOVER;
|
mPointerGesture.spotGesture = down ? PointerControllerInterface::SPOT_GESTURE_DRAG
|
||||||
|
: PointerControllerInterface::SPOT_GESTURE_HOVER;
|
||||||
mPointerGesture.spotIdBits.clear();
|
mPointerGesture.spotIdBits.clear();
|
||||||
mPointerGesture.spotIdBits.markBit(activeTouchId);
|
mPointerGesture.spotIdBits.markBit(activeTouchId);
|
||||||
mPointerGesture.spotIdToIndex[activeTouchId] = 0;
|
mPointerGesture.spotIdToIndex[activeTouchId] = 0;
|
||||||
@ -4098,6 +4178,7 @@ void TouchInputMapper::preparePointerGestures(nsecs_t when,
|
|||||||
coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
|
coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TouchInputMapper::moveSpotsLocked() {
|
void TouchInputMapper::moveSpotsLocked() {
|
||||||
|
@ -570,6 +570,7 @@ public:
|
|||||||
const int32_t* keyCodes, uint8_t* outFlags);
|
const int32_t* keyCodes, uint8_t* outFlags);
|
||||||
|
|
||||||
virtual void fadePointer();
|
virtual void fadePointer();
|
||||||
|
virtual void timeoutExpired(nsecs_t when);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Mutex mLock;
|
Mutex mLock;
|
||||||
@ -935,10 +936,15 @@ private:
|
|||||||
// Emits DOWN and UP events at the pointer location.
|
// Emits DOWN and UP events at the pointer location.
|
||||||
TAP,
|
TAP,
|
||||||
|
|
||||||
|
// Exactly one finger dragging following a tap.
|
||||||
|
// Pointer follows the active finger.
|
||||||
|
// Emits DOWN, MOVE and UP events at the pointer location.
|
||||||
|
TAP_DRAG,
|
||||||
|
|
||||||
// Button is pressed.
|
// Button is pressed.
|
||||||
// Pointer follows the active finger if there is one. Other fingers are ignored.
|
// Pointer follows the active finger if there is one. Other fingers are ignored.
|
||||||
// Emits DOWN, MOVE and UP events at the pointer location.
|
// Emits DOWN, MOVE and UP events at the pointer location.
|
||||||
CLICK_OR_DRAG,
|
BUTTON_CLICK_OR_DRAG,
|
||||||
|
|
||||||
// Exactly one finger, button is not pressed.
|
// Exactly one finger, button is not pressed.
|
||||||
// Pointer follows the active finger.
|
// Pointer follows the active finger.
|
||||||
@ -997,8 +1003,11 @@ private:
|
|||||||
// Time the pointer gesture last went down.
|
// Time the pointer gesture last went down.
|
||||||
nsecs_t downTime;
|
nsecs_t downTime;
|
||||||
|
|
||||||
// Time we started waiting for a tap gesture.
|
// Time when the pointer went down for a TAP.
|
||||||
nsecs_t tapTime;
|
nsecs_t tapDownTime;
|
||||||
|
|
||||||
|
// Time when the pointer went up for a TAP.
|
||||||
|
nsecs_t tapUpTime;
|
||||||
|
|
||||||
// Location of initial tap.
|
// Location of initial tap.
|
||||||
float tapX, tapY;
|
float tapX, tapY;
|
||||||
@ -1030,12 +1039,13 @@ private:
|
|||||||
spotIdBits.clear();
|
spotIdBits.clear();
|
||||||
downTime = 0;
|
downTime = 0;
|
||||||
velocityTracker.clear();
|
velocityTracker.clear();
|
||||||
resetTapTime();
|
resetTap();
|
||||||
resetQuietTime();
|
resetQuietTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetTapTime() {
|
void resetTap() {
|
||||||
tapTime = LLONG_MIN;
|
tapDownTime = LLONG_MIN;
|
||||||
|
tapUpTime = LLONG_MIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetQuietTime() {
|
void resetQuietTime() {
|
||||||
@ -1048,9 +1058,9 @@ private:
|
|||||||
TouchResult consumeOffScreenTouches(nsecs_t when, uint32_t policyFlags);
|
TouchResult consumeOffScreenTouches(nsecs_t when, uint32_t policyFlags);
|
||||||
void dispatchTouches(nsecs_t when, uint32_t policyFlags);
|
void dispatchTouches(nsecs_t when, uint32_t policyFlags);
|
||||||
void prepareTouches(int32_t* outEdgeFlags, float* outXPrecision, float* outYPrecision);
|
void prepareTouches(int32_t* outEdgeFlags, float* outXPrecision, float* outYPrecision);
|
||||||
void dispatchPointerGestures(nsecs_t when, uint32_t policyFlags);
|
void dispatchPointerGestures(nsecs_t when, uint32_t policyFlags, bool isTimeout);
|
||||||
void preparePointerGestures(nsecs_t when,
|
bool preparePointerGestures(nsecs_t when,
|
||||||
bool* outCancelPreviousGesture, bool* outFinishPreviousGesture);
|
bool* outCancelPreviousGesture, bool* outFinishPreviousGesture, bool isTimeout);
|
||||||
void moveSpotsLocked();
|
void moveSpotsLocked();
|
||||||
|
|
||||||
// Dispatches a motion event.
|
// Dispatches a motion event.
|
||||||
|
@ -91,6 +91,9 @@ public:
|
|||||||
// Tap at current location.
|
// Tap at current location.
|
||||||
// Briefly display one spot at the tapped location.
|
// Briefly display one spot at the tapped location.
|
||||||
SPOT_GESTURE_TAP,
|
SPOT_GESTURE_TAP,
|
||||||
|
// Drag at current location.
|
||||||
|
// Display spot at pressed location.
|
||||||
|
SPOT_GESTURE_DRAG,
|
||||||
// Button pressed but no finger is down.
|
// Button pressed but no finger is down.
|
||||||
// Display spot at pressed location.
|
// Display spot at pressed location.
|
||||||
SPOT_GESTURE_BUTTON_CLICK,
|
SPOT_GESTURE_BUTTON_CLICK,
|
||||||
|
Reference in New Issue
Block a user