author | Timothy Nikkel <tnikkel@gmail.com> |
Tue, 11 Aug 2020 09:08:06 +0000 | |
changeset 544365 | bd9655461cbce5a309ba79ec6ab5cb71855356b2 |
parent 544364 | 3555578b1b2542b0a1ec36a4446ae2f11b6e45a2 |
child 544366 | 5e401631f3ef750246698f5a3ebb1e608fd9a160 |
push id | 123992 |
push user | tnikkel@mozilla.com |
push date | Wed, 12 Aug 2020 07:00:48 +0000 |
treeherder | autoland@bd9655461cbc [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | kats |
bugs | 1658001 |
milestone | 81.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/widget/InputData.cpp +++ b/widget/InputData.cpp @@ -525,16 +525,17 @@ PinchGestureInput::PinchGestureInput( ScreenCoord aPreviousSpan, Modifiers aModifiers) : InputData(PINCHGESTURE_INPUT, aTime, aTimeStamp, aModifiers), mType(aType), mSource(aSource), mFocusPoint(aFocusPoint), mScreenOffset(aScreenOffset), mCurrentSpan(aCurrentSpan), mPreviousSpan(aPreviousSpan), + mLineOrPageDeltaY(0), mHandledByAPZ(false) {} bool PinchGestureInput::TransformToLocal( const ScreenToParentLayerMatrix4x4& aTransform) { Maybe<ParentLayerPoint> point = UntransformBy(aTransform, mFocusPoint); if (!point) { return false; } @@ -550,16 +551,26 @@ WidgetWheelEvent PinchGestureInput::ToWi wheelEvent.mTimeStamp = mTimeStamp; wheelEvent.mRefPoint = RoundedToInt(ViewAs<LayoutDevicePixel>( mFocusPoint, PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent)); wheelEvent.mButtons = 0; wheelEvent.mFlags.mHandledByAPZ = mHandledByAPZ; wheelEvent.mDeltaMode = WheelEvent_Binding::DOM_DELTA_PIXEL; + wheelEvent.mDeltaY = ComputeDeltaY(aWidget); + + wheelEvent.mLineOrPageDeltaY = mLineOrPageDeltaY; + + MOZ_ASSERT(mType == PINCHGESTURE_END || wheelEvent.mDeltaY != 0.0); + + return wheelEvent; +} + +double PinchGestureInput::ComputeDeltaY(nsIWidget* aWidget) const { #if defined(OS_MACOSX) // This converts the pinch gesture value to a fake wheel event that has the // control key pressed so that pages can implement custom pinch gesture // handling. It may seem strange that this doesn't use a wheel event with // the deltaZ property set, but this matches Chrome's behavior as described // at https://code.google.com/p/chromium/issues/detail?id=289887 // // The intent of the formula below is to produce numbers similar to Chrome's @@ -578,41 +589,49 @@ WidgetWheelEvent PinchGestureInput::ToWi // We want to set deltaY to |-100.0 * M * GetDefaultScaleInternal()| where M // is [event magnification] but [event magnification] is only available in the // macOS widget code so we have to reverse engineer from mCurrentSpan and // mPreviousSpan (which are derived from [event magnification]) to get it. // Specifically, we know |mCurrentSpan == 100.0| and |mPreviousSpan == 100.0 * // (1.0 - M)|. We can calculate deltaY by solving the mPreviousSpan equation // for M in terms of mPreviousSpan and plugging that into to the formula for // deltaY. - wheelEvent.mDeltaY = (mPreviousSpan - 100.0) * - (aWidget ? aWidget->GetDefaultScaleInternal() : 1.f); + return (mPreviousSpan - 100.0) * + (aWidget ? aWidget->GetDefaultScaleInternal() : 1.f); #else // This calculation is based on what the Windows widget code does. // Specifically, it creates a PinchGestureInput with |mCurrentSpan == 100.0 * // currentScale| and |mPreviousSpan == 100.0 * lastScale| where currentScale // is the scale from the current OS event and lastScale is the scale when the // previous OS event happened. On macOS [event magnification] is a relative // change in scale factor, ie if the scale factor changed from 1 to 1.1 it // will be 0.1, similarly if it changed from 1 to 0.9 it will be -0.1. To // calculate the relative scale change on Windows we would calculate |M = // currentScale - lastScale = (mCurrentSpan-mPreviousSpan)/100| and use the // same formula as the macOS code // (|-100.0 * M * GetDefaultScaleInternal()|). // XXX When we write the code for other platforms to do the same we'll need to // make sure this calculation is reasonable. - wheelEvent.mDeltaY = (mPreviousSpan - mCurrentSpan) * - (aWidget ? aWidget->GetDefaultScaleInternal() : 1.f); + return (mPreviousSpan - mCurrentSpan) * + (aWidget ? aWidget->GetDefaultScaleInternal() : 1.f); #endif +} - MOZ_ASSERT(mType == PINCHGESTURE_END || wheelEvent.mDeltaY != 0.0); - - return wheelEvent; +/* static */ gfx::IntPoint PinchGestureInput::GetIntegerDeltaForEvent( + bool aIsStart, float x, float y) { + static gfx::Point sAccumulator(0.0f, 0.0f); + if (aIsStart) { + sAccumulator = gfx::Point(0.0f, 0.0f); + } + sAccumulator.x += x; + sAccumulator.y += y; + return gfx::IntPoint(TakeLargestInt(&sAccumulator.x), + TakeLargestInt(&sAccumulator.y)); } TapGestureInput::TapGestureInput() : InputData(TAPGESTURE_INPUT), mType(TAPGESTURE_LONG) {} TapGestureInput::TapGestureInput(TapGestureType aType, uint32_t aTime, TimeStamp aTimeStamp, const ScreenIntPoint& aPoint,
--- a/widget/InputData.h +++ b/widget/InputData.h @@ -470,16 +470,20 @@ class PinchGestureInput : public InputDa const ExternalPoint& aScreenOffset, const ScreenPoint& aFocusPoint, ScreenCoord aCurrentSpan, ScreenCoord aPreviousSpan, Modifiers aModifiers); bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform); WidgetWheelEvent ToWidgetWheelEvent(nsIWidget* aWidget) const; + double ComputeDeltaY(nsIWidget* aWidget) const; + + static gfx::IntPoint GetIntegerDeltaForEvent(bool aIsStart, float x, float y); + // Warning, this class is serialized and sent over IPC. Any change to its // fields must be reflected in its ParamTraits<>, in nsGUIEventIPC.h PinchGestureType mType; // Some indication of the input device that generated this pinch gesture. PinchGestureSource mSource; // Center point of the pinch gesture. That is, if there are two fingers on the @@ -504,16 +508,24 @@ class PinchGestureInput : public InputDa // The distance between the touches responsible for the pinch gesture. 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. ScreenCoord mPreviousSpan; + // We accumulate (via GetIntegerDeltaForEvent) the deltaY that would be + // computed by ToWidgetWheelEvent, and then whenever we get a whole integer + // value we put it in mLineOrPageDeltaY. Since we only ever use deltaY we + // don't need a mLineOrPageDeltaX. This field is used to dispatch legacy mouse + // events which are only dispatched when the corresponding field on + // WidgetWheelEvent is non-zero. + int32_t mLineOrPageDeltaY; + bool mHandledByAPZ; }; /** * Encapsulation class for tap events. In general, these will be generated by * a gesture listener by looking at SingleTouchData/MultiTouchInput instances * and determining whether or not the user was trying to do a gesture. */
--- a/widget/nsGUIEventIPC.h +++ b/widget/nsGUIEventIPC.h @@ -1301,29 +1301,31 @@ struct ParamTraits<mozilla::PinchGesture WriteParam(aMsg, static_cast<const mozilla::InputData&>(aParam)); WriteParam(aMsg, aParam.mType); WriteParam(aMsg, aParam.mSource); WriteParam(aMsg, aParam.mScreenOffset); WriteParam(aMsg, aParam.mFocusPoint); WriteParam(aMsg, aParam.mLocalFocusPoint); WriteParam(aMsg, aParam.mCurrentSpan); WriteParam(aMsg, aParam.mPreviousSpan); + WriteParam(aMsg, aParam.mLineOrPageDeltaY); WriteParam(aMsg, aParam.mHandledByAPZ); } static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) { return ReadParam(aMsg, aIter, static_cast<mozilla::InputData*>(aResult)) && ReadParam(aMsg, aIter, &aResult->mType) && ReadParam(aMsg, aIter, &aResult->mSource) && ReadParam(aMsg, aIter, &aResult->mScreenOffset) && ReadParam(aMsg, aIter, &aResult->mFocusPoint) && ReadParam(aMsg, aIter, &aResult->mLocalFocusPoint) && ReadParam(aMsg, aIter, &aResult->mCurrentSpan) && ReadParam(aMsg, aIter, &aResult->mPreviousSpan) && + ReadParam(aMsg, aIter, &aResult->mLineOrPageDeltaY) && ReadParam(aMsg, aIter, &aResult->mHandledByAPZ); } }; template <> struct ParamTraits<mozilla::TapGestureInput::TapGestureType> : public ContiguousEnumSerializerInclusive< mozilla::TapGestureInput::TapGestureType,
--- a/widget/windows/DirectManipulationOwner.cpp +++ b/widget/windows/DirectManipulationOwner.cpp @@ -410,16 +410,20 @@ void DManipEventHandler::SendPinch(Phase eventIntervalTime, eventTimeStamp, screenOffset, position, 100.0 * ((aPhase == Phase::eEnd) ? 1.f : aScale), 100.0 * ((aPhase == Phase::eEnd) ? 1.f : mLastScale), mods}; + gfx::IntPoint lineOrPageDelta = PinchGestureInput::GetIntegerDeltaForEvent( + (aPhase == Phase::eStart), 0, event.ComputeDeltaY(mWindow)); + event.mLineOrPageDeltaY = lineOrPageDelta.y; + mWindow->SendAnAPZEvent(event); } void DManipEventHandler::SendPan(Phase aPhase, float x, float y, bool aIsInertia) { if (!mWindow) { return; }