mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1121353 - Implement SynthesizeNativeTouchPoint in the gonk widget to allow injecting touch events into APZ. r=mwu
This commit is contained in:
parent
a4a3c0a4d7
commit
e116db3134
@ -664,8 +664,8 @@ interface nsIDOMWindowUtils : nsISupports {
|
||||
* drag - msg1-n:TOUCH_CONTACT (moving), msgn+1:TOUCH_REMOVE
|
||||
* hover drag - msg1-n:TOUCH_HOVER (moving), msgn+1:TOUCH_REMOVE
|
||||
*
|
||||
* Widget support: Windows 8.0+, Winrt/Win32. Other widgets will
|
||||
* throw.
|
||||
* Widget support: Windows 8.0+, Winrt/Win32. Gonk supports CONTACT, REMOVE,
|
||||
* and CANCEL but no HOVER. Other widgets will throw.
|
||||
*
|
||||
* @param aPointerId The touch point id to create or update.
|
||||
* @param aTouchState one or more of the touch states listed above
|
||||
|
@ -158,6 +158,17 @@ MultiTouchInput::ToWidgetMouseEvent(nsIWidget* aWidget) const
|
||||
return event;
|
||||
}
|
||||
|
||||
int32_t
|
||||
MultiTouchInput::IndexOfTouch(int32_t aTouchIdentifier)
|
||||
{
|
||||
for (size_t i = 0; i < mTouches.Length(); i++) {
|
||||
if (mTouches[i].mIdentifier == aTouchIdentifier) {
|
||||
return (int32_t)i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// This conversion from WidgetMouseEvent to MultiTouchInput is needed because on
|
||||
// the B2G emulator we can only receive mouse events, but we need to be able
|
||||
// to pan correctly. To do this, we convert the events into a format that the
|
||||
|
@ -222,6 +222,10 @@ public:
|
||||
WidgetTouchEvent ToWidgetTouchEvent(nsIWidget* aWidget) const;
|
||||
WidgetMouseEvent ToWidgetMouseEvent(nsIWidget* aWidget) const;
|
||||
|
||||
// Return the index into mTouches of the SingleTouchData with the given
|
||||
// identifier, or -1 if there is no such SingleTouchData.
|
||||
int32_t IndexOfTouch(int32_t aTouchIdentifier);
|
||||
|
||||
// This conversion from WidgetMouseEvent to MultiTouchInput is needed because
|
||||
// on the B2G emulator we can only receive mouse events, but we need to be
|
||||
// able to pan correctly. To do this, we convert the events into a format that
|
||||
|
@ -224,19 +224,15 @@ Interpolate(int start, int end, TimeDuration aFrameDiff, TimeDuration aTouchDiff
|
||||
static const SingleTouchData&
|
||||
GetTouchByID(const SingleTouchData& aCurrentTouch, MultiTouchInput& aOtherTouch)
|
||||
{
|
||||
int32_t id = aCurrentTouch.mIdentifier;
|
||||
for (size_t i = 0; i < aOtherTouch.mTouches.Length(); i++) {
|
||||
SingleTouchData& touch = aOtherTouch.mTouches[i];
|
||||
if (touch.mIdentifier == id) {
|
||||
return touch;
|
||||
}
|
||||
int32_t index = aOtherTouch.IndexOfTouch(aCurrentTouch.mIdentifier);
|
||||
if (index < 0) {
|
||||
// We can have situations where a previous touch event had 2 fingers
|
||||
// and we lift 1 finger off. In those cases, we won't find the touch event
|
||||
// with given id, so just return the current touch, which will be resampled
|
||||
// without modification and dispatched.
|
||||
return aCurrentTouch;
|
||||
}
|
||||
|
||||
// We can have situations where a previous touch event had 2 fingers
|
||||
// and we lift 1 finger off. In those cases, we won't find the touch event
|
||||
// with given id, so just return the current touch, which will be resampled
|
||||
// without modification and dispatched.
|
||||
return aCurrentTouch;
|
||||
return aOtherTouch.mTouches[index];
|
||||
}
|
||||
|
||||
|
||||
|
@ -300,6 +300,71 @@ nsWindow::DispatchTouchInputViaAPZ(MultiTouchInput& aInput)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsWindow::SynthesizeNativeTouchPoint(uint32_t aPointerId,
|
||||
TouchPointerState aPointerState,
|
||||
nsIntPoint aPointerScreenPoint,
|
||||
double aPointerPressure,
|
||||
uint32_t aPointerOrientation)
|
||||
{
|
||||
if (aPointerState == TOUCH_HOVER) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
if (!mSynthesizedTouchInput) {
|
||||
mSynthesizedTouchInput = new MultiTouchInput();
|
||||
}
|
||||
|
||||
// We can't dispatch mSynthesizedTouchInput directly because (a) dispatching
|
||||
// it might inadvertently modify it and (b) in the case of touchend or
|
||||
// touchcancel events mSynthesizedTouchInput will hold the touches that are
|
||||
// still down whereas the input dispatched needs to hold the removed
|
||||
// touch(es). We use |inputToDispatch| for this purpose.
|
||||
MultiTouchInput inputToDispatch;
|
||||
inputToDispatch.mInputType = MULTITOUCH_INPUT;
|
||||
|
||||
int32_t index = mSynthesizedTouchInput->IndexOfTouch((int32_t)aPointerId);
|
||||
if (aPointerState == TOUCH_CONTACT) {
|
||||
if (index >= 0) {
|
||||
// found an existing touch point, update it
|
||||
SingleTouchData& point = mSynthesizedTouchInput->mTouches[index];
|
||||
point.mScreenPoint = ScreenIntPoint::FromUntyped(aPointerScreenPoint);
|
||||
point.mRotationAngle = (float)aPointerOrientation;
|
||||
point.mForce = (float)aPointerPressure;
|
||||
inputToDispatch.mType = MultiTouchInput::MULTITOUCH_MOVE;
|
||||
} else {
|
||||
// new touch point, add it
|
||||
mSynthesizedTouchInput->mTouches.AppendElement(SingleTouchData(
|
||||
(int32_t)aPointerId,
|
||||
ScreenIntPoint::FromUntyped(aPointerScreenPoint),
|
||||
ScreenSize(0, 0),
|
||||
(float)aPointerOrientation,
|
||||
(float)aPointerPressure));
|
||||
inputToDispatch.mType = MultiTouchInput::MULTITOUCH_START;
|
||||
}
|
||||
inputToDispatch.mTouches = mSynthesizedTouchInput->mTouches;
|
||||
} else {
|
||||
MOZ_ASSERT(aPointerState == TOUCH_REMOVE || aPointerState == TOUCH_CANCEL);
|
||||
// a touch point is being lifted, so remove it from the stored list
|
||||
if (index >= 0) {
|
||||
mSynthesizedTouchInput->mTouches.RemoveElementAt(index);
|
||||
}
|
||||
inputToDispatch.mType = (aPointerState == TOUCH_REMOVE
|
||||
? MultiTouchInput::MULTITOUCH_END
|
||||
: MultiTouchInput::MULTITOUCH_CANCEL);
|
||||
inputToDispatch.mTouches.AppendElement(SingleTouchData(
|
||||
(int32_t)aPointerId,
|
||||
ScreenIntPoint::FromUntyped(aPointerScreenPoint),
|
||||
ScreenSize(0, 0),
|
||||
(float)aPointerOrientation,
|
||||
(float)aPointerPressure));
|
||||
}
|
||||
|
||||
DispatchTouchInputViaAPZ(inputToDispatch);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindow::Create(nsIWidget *aParent,
|
||||
void *aNativeParent,
|
||||
|
@ -90,6 +90,12 @@ public:
|
||||
void DispatchTouchInputViaAPZ(mozilla::MultiTouchInput& aInput);
|
||||
NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent,
|
||||
nsEventStatus& aStatus);
|
||||
virtual nsresult SynthesizeNativeTouchPoint(uint32_t aPointerId,
|
||||
TouchPointerState aPointerState,
|
||||
nsIntPoint aPointerScreenPoint,
|
||||
double aPointerPressure,
|
||||
uint32_t aPointerOrientation) MOZ_OVERRIDE;
|
||||
|
||||
NS_IMETHOD CaptureRollupEvents(nsIRollupListener *aListener,
|
||||
bool aDoCapture)
|
||||
{
|
||||
@ -147,6 +153,11 @@ protected:
|
||||
// Call this function when the users activity is the direct cause of an
|
||||
// event (like a keypress or mouse click).
|
||||
void UserActivity();
|
||||
|
||||
private:
|
||||
// This is used by SynthesizeNativeTouchPoint to maintain state between
|
||||
// multiple synthesized points
|
||||
nsAutoPtr<mozilla::MultiTouchInput> mSynthesizedTouchInput;
|
||||
};
|
||||
|
||||
#endif /* nsWindow_h */
|
||||
|
Loading…
Reference in New Issue
Block a user