mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1515774 - Use Screen pixels for gesture detection. r=botond
We currently use ParentLayer pixels in GestureEventListener, it should be Screen pixels because we care about physical distances and thresholds, not layer-relative ones. Differential Revision: https://phabricator.services.mozilla.com/D17042 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
6c95500b14
commit
186e2cc4ca
@ -1891,10 +1891,8 @@ void APZCTreeManager::SynthesizePinchGestureFromMouseWheel(
|
||||
ScreenPoint focusPoint = aWheelInput.mOrigin;
|
||||
|
||||
// Compute span values based on the wheel delta.
|
||||
// See the PinchGestureInput constructor called below for why
|
||||
// it's OK to use ParentLayer coordinates for the span values.
|
||||
ParentLayerCoord oldSpan = 100;
|
||||
ParentLayerCoord newSpan = oldSpan + aWheelInput.mDeltaY;
|
||||
ScreenCoord oldSpan = 100;
|
||||
ScreenCoord newSpan = oldSpan + aWheelInput.mDeltaY;
|
||||
|
||||
// There's no ambiguity as to the target for pinch gesture events.
|
||||
TargetConfirmationFlags confFlags{true};
|
||||
|
@ -1078,18 +1078,20 @@ nsEventStatus AsyncPanZoomController::HandleInputEvent(
|
||||
switch (aEvent.mInputType) {
|
||||
case MULTITOUCH_INPUT: {
|
||||
MultiTouchInput multiTouchInput = aEvent.AsMultiTouchInput();
|
||||
if (!multiTouchInput.TransformToLocal(aTransformToApzc)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
RefPtr<GestureEventListener> listener = GetGestureEventListener();
|
||||
if (listener) {
|
||||
// We only care about screen coordinates in the gesture listener,
|
||||
// so we don't bother transforming the event to parent layer coordinates
|
||||
rv = listener->HandleInputEvent(multiTouchInput);
|
||||
if (rv == nsEventStatus_eConsumeNoDefault) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
if (!multiTouchInput.TransformToLocal(aTransformToApzc)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
switch (multiTouchInput.mType) {
|
||||
case MultiTouchInput::MULTITOUCH_START:
|
||||
rv = OnTouchStart(multiTouchInput);
|
||||
@ -1192,7 +1194,8 @@ nsEventStatus AsyncPanZoomController::HandleGestureEvent(
|
||||
|
||||
switch (aEvent.mInputType) {
|
||||
case PINCHGESTURE_INPUT: {
|
||||
const PinchGestureInput& pinchGestureInput = aEvent.AsPinchGestureInput();
|
||||
PinchGestureInput pinchGestureInput = aEvent.AsPinchGestureInput();
|
||||
pinchGestureInput.TransformToLocal(GetTransformToThis());
|
||||
switch (pinchGestureInput.mType) {
|
||||
case PinchGestureInput::PINCHGESTURE_START:
|
||||
rv = OnScaleBegin(pinchGestureInput);
|
||||
@ -1207,7 +1210,8 @@ nsEventStatus AsyncPanZoomController::HandleGestureEvent(
|
||||
break;
|
||||
}
|
||||
case TAPGESTURE_INPUT: {
|
||||
const TapGestureInput& tapGestureInput = aEvent.AsTapGestureInput();
|
||||
TapGestureInput tapGestureInput = aEvent.AsTapGestureInput();
|
||||
tapGestureInput.TransformToLocal(GetTransformToThis());
|
||||
switch (tapGestureInput.mType) {
|
||||
case TapGestureInput::TAPGESTURE_LONG:
|
||||
rv = OnLongPress(tapGestureInput);
|
||||
|
@ -38,24 +38,24 @@ static const float ONE_TOUCH_PINCH_SPEED = 0.005f;
|
||||
|
||||
static bool sLongTapEnabled = true;
|
||||
|
||||
ParentLayerPoint GetCurrentFocus(const MultiTouchInput& aEvent) {
|
||||
const ParentLayerPoint& firstTouch = aEvent.mTouches[0].mLocalScreenPoint;
|
||||
const ParentLayerPoint& secondTouch = aEvent.mTouches[1].mLocalScreenPoint;
|
||||
ScreenPoint GetCurrentFocus(const MultiTouchInput& aEvent) {
|
||||
const ScreenPoint& firstTouch = aEvent.mTouches[0].mScreenPoint;
|
||||
const ScreenPoint& secondTouch = aEvent.mTouches[1].mScreenPoint;
|
||||
return (firstTouch + secondTouch) / 2;
|
||||
}
|
||||
|
||||
ParentLayerCoord GetCurrentSpan(const MultiTouchInput& aEvent) {
|
||||
const ParentLayerPoint& firstTouch = aEvent.mTouches[0].mLocalScreenPoint;
|
||||
const ParentLayerPoint& secondTouch = aEvent.mTouches[1].mLocalScreenPoint;
|
||||
ParentLayerPoint delta = secondTouch - firstTouch;
|
||||
ScreenCoord GetCurrentSpan(const MultiTouchInput& aEvent) {
|
||||
const ScreenPoint& firstTouch = aEvent.mTouches[0].mScreenPoint;
|
||||
const ScreenPoint& secondTouch = aEvent.mTouches[1].mScreenPoint;
|
||||
ScreenPoint delta = secondTouch - firstTouch;
|
||||
return delta.Length();
|
||||
}
|
||||
|
||||
ParentLayerCoord GestureEventListener::GetYSpanFromGestureStartPoint() {
|
||||
ScreenCoord GestureEventListener::GetYSpanFromGestureStartPoint() {
|
||||
// use the position that began the one-touch-pinch gesture rather
|
||||
// mTouchStartPosition
|
||||
const ParentLayerPoint start = mOneTouchPinchStartPosition;
|
||||
const ParentLayerPoint& current = mTouches[0].mLocalScreenPoint;
|
||||
const ScreenPoint start = mOneTouchPinchStartPosition;
|
||||
const ScreenPoint& current = mTouches[0].mScreenPoint;
|
||||
return current.y - start.y;
|
||||
}
|
||||
|
||||
@ -157,7 +157,7 @@ nsEventStatus GestureEventListener::HandleInputTouchSingleStart() {
|
||||
switch (mState) {
|
||||
case GESTURE_NONE:
|
||||
SetState(GESTURE_FIRST_SINGLE_TOUCH_DOWN);
|
||||
mTouchStartPosition = mLastTouchInput.mTouches[0].mLocalScreenPoint;
|
||||
mTouchStartPosition = mLastTouchInput.mTouches[0].mScreenPoint;
|
||||
|
||||
if (sLongTapEnabled) {
|
||||
CreateLongTapTimeoutTask();
|
||||
@ -176,7 +176,7 @@ nsEventStatus GestureEventListener::HandleInputTouchSingleStart() {
|
||||
// Otherwise, reset the touch start position so that, if this turns into
|
||||
// a one-touch-pinch gesture, it uses the second tap's down position as
|
||||
// the focus, rather than the first tap's.
|
||||
mTouchStartPosition = mLastTouchInput.mTouches[0].mLocalScreenPoint;
|
||||
mTouchStartPosition = mLastTouchInput.mTouches[0].mScreenPoint;
|
||||
SetState(GESTURE_SECOND_SINGLE_TOUCH_DOWN);
|
||||
}
|
||||
break;
|
||||
@ -240,10 +240,9 @@ nsEventStatus GestureEventListener::HandleInputTouchMultiStart() {
|
||||
}
|
||||
|
||||
bool GestureEventListener::MoveDistanceExceeds(ScreenCoord aThreshold) const {
|
||||
const ParentLayerPoint start = mLastTouchInput.mTouches[0].mLocalScreenPoint;
|
||||
ParentLayerPoint delta = start - mTouchStartPosition;
|
||||
ScreenPoint screenDelta =
|
||||
mAsyncPanZoomController->ToScreenCoordinates(delta, start);
|
||||
ScreenPoint(mLastTouchInput.mTouches[0].mScreenPoint) -
|
||||
mTouchStartPosition;
|
||||
return (screenDelta.Length() > aThreshold);
|
||||
}
|
||||
|
||||
@ -304,12 +303,11 @@ nsEventStatus GestureEventListener::HandleInputTouchMove() {
|
||||
|
||||
SetState(GESTURE_ONE_TOUCH_PINCH);
|
||||
|
||||
ParentLayerCoord currentSpan = 1.0f;
|
||||
ParentLayerPoint currentFocus = mTouchStartPosition;
|
||||
ScreenCoord currentSpan = 1.0f;
|
||||
ScreenPoint currentFocus = mTouchStartPosition;
|
||||
|
||||
// save the position that the one-touch-pinch gesture actually begins
|
||||
mOneTouchPinchStartPosition =
|
||||
mLastTouchInput.mTouches[0].mLocalScreenPoint;
|
||||
mOneTouchPinchStartPosition = mLastTouchInput.mTouches[0].mScreenPoint;
|
||||
|
||||
PinchGestureInput pinchEvent(
|
||||
PinchGestureInput::PINCHGESTURE_START, mLastTouchInput.mTime,
|
||||
@ -332,8 +330,8 @@ nsEventStatus GestureEventListener::HandleInputTouchMove() {
|
||||
break;
|
||||
}
|
||||
|
||||
ParentLayerCoord currentSpan = GetCurrentSpan(mLastTouchInput);
|
||||
ParentLayerPoint currentFocus = GetCurrentFocus(mLastTouchInput);
|
||||
ScreenCoord currentSpan = GetCurrentSpan(mLastTouchInput);
|
||||
ScreenPoint currentFocus = GetCurrentFocus(mLastTouchInput);
|
||||
|
||||
mSpanChange += fabsf(currentSpan - mPreviousSpan);
|
||||
mFocusChange += (currentFocus - mPreviousFocus).Length();
|
||||
@ -366,7 +364,7 @@ nsEventStatus GestureEventListener::HandleInputTouchMove() {
|
||||
break;
|
||||
}
|
||||
|
||||
ParentLayerCoord currentSpan = GetCurrentSpan(mLastTouchInput);
|
||||
ScreenCoord currentSpan = GetCurrentSpan(mLastTouchInput);
|
||||
|
||||
PinchGestureInput pinchEvent(
|
||||
PinchGestureInput::PINCHGESTURE_SCALE, mLastTouchInput.mTime,
|
||||
@ -380,10 +378,10 @@ nsEventStatus GestureEventListener::HandleInputTouchMove() {
|
||||
}
|
||||
|
||||
case GESTURE_ONE_TOUCH_PINCH: {
|
||||
ParentLayerCoord currentSpan = GetYSpanFromGestureStartPoint();
|
||||
ScreenCoord currentSpan = GetYSpanFromGestureStartPoint();
|
||||
float effectiveSpan =
|
||||
1.0f + (fabsf(currentSpan.value) * ONE_TOUCH_PINCH_SPEED);
|
||||
ParentLayerPoint currentFocus = mTouchStartPosition;
|
||||
ScreenPoint currentFocus = mTouchStartPosition;
|
||||
|
||||
// Invert zoom.
|
||||
if (currentSpan.value < 0) {
|
||||
@ -468,11 +466,11 @@ nsEventStatus GestureEventListener::HandleInputTouchEnd() {
|
||||
case GESTURE_PINCH:
|
||||
if (mTouches.Length() < 2) {
|
||||
SetState(GESTURE_NONE);
|
||||
ParentLayerPoint point = PinchGestureInput::BothFingersLifted();
|
||||
ScreenPoint point = PinchGestureInput::BothFingersLifted<ScreenPixel>();
|
||||
if (mTouches.Length() == 1) {
|
||||
// As user still keeps one finger down the event's focus point should
|
||||
// contain meaningful data.
|
||||
point = mTouches[0].mLocalScreenPoint;
|
||||
point = mTouches[0].mScreenPoint;
|
||||
}
|
||||
PinchGestureInput pinchEvent(PinchGestureInput::PINCHGESTURE_END,
|
||||
mLastTouchInput.mTime,
|
||||
@ -487,7 +485,7 @@ nsEventStatus GestureEventListener::HandleInputTouchEnd() {
|
||||
|
||||
case GESTURE_ONE_TOUCH_PINCH: {
|
||||
SetState(GESTURE_NONE);
|
||||
ParentLayerPoint point(-1, -1);
|
||||
ScreenPoint point = PinchGestureInput::BothFingersLifted<ScreenPixel>();
|
||||
PinchGestureInput pinchEvent(PinchGestureInput::PINCHGESTURE_END,
|
||||
mLastTouchInput.mTime,
|
||||
mLastTouchInput.mTimeStamp, point, 1.0f,
|
||||
|
@ -156,7 +156,7 @@ class GestureEventListener final {
|
||||
* Returns current vertical span, counting from the where the gesture first
|
||||
* began (after a brief delay detecting the gesture from first touch).
|
||||
*/
|
||||
ParentLayerCoord GetYSpanFromGestureStartPoint();
|
||||
ScreenCoord GetYSpanFromGestureStartPoint();
|
||||
|
||||
/**
|
||||
* Do actual state transition and reset substates.
|
||||
@ -185,17 +185,17 @@ class GestureEventListener final {
|
||||
* out we are compared to our original pinch span. Note that this does _not_
|
||||
* continue to be updated once we jump into the |GESTURE_PINCH| state.
|
||||
*/
|
||||
ParentLayerCoord mSpanChange;
|
||||
ScreenCoord mSpanChange;
|
||||
|
||||
/**
|
||||
* Previous span calculated for the purposes of setting inside a
|
||||
* PinchGestureInput.
|
||||
*/
|
||||
ParentLayerCoord mPreviousSpan;
|
||||
ScreenCoord mPreviousSpan;
|
||||
|
||||
/* Properties similar to mSpanChange and mPreviousSpan, but for the focus */
|
||||
ParentLayerCoord mFocusChange;
|
||||
ParentLayerPoint mPreviousFocus;
|
||||
ScreenCoord mFocusChange;
|
||||
ScreenPoint mPreviousFocus;
|
||||
|
||||
/**
|
||||
* Cached copy of the last touch input.
|
||||
@ -219,7 +219,7 @@ class GestureEventListener final {
|
||||
* is calculated from, instead of starting at 1.0 when the threshold gets
|
||||
* passed.
|
||||
*/
|
||||
ParentLayerPoint mOneTouchPinchStartPosition;
|
||||
ScreenPoint mOneTouchPinchStartPosition;
|
||||
|
||||
/**
|
||||
* Position of the last touch starting. This is only valid during an attempt
|
||||
@ -230,7 +230,7 @@ class GestureEventListener final {
|
||||
* or GESTURE_SECOND_SINGLE_TOUCH_DOWN then we're certain the gesture is
|
||||
* not tap.
|
||||
*/
|
||||
ParentLayerPoint mTouchStartPosition;
|
||||
ScreenPoint mTouchStartPosition;
|
||||
|
||||
/**
|
||||
* Task used to timeout a long tap. This gets posted to the UI thread such
|
||||
|
@ -31,10 +31,8 @@
|
||||
PinchGestureInput CreatePinchGestureInput(
|
||||
PinchGestureInput::PinchGestureType aType, const ScreenPoint& aFocus,
|
||||
float aCurrentSpan, float aPreviousSpan) {
|
||||
ParentLayerPoint localFocus(aFocus.x, aFocus.y);
|
||||
PinchGestureInput result(aType, 0, TimeStamp(), localFocus, aCurrentSpan,
|
||||
PinchGestureInput result(aType, 0, TimeStamp(), aFocus, aCurrentSpan,
|
||||
aPreviousSpan, 0);
|
||||
result.mFocusPoint = aFocus;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -549,8 +549,8 @@ PinchGestureInput::PinchGestureInput()
|
||||
PinchGestureInput::PinchGestureInput(PinchGestureType aType, uint32_t aTime,
|
||||
TimeStamp aTimeStamp,
|
||||
const ScreenPoint& aFocusPoint,
|
||||
ParentLayerCoord aCurrentSpan,
|
||||
ParentLayerCoord aPreviousSpan,
|
||||
ScreenCoord aCurrentSpan,
|
||||
ScreenCoord aPreviousSpan,
|
||||
Modifiers aModifiers)
|
||||
: InputData(PINCHGESTURE_INPUT, aTime, aTimeStamp, aModifiers),
|
||||
mType(aType),
|
||||
@ -558,18 +558,6 @@ PinchGestureInput::PinchGestureInput(PinchGestureType aType, uint32_t aTime,
|
||||
mCurrentSpan(aCurrentSpan),
|
||||
mPreviousSpan(aPreviousSpan) {}
|
||||
|
||||
PinchGestureInput::PinchGestureInput(PinchGestureType aType, uint32_t aTime,
|
||||
TimeStamp aTimeStamp,
|
||||
const ParentLayerPoint& aLocalFocusPoint,
|
||||
ParentLayerCoord aCurrentSpan,
|
||||
ParentLayerCoord aPreviousSpan,
|
||||
Modifiers aModifiers)
|
||||
: InputData(PINCHGESTURE_INPUT, aTime, aTimeStamp, aModifiers),
|
||||
mType(aType),
|
||||
mLocalFocusPoint(aLocalFocusPoint),
|
||||
mCurrentSpan(aCurrentSpan),
|
||||
mPreviousSpan(aPreviousSpan) {}
|
||||
|
||||
bool PinchGestureInput::TransformToLocal(
|
||||
const ScreenToParentLayerMatrix4x4& aTransform) {
|
||||
if (mFocusPoint == BothFingersLifted<ScreenPixel>()) {
|
||||
|
@ -414,24 +414,10 @@ class PinchGestureInput : public InputData {
|
||||
// clang-format on
|
||||
|
||||
// Construct a pinch gesture from a Screen point.
|
||||
// (Technically, we should take the span values in Screen pixels as well,
|
||||
// but that would require also storing them in Screen pixels and then
|
||||
// converting them in TransformToLocal() like the focus point. Since pinch
|
||||
// gesture events are processed by the root content APZC, the only transform
|
||||
// between Screen and ParentLayer pixels should be a translation, which is
|
||||
// irrelevant to span values, so we don't bother.)
|
||||
PinchGestureInput(PinchGestureType aType, uint32_t aTime,
|
||||
TimeStamp aTimeStamp, const ScreenPoint& aFocusPoint,
|
||||
ParentLayerCoord aCurrentSpan,
|
||||
ParentLayerCoord aPreviousSpan, Modifiers aModifiers);
|
||||
|
||||
// Construct a pinch gesture from a ParentLayer point.
|
||||
// mFocusPoint remains (0,0) unless it's set later.
|
||||
PinchGestureInput(PinchGestureType aType, uint32_t aTime,
|
||||
TimeStamp aTimeStamp,
|
||||
const ParentLayerPoint& aLocalFocusPoint,
|
||||
ParentLayerCoord aCurrentSpan,
|
||||
ParentLayerCoord aPreviousSpan, Modifiers aModifiers);
|
||||
ScreenCoord aCurrentSpan, ScreenCoord aPreviousSpan,
|
||||
Modifiers aModifiers);
|
||||
|
||||
bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform);
|
||||
|
||||
@ -454,12 +440,12 @@ class PinchGestureInput : public InputData {
|
||||
ParentLayerPoint mLocalFocusPoint;
|
||||
|
||||
// The distance between the touches responsible for the pinch gesture.
|
||||
ParentLayerCoord mCurrentSpan;
|
||||
ScreenCoord mCurrentSpan;
|
||||
|
||||
// The previous |mCurrentSpan| in the PinchGestureInput preceding this one.
|
||||
// This is only really relevant during a PINCHGESTURE_SCALE because when it is
|
||||
// of this type then there must have been a history of spans.
|
||||
ParentLayerCoord mPreviousSpan;
|
||||
ScreenCoord mPreviousSpan;
|
||||
|
||||
// A special value for mFocusPoint used in PINCHGESTURE_END events to
|
||||
// indicate that both fingers have been lifted. If only one finger has
|
||||
|
Loading…
Reference in New Issue
Block a user