diff --git a/widget/InputData.cpp b/widget/InputData.cpp index 0d7e701f0396..36ba907c53a6 100644 --- a/widget/InputData.cpp +++ b/widget/InputData.cpp @@ -146,8 +146,11 @@ void MultiTouchInput::Translate(const ScreenPoint& aTranslation) { const int32_t xTranslation = (int32_t)(aTranslation.x + 0.5f); const int32_t yTranslation = (int32_t)(aTranslation.y + 0.5f); - for (auto iter = mTouches.begin(); iter != mTouches.end(); iter++) { - iter->mScreenPoint.MoveBy(xTranslation, yTranslation); + for (auto& touchData : mTouches) { + for (auto& historicalData : touchData.mHistoricalData) { + historicalData.mScreenPoint.MoveBy(xTranslation, yTranslation); + } + touchData.mScreenPoint.MoveBy(xTranslation, yTranslation); } } @@ -205,13 +208,21 @@ int32_t MultiTouchInput::IndexOfTouch(int32_t aTouchIdentifier) { bool MultiTouchInput::TransformToLocal( const ScreenToParentLayerMatrix4x4& aTransform) { - for (size_t i = 0; i < mTouches.Length(); i++) { + for (auto& touchData : mTouches) { + for (auto& historicalData : touchData.mHistoricalData) { + Maybe historicalPoint = + UntransformBy(aTransform, historicalData.mScreenPoint); + if (!historicalPoint) { + return false; + } + historicalData.mLocalScreenPoint = *historicalPoint; + } Maybe point = - UntransformBy(aTransform, mTouches[i].mScreenPoint); + UntransformBy(aTransform, touchData.mScreenPoint); if (!point) { return false; } - mTouches[i].mLocalScreenPoint = *point; + touchData.mLocalScreenPoint = *point; } return true; } diff --git a/widget/InputData.h b/widget/InputData.h index 4cbbd9e41aea..dc86550e05fa 100644 --- a/widget/InputData.h +++ b/widget/InputData.h @@ -149,6 +149,28 @@ class SingleTouchData { // Warning, this class is serialized and sent over IPC. Any change to its // fields must be reflected in its ParamTraits<>, in nsGUIEventIPC.h + // Historical data of this touch, which was coalesced into this event. + // Touch event coalescing can happen at the system level when the touch + // screen's sampling frequency is higher than the vsync rate, or when the + // UI thread is busy. When multiple "samples" of touch data are coalesced into + // one touch event, the touch event's regular position information is the + // information from the last sample. And the previous, "coalesced-away" + // samples are stored in mHistoricalData. + + struct HistoricalTouchData { + // The timestamp at which the information in this "sample" was originally + // sampled. + TimeStamp mTimeStamp; + + // The touch data of this historical sample. + ScreenIntPoint mScreenPoint; + ParentLayerPoint mLocalScreenPoint; + ScreenSize mRadius; + float mRotationAngle = 0.0f; + float mForce = 0.0f; + }; + CopyableTArray mHistoricalData; + // A unique number assigned to each SingleTouchData within a MultiTouchInput // so that they can be easily distinguished when handling a touch // start/move/end. diff --git a/widget/nsGUIEventIPC.h b/widget/nsGUIEventIPC.h index c41fbdb4625f..4e88abbc6b66 100644 --- a/widget/nsGUIEventIPC.h +++ b/widget/nsGUIEventIPC.h @@ -1124,11 +1124,36 @@ struct ParamTraits { } }; +template <> +struct ParamTraits { + typedef mozilla::SingleTouchData::HistoricalTouchData paramType; + + static void Write(Message* aMsg, const paramType& aParam) { + WriteParam(aMsg, aParam.mTimeStamp); + WriteParam(aMsg, aParam.mScreenPoint); + WriteParam(aMsg, aParam.mLocalScreenPoint); + WriteParam(aMsg, aParam.mRadius); + WriteParam(aMsg, aParam.mRotationAngle); + WriteParam(aMsg, aParam.mForce); + } + + static bool Read(const Message* aMsg, PickleIterator* aIter, + paramType* aResult) { + return (ReadParam(aMsg, aIter, &aResult->mTimeStamp) && + ReadParam(aMsg, aIter, &aResult->mScreenPoint) && + ReadParam(aMsg, aIter, &aResult->mLocalScreenPoint) && + ReadParam(aMsg, aIter, &aResult->mRadius) && + ReadParam(aMsg, aIter, &aResult->mRotationAngle) && + ReadParam(aMsg, aIter, &aResult->mForce)); + } +}; + template <> struct ParamTraits { typedef mozilla::SingleTouchData paramType; static void Write(Message* aMsg, const paramType& aParam) { + WriteParam(aMsg, aParam.mHistoricalData); WriteParam(aMsg, aParam.mIdentifier); WriteParam(aMsg, aParam.mScreenPoint); WriteParam(aMsg, aParam.mLocalScreenPoint); @@ -1139,7 +1164,8 @@ struct ParamTraits { static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) { - return (ReadParam(aMsg, aIter, &aResult->mIdentifier) && + return (ReadParam(aMsg, aIter, &aResult->mHistoricalData) && + ReadParam(aMsg, aIter, &aResult->mIdentifier) && ReadParam(aMsg, aIter, &aResult->mScreenPoint) && ReadParam(aMsg, aIter, &aResult->mLocalScreenPoint) && ReadParam(aMsg, aIter, &aResult->mRadius) &&