From 04cf2a513c6cef59b2486ba7d38620b468557f23 Mon Sep 17 00:00:00 2001 From: Edgar Chen Date: Tue, 8 Nov 2022 19:47:29 +0000 Subject: [PATCH] Bug 1795116 - Support specifying tiltX/tiltY/twist on synthesized touch event; r=webdriver-reviewers,smaug,whimboo Differential Revision: https://phabricator.services.mozilla.com/D160970 --- dom/base/nsDOMWindowUtils.cpp | 27 +++++++---- dom/base/nsDOMWindowUtils.h | 5 +- dom/events/Touch.cpp | 9 ++++ dom/events/Touch.h | 3 ++ .../file_coalesce_touchmove_browserchild.html | 10 ++-- ...file_coalesce_touchmove_browserchild2.html | 21 +++++---- .../test/file_coalesce_touchmove_ipc.html | 21 +++++---- .../test/pointerevents/bug968148_inner.html | 30 ++++++++---- .../test/pointerevents/bug968148_inner2.html | 30 ++++++++---- dom/events/test/pointerevents/mochitest.ini | 1 + .../test/pointerevents/test_bug1420589_1.html | 9 ++-- .../test/pointerevents/test_bug1420589_2.html | 9 ++-- .../test/pointerevents/test_bug1420589_3.html | 9 ++-- .../pointerevents/test_multiple_touches.html | 45 +++++++++++------- .../pointerevents/test_synthesized_touch.html | 47 +++++++++++++++++++ dom/events/test/test_bug603008.html | 7 ++- dom/events/test/test_bug741666.html | 7 ++- dom/events/test/window_bug1429572.html | 10 +++- dom/interfaces/base/nsIDOMWindowUtils.idl | 9 ++++ layout/base/tests/bug970964_inner.html | 7 ++- layout/base/tests/bug970964_inner2.html | 7 ++- .../test_accessiblecaret_selection_mode.py | 4 +- layout/base/tests/test_bug993936.html | 7 ++- .../test/test_selection_touchevents.html | 2 +- remote/marionette/action.sys.mjs | 6 +++ remote/marionette/event.sys.mjs | 3 ++ remote/marionette/legacyaction.sys.mjs | 3 ++ .../mochitest/tests/SimpleTest/EventUtils.js | 21 ++++++++- .../perform_actions/pointer_touch.py.ini | 3 -- 29 files changed, 269 insertions(+), 103 deletions(-) create mode 100644 dom/events/test/pointerevents/test_synthesized_touch.html delete mode 100644 testing/web-platform/meta/webdriver/tests/perform_actions/pointer_touch.py.ini diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 885083ab95bf5..9e4bb8434c694 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -840,10 +840,13 @@ nsDOMWindowUtils::SendTouchEvent( const nsTArray& aXs, const nsTArray& aYs, const nsTArray& aRxs, const nsTArray& aRys, const nsTArray& aRotationAngles, const nsTArray& aForces, - int32_t aModifiers, bool aIgnoreRootScrollFrame, bool* aPreventDefault) { + const nsTArray& aTiltXs, const nsTArray& aTiltYs, + const nsTArray& aTwists, int32_t aModifiers, + bool aIgnoreRootScrollFrame, bool* aPreventDefault) { return SendTouchEventCommon(aType, aIdentifiers, aXs, aYs, aRxs, aRys, - aRotationAngles, aForces, aModifiers, - aIgnoreRootScrollFrame, false, aPreventDefault); + aRotationAngles, aForces, aTiltXs, aTiltYs, + aTwists, aModifiers, aIgnoreRootScrollFrame, + false, aPreventDefault); } NS_IMETHODIMP @@ -852,10 +855,13 @@ nsDOMWindowUtils::SendTouchEventToWindow( const nsTArray& aXs, const nsTArray& aYs, const nsTArray& aRxs, const nsTArray& aRys, const nsTArray& aRotationAngles, const nsTArray& aForces, - int32_t aModifiers, bool aIgnoreRootScrollFrame, bool* aPreventDefault) { + const nsTArray& aTiltXs, const nsTArray& aTiltYs, + const nsTArray& aTwists, int32_t aModifiers, + bool aIgnoreRootScrollFrame, bool* aPreventDefault) { return SendTouchEventCommon(aType, aIdentifiers, aXs, aYs, aRxs, aRys, - aRotationAngles, aForces, aModifiers, - aIgnoreRootScrollFrame, true, aPreventDefault); + aRotationAngles, aForces, aTiltXs, aTiltYs, + aTwists, aModifiers, aIgnoreRootScrollFrame, true, + aPreventDefault); } nsresult nsDOMWindowUtils::SendTouchEventCommon( @@ -863,8 +869,9 @@ nsresult nsDOMWindowUtils::SendTouchEventCommon( const nsTArray& aXs, const nsTArray& aYs, const nsTArray& aRxs, const nsTArray& aRys, const nsTArray& aRotationAngles, const nsTArray& aForces, - int32_t aModifiers, bool aIgnoreRootScrollFrame, bool aToWindow, - bool* aPreventDefault) { + const nsTArray& aTiltXs, const nsTArray& aTiltYs, + const nsTArray& aTwists, int32_t aModifiers, + bool aIgnoreRootScrollFrame, bool aToWindow, bool* aPreventDefault) { // get the widget to send the event to nsPoint offset; nsCOMPtr widget = GetWidget(&offset); @@ -905,8 +912,8 @@ nsresult nsDOMWindowUtils::SendTouchEventCommon( CSSPoint::ToAppUnits(CSSPoint(aRxs[i], aRys[i])), presContext->AppUnitsPerDevPixel()); - RefPtr t = - new Touch(aIdentifiers[i], pt, radius, aRotationAngles[i], aForces[i]); + RefPtr t = new Touch(aIdentifiers[i], pt, radius, aRotationAngles[i], + aForces[i], aTiltXs[i], aTiltYs[i], aTwists[i]); event.mTouches.AppendElement(t); } diff --git a/dom/base/nsDOMWindowUtils.h b/dom/base/nsDOMWindowUtils.h index 30e0fafa77857..63968c9b7a4e4 100644 --- a/dom/base/nsDOMWindowUtils.h +++ b/dom/base/nsDOMWindowUtils.h @@ -101,8 +101,9 @@ class nsDOMWindowUtils final : public nsIDOMWindowUtils, const nsTArray& aXs, const nsTArray& aYs, const nsTArray& aRxs, const nsTArray& aRys, const nsTArray& aRotationAngles, const nsTArray& aForces, - int32_t aModifiers, bool aIgnoreRootScrollFrame, bool aToWindow, - bool* aPreventDefault); + const nsTArray& aTiltXs, const nsTArray& aTiltYs, + const nsTArray& aTwists, int32_t aModifiers, + bool aIgnoreRootScrollFrame, bool aToWindow, bool* aPreventDefault); void ReportErrorMessageForWindow(const nsAString& aErrorMessage, const char* aClassification, diff --git a/dom/events/Touch.cpp b/dom/events/Touch.cpp index 11af73879bdad..0d7750c35e67e 100644 --- a/dom/events/Touch.cpp +++ b/dom/events/Touch.cpp @@ -67,6 +67,15 @@ Touch::Touch(int32_t aIdentifier, LayoutDeviceIntPoint aPoint, nsJSContext::LikelyShortLivingObjectCreated(); } +Touch::Touch(int32_t aIdentifier, LayoutDeviceIntPoint aPoint, + LayoutDeviceIntPoint aRadius, float aRotationAngle, float aForce, + int32_t aTiltX, int32_t aTiltY, int32_t aTwist) + : Touch(aIdentifier, aPoint, aRadius, aRotationAngle, aForce) { + tiltX = aTiltX; + tiltY = aTiltY; + twist = aTwist; +} + Touch::Touch(const Touch& aOther) : mOriginalTarget(aOther.mOriginalTarget), mTarget(aOther.mTarget), diff --git a/dom/events/Touch.h b/dom/events/Touch.h index a137b2fcb16bf..5a329b4cea16e 100644 --- a/dom/events/Touch.h +++ b/dom/events/Touch.h @@ -36,6 +36,9 @@ class Touch final : public nsISupports, float aRotationAngle, float aForce); Touch(int32_t aIdentifier, LayoutDeviceIntPoint aPoint, LayoutDeviceIntPoint aRadius, float aRotationAngle, float aForce); + Touch(int32_t aIdentifier, LayoutDeviceIntPoint aPoint, + LayoutDeviceIntPoint aRadius, float aRotationAngle, float aForce, + int32_t aTiltX, int32_t aTiltY, int32_t aTwist); Touch(const Touch& aOther); NS_DECL_CYCLE_COLLECTING_ISUPPORTS diff --git a/dom/events/test/file_coalesce_touchmove_browserchild.html b/dom/events/test/file_coalesce_touchmove_browserchild.html index 0acbfff768381..28a4ae5252c1b 100644 --- a/dom/events/test/file_coalesce_touchmove_browserchild.html +++ b/dom/events/test/file_coalesce_touchmove_browserchild.html @@ -27,24 +27,24 @@ var endYForFirstTouch = Math.floor(rect.y + ((rect.height / 4) * 2)); var endYForSecondTouch = Math.floor(rect.y + ((rect.height / 4) * 4)); utils.sendTouchEvent("touchstart", [0], [x], [y], [1], [1], [0], [1], - 0, false); + [0], [0], [0], 0, false); while (y != endYForFirstTouch) { utils.sendTouchEvent("touchmove", [0], [x], [y], [1], [1], [0], [1], - 0, false); + [0], [0], [0], 0, false); ++y; } // Add a new touch and move this touch utils.sendTouchEvent("touchstart", [0, 1], [x, x], [endYForFirstTouch, endYForFirstTouch], [1, 1], [1, 1], [0, 0], [1, 1], - 0, false); + [0, 0], [0, 0], [0, 0], 0, false); while (y != endYForSecondTouch) { utils.sendTouchEvent("touchmove", [0, 1], [x, x], [endYForFirstTouch, y], [1, 1], [1, 1], [0, 0], [1, 1], - 0, false); + [0, 0], [0, 0], [0, 0], 0, false); ++y; } utils.sendTouchEvent("touchend", [0, 1], [x, x], [endYForFirstTouch, endYForSecondTouch], [1, 1], [1, 1], [0, 0], [1, 1], - 0, false); + [0, 0], [0, 0], [0, 0], 0, false); }); let touchStartCount = 0; diff --git a/dom/events/test/file_coalesce_touchmove_browserchild2.html b/dom/events/test/file_coalesce_touchmove_browserchild2.html index be552e99a8d3f..b29ae291c2d76 100644 --- a/dom/events/test/file_coalesce_touchmove_browserchild2.html +++ b/dom/events/test/file_coalesce_touchmove_browserchild2.html @@ -34,14 +34,14 @@ var y = Math.floor(rect.y + (rect.height / 4)); var endY = Math.floor(rect.y + ((rect.height / 4) * 2)); utils.sendTouchEvent("touchstart", [0], [x], [y], [1], [1], [0], [1], - 0, false); + [0], [0], [0], 0, false); while (y != endY) { utils.sendTouchEvent("touchmove", [0], [x], [y], [1], [1], [0], [1], - 0, false); + [0], [0], [0], 0, false); ++y; } utils.sendTouchEvent("touchend", [0], [x], [y], [1], [1], [0], [1], - 0, false); + [0], [0], [0], 0, false); }); @@ -68,13 +68,13 @@ var startY = Math.floor(rect.y + (rect.height / 4)); var endY = Math.floor(rect.y + ((rect.height / 4) * 2)); utils.sendTouchEvent("touchstart", [0], [x], [startY], [1], [1], [0], - [1], 0, false); + [1], [0], [0], [0], 0, false); utils.sendTouchEvent("touchmove", [0], [x], [startY], [1], [1], [0], - [1], 0, false); + [1], [0], [0], [0], 0, false); utils.sendTouchEvent("touchmove", [0], [x], [startY + 1], [1], [1], [0], - [1], 0, false); + [1], [0], [0], [0], 0, false); utils.sendTouchEvent("touchend", [0], [x], [endY], [1], [1], [0], - [1], 0, false); + [1], [0], [0], [0], 0, false); }); touchmoveEvents = []; @@ -101,15 +101,16 @@ var endY = Math.floor(rect.y + ((rect.height / 4) * 2)); utils.sendTouchEvent("touchstart", [0, 1], [x, x + 1], [startY, startY + 1], [1, 1], [1, 1], [0, 0], - [1, 1], 0, false); + [1, 1], [0, 0], [0, 0], [0, 0], 0, false); while (startY != endY) { utils.sendTouchEvent("touchmove", [0, 1], [x, x + 1], [startY, startY + 1], [1, 1], [1, 1], [0, 0], - [1, 1], 0, false); + [1, 1], [0, 0], [0, 0], [0, 0], 0, false); ++startY; } utils.sendTouchEvent("touchend", [0, 1], [x, x + 1], [endY, endY + 1], - [1, 1], [1, 1], [0, 0], [1, 1], 0, false); + [1, 1], [1, 1], [0, 0], [1, 1], [0, 0], [0, 0], + [0, 0], 0, false); }); diff --git a/dom/events/test/file_coalesce_touchmove_ipc.html b/dom/events/test/file_coalesce_touchmove_ipc.html index 6042deb19cc3c..73e5a1157d65d 100644 --- a/dom/events/test/file_coalesce_touchmove_ipc.html +++ b/dom/events/test/file_coalesce_touchmove_ipc.html @@ -34,14 +34,14 @@ var y = Math.floor(rect.y + (rect.height / 4)); var endY = Math.floor(rect.y + ((rect.height / 4) * 2)); utils.sendTouchEvent("touchstart", [0], [x], [y], [1], [1], [0], [1], - 0, false); + [0], [0], [0], 0, false); while (y != endY) { utils.sendTouchEvent("touchmove", [0], [x], [y], [1], [1], [0], [1], - 0, false); + [0], [0], [0], 0, false); ++y; } utils.sendTouchEvent("touchend", [0], [x], [y], [1], [1], [0], [1], - 0, false); + [0], [0], [0], 0, false); }); @@ -68,13 +68,13 @@ var startY = Math.floor(rect.y + (rect.height / 4)); var endY = Math.floor(rect.y + ((rect.height / 4) * 2)); utils.sendTouchEvent("touchstart", [0], [x], [startY], [1], [1], [0], - [1], 0, false); + [1], [0], [0], [0], 0, false); utils.sendTouchEvent("touchmove", [0], [x], [startY], [1], [1], [0], - [1], 0, false); + [1], [0], [0], [0], 0, false); utils.sendTouchEvent("touchmove", [0], [x], [startY + 1], [1], [1], [0], - [1], 0, false); + [1], [0], [0], [0], 0, false); utils.sendTouchEvent("touchend", [0], [x], [endY], [1], [1], [0], - [1], 0, false); + [1], [0], [0], [0], 0, false); }); touchmoveEvents = []; @@ -101,15 +101,16 @@ var endY = Math.floor(rect.y + ((rect.height / 4) * 2)); utils.sendTouchEvent("touchstart", [0, 1], [x, x + 1], [startY, startY + 1], [1, 1], [1, 1], [0, 0], - [1, 1], 0, false); + [1, 1], [0, 0], [0, 0], [0, 0], 0, false); while (startY != endY) { utils.sendTouchEvent("touchmove", [0, 1], [x, x + 1], [startY, startY + 1], [1, 1], [1, 1], [0, 0], - [1, 1], 0, false); + [1, 1], [0, 0], [0, 0], [0, 0], 0, false); ++startY; } utils.sendTouchEvent("touchend", [0, 1], [x, x + 1], [endY, endY + 1], - [1, 1], [1, 1], [0, 0], [1, 1], 0, false); + [1, 1], [1, 1], [0, 0], [1, 1], [0, 0], [0, 0], + [0, 0], 0, false); }); diff --git a/dom/events/test/pointerevents/bug968148_inner.html b/dom/events/test/pointerevents/bug968148_inner.html index 09d6c42524cf2..464e2e5c38bcd 100644 --- a/dom/events/test/pointerevents/bug968148_inner.html +++ b/dom/events/test/pointerevents/bug968148_inner.html @@ -194,15 +194,18 @@ // event listener. utils.sendTouchEvent('touchstart', [test1PointerId, test2PointerId], [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); utils.sendTouchEvent('touchmove', [test1PointerId, test2PointerId], [left1d2, left2d2], [top1d2, top2d2], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); utils.sendTouchEvent('touchend', [test1PointerId, test2PointerId], [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); // No implicitly / explicitly pointer capture. pointermove should be // dispatched to 1d2, 2d2 @@ -217,11 +220,13 @@ utils.sendTouchEvent('touchstart', [test1PointerId, test2PointerId], [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); utils.sendTouchEvent('touchmove', [test1PointerId, test2PointerId], [left1d2, left2d2], [top1d2, top2d2], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); // Explicitly capture pointer to 1d1, 2d1. pointermove, gotpointercapture // should be dispatched to 1d1, 2d1 @@ -237,7 +242,8 @@ utils.sendTouchEvent('touchend', [test1PointerId, test2PointerId], [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); // Explicitly capture pointer to 1d1, 2d1 when pointerdown test1d1.addEventListener("pointerdown", test1d1CapturePointer, {capture: true, once: true}); @@ -249,17 +255,20 @@ utils.sendTouchEvent('touchstart', [test1PointerId, test2PointerId], [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); // This should send pointer event to test1d1, test2d1. utils.sendTouchEvent('touchmove', [test1PointerId, test2PointerId], [left1d1 + 5, left2d1 + 5], [top1d1, top2d1], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); // This should send pointer event to test1d2, test2d2. utils.sendTouchEvent('touchmove', [test1PointerId, test2PointerId], [left1d1 + 5, left2d1 + 5], [top1d1 + 5, top2d1 + 5], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); is(test1d1pointermovecount, 2, "1d1 should have got pointermove"); is(test1d1pointergotcapture, 2, "1d1 should have got pointergotcapture"); @@ -273,7 +282,8 @@ utils.sendTouchEvent('touchend', [test1PointerId, test2PointerId], [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); finishTest(); } diff --git a/dom/events/test/pointerevents/bug968148_inner2.html b/dom/events/test/pointerevents/bug968148_inner2.html index 0821c83771731..ffad5297bc829 100644 --- a/dom/events/test/pointerevents/bug968148_inner2.html +++ b/dom/events/test/pointerevents/bug968148_inner2.html @@ -194,15 +194,18 @@ // event listener. utils.sendTouchEvent('touchstart', [test1PointerId, test2PointerId], [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); utils.sendTouchEvent('touchmove', [test1PointerId, test2PointerId], [left1d2, left2d2], [top1d2, top2d2], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); utils.sendTouchEvent('touchend', [test1PointerId, test2PointerId], [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); // Implicitly pointer capture. pointermove should be dispatched to 1d1, 2d1 is(test1d1pointermovecount, 1, "1d1 should have got pointermove"); @@ -216,11 +219,13 @@ utils.sendTouchEvent('touchstart', [test1PointerId, test2PointerId], [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); utils.sendTouchEvent('touchmove', [test1PointerId, test2PointerId], [left1d2, left2d2], [top1d2, top2d2], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); // Explicitly capture pointer to 1d1, 2d1. pointermove, gotpointercapture // should be dispatched to 1d1, 2d1 @@ -236,7 +241,8 @@ utils.sendTouchEvent('touchend', [test1PointerId, test2PointerId], [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); // Explicitly capture pointer to 1d1, 2d1 when pointerdown test1d1.addEventListener("pointerdown", test1d1CapturePointer, {capture: true, once: true}); @@ -248,17 +254,20 @@ utils.sendTouchEvent('touchstart', [test1PointerId, test2PointerId], [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); // This should send pointer event to test1d1, test2d1. utils.sendTouchEvent('touchmove', [test1PointerId, test2PointerId], [left1d1 + 5, left2d1 + 5], [top1d1, top2d1], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); // This should send pointer event to test1d2, test2d2. utils.sendTouchEvent('touchmove', [test1PointerId, test2PointerId], [left1d1 + 5, left2d1 + 5], [top1d1 + 5, top2d1 + 5], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); is(test1d1pointermovecount, 3, "1d1 shouldn't have got pointermove"); is(test1d1pointergotcapture, 3, "1d1 should have got pointergotcapture"); @@ -272,7 +281,8 @@ utils.sendTouchEvent('touchend', [test1PointerId, test2PointerId], [left1d1, left2d1], [top1d1, top2d1], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); finishTest(); } diff --git a/dom/events/test/pointerevents/mochitest.ini b/dom/events/test/pointerevents/mochitest.ini index 80b198641aa47..ce6a546276095 100644 --- a/dom/events/test/pointerevents/mochitest.ini +++ b/dom/events/test/pointerevents/mochitest.ini @@ -132,3 +132,4 @@ support-files = [test_pointercapture_remove_iframe.html] [test_pointermove_drag_scrollbar.html] skip-if = os == 'android' # scrollbar not showed on mobile +[test_synthesized_touch.html] diff --git a/dom/events/test/pointerevents/test_bug1420589_1.html b/dom/events/test/pointerevents/test_bug1420589_1.html index d16cb13c8867c..8ecea7a28b918 100644 --- a/dom/events/test/pointerevents/test_bug1420589_1.html +++ b/dom/events/test/pointerevents/test_bug1420589_1.html @@ -83,13 +83,16 @@ var utils = SpecialPowers.getDOMWindowUtils(window); utils.sendTouchEvent('touchstart', [test1PointerId, test2PointerId], [left1, left2], [top1, top2], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); utils.sendTouchEvent('touchmove', [test1PointerId, test2PointerId], [left1 + 1, left2 + 1], [top1, top2], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); utils.sendTouchEvent('touchend', [test1PointerId, test2PointerId], [left1 + 1, left2 + 1], [top1, top2], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); } SimpleTest.waitForFocus(() => { diff --git a/dom/events/test/pointerevents/test_bug1420589_2.html b/dom/events/test/pointerevents/test_bug1420589_2.html index 45f08fc408946..2bfac2cdfce23 100644 --- a/dom/events/test/pointerevents/test_bug1420589_2.html +++ b/dom/events/test/pointerevents/test_bug1420589_2.html @@ -96,17 +96,20 @@ var utils = SpecialPowers.getDOMWindowUtils(window); utils.sendTouchEvent('touchstart', [test1PointerId, test2PointerId], [left1, left2], [top1, top2], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); // Move the touch pointers so that we dispatch all of them to content. left1++; left2++; utils.sendTouchEvent('touchmove', [test1PointerId, test2PointerId], [left1, left2], [top1, top2], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); utils.sendTouchEvent('touchend', [test1PointerId, test2PointerId], [left1, left2], [top1, top2], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); } SimpleTest.waitForFocus(() => { diff --git a/dom/events/test/pointerevents/test_bug1420589_3.html b/dom/events/test/pointerevents/test_bug1420589_3.html index a76b63f9b380a..9942591f64bac 100644 --- a/dom/events/test/pointerevents/test_bug1420589_3.html +++ b/dom/events/test/pointerevents/test_bug1420589_3.html @@ -89,17 +89,20 @@ var utils = SpecialPowers.getDOMWindowUtils(window); utils.sendTouchEvent('touchstart', [test1PointerId, test2PointerId], [left1, left2], [top1, top2], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); // Move the touch pointers so that we dispatch all of them to content. left1++; left2++; utils.sendTouchEvent('touchmove', [test1PointerId, test2PointerId], [left1, left2], [top1, top2], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); utils.sendTouchEvent('touchend', [test1PointerId, test2PointerId], [left1, left2], [top1, top2], [rx, rx], [ry, ry], - [angle, angle], [force, force], modifiers); + [angle, angle], [force, force], [0, 0], [0, 0], + [0, 0], modifiers); } SimpleTest.waitForFocus(() => { diff --git a/dom/events/test/pointerevents/test_multiple_touches.html b/dom/events/test/pointerevents/test_multiple_touches.html index c07d2ef20b340..15202c3636532 100644 --- a/dom/events/test/pointerevents/test_multiple_touches.html +++ b/dom/events/test/pointerevents/test_multiple_touches.html @@ -24,17 +24,22 @@ rys: [], angles: [], forces: [], + tiltXs: [], + tiltYs: [], + twists: [], }; -function synthesizeTouchEvent(aType, aIds, aLefts, aTops, aRxs, aRys, aAngles, aForces) { +function synthesizeTouchEvent(aType, aTouches) { var utils = _getDOMWindowUtils(window); if (!utils) { ok(false, "unable to get nsIDOMWindowUtils"); return; } - utils.sendTouchEvent(aType, aIds, aLefts, aTops, aRxs, aRys, - aAngles, aForces, 0 /* modifiers */); + utils.sendTouchEvent(aType, aTouches.ids, aTouches.lefts, aTouches.tops, + aTouches.rxs, aTouches.rys, aTouches.angles, + aTouches.forces, aTouches.tiltXs, aTouches.tiltYs, + aTouches.twists, 0 /* modifiers */); } function synthesizeTouchStart(aTarget, aId, aOffsetX, aOffsetY) { @@ -51,9 +56,11 @@ touches.rys.push(1); touches.angles.push(0); touches.forces.push(1); + touches.tiltXs.push(0); + touches.tiltYs.push(0); + touches.twists.push(0); - synthesizeTouchEvent("touchstart", touches.ids, touches.lefts, touches.tops, - touches.rxs, touches.rys, touches.angles, touches.forces); + synthesizeTouchEvent("touchstart", touches); } function synthesizeTouchEnd(aTarget, aId, aOffsetX, aOffsetY) { @@ -63,17 +70,20 @@ return; } - let rect = aTarget.getBoundingClientRect(); - touches.ids.splice(index, 1); - touches.lefts.splice(index, 1); - touches.tops.splice(index, 1); - touches.rxs.splice(index, 1); - touches.rys.splice(index, 1); - touches.angles.splice(index, 1); - touches.forces.splice(index, 1); - - synthesizeTouchEvent("touchend", [aId], [rect.left + aOffsetX], [rect.top + aOffsetY], - [1], [1], [0], [1]); + var removedTouches = { + ids: touches.ids.splice(index, 1), + lefts: touches.lefts.splice(index, 1), + tops: touches.tops.splice(index, 1), + rxs: touches.rxs.splice(index, 1), + rys: touches.rys.splice(index, 1), + angles: touches.angles.splice(index, 1), + forces: touches.forces.splice(index, 1), + tiltXs: touches.tiltXs.splice(index, 1), + tiltYs: touches.tiltYs.splice(index, 1), + twists: touches.twists.splice(index, 1), + }; + + synthesizeTouchEvent("touchend", removedTouches); } function synthesizeTouchMove(aTarget, aId, aOffsetX, aOffsetY) { @@ -87,8 +97,7 @@ touches.lefts[index] = rect.left + aOffsetX; touches.tops[index] = rect.top + aOffsetY; - synthesizeTouchEvent("touchmove", touches.ids, touches.lefts, touches.tops, - touches.rxs, touches.rys, touches.angles, touches.forces); + synthesizeTouchEvent("touchmove", touches); } var target0 = document.getElementById("target0"); diff --git a/dom/events/test/pointerevents/test_synthesized_touch.html b/dom/events/test/pointerevents/test_synthesized_touch.html new file mode 100644 index 0000000000000..8a79303e74bf0 --- /dev/null +++ b/dom/events/test/pointerevents/test_synthesized_touch.html @@ -0,0 +1,47 @@ + + +Test synthesized touch input + + + + + + +
+ + diff --git a/dom/events/test/test_bug603008.html b/dom/events/test/test_bug603008.html index b52956fabcd58..ccba289a51906 100644 --- a/dom/events/test/test_bug603008.html +++ b/dom/events/test/test_bug603008.html @@ -75,7 +75,7 @@ function sendTouchEvent(windowUtils, aType, aEvent, aModifiers) { var ids = [], xs=[], ys=[], rxs = [], rys = [], - rotations = [], forces = []; + rotations = [], forces = [], tiltXs = [], tiltYs = [], twists = []; for (var touchType of ["touches", "changedTouches", "targetTouches"]) { for (var i = 0; i < aEvent[touchType].length; i++) { @@ -87,12 +87,15 @@ rys.push(aEvent[touchType][i].radius.y); rotations.push(aEvent[touchType][i].rotationAngle); forces.push(aEvent[touchType][i].force); + tiltXs.push(0); + tiltYs.push(0); + twists.push(0); } } } return windowUtils.sendTouchEvent(aType, ids, xs, ys, rxs, rys, - rotations, forces, + rotations, forces, tiltXs, tiltYs, twists, aModifiers, 0); } diff --git a/dom/events/test/test_bug741666.html b/dom/events/test/test_bug741666.html index 3a048c0f49e50..f67a3a7065970 100644 --- a/dom/events/test/test_bug741666.html +++ b/dom/events/test/test_bug741666.html @@ -73,7 +73,7 @@ function sendTouchEvent(windowUtils, aType, aEvent, aModifiers) { var ids = [], xs=[], ys=[], rxs = [], rys = [], - rotations = [], forces = []; + rotations = [], forces = [], tiltXs = [], tiltYs = [], twists = []; for (var touchType of ["touches", "changedTouches", "targetTouches"]) { for (var i = 0; i < aEvent[touchType].length; i++) { @@ -85,12 +85,15 @@ rys.push(aEvent[touchType][i].radius.y); rotations.push(aEvent[touchType][i].rotationAngle); forces.push(aEvent[touchType][i].force); + tiltXs.push(0); + tiltYs.push(0); + twists.push(0); } } } return windowUtils.sendTouchEvent(aType, ids, xs, ys, rxs, rys, - rotations, forces, + rotations, forces, tiltXs, tiltYs, twists, aModifiers, 0); } diff --git a/dom/events/test/window_bug1429572.html b/dom/events/test/window_bug1429572.html index 08c341df13670..694794b1e4794 100644 --- a/dom/events/test/window_bug1429572.html +++ b/dom/events/test/window_bug1429572.html @@ -39,6 +39,9 @@ var rys = []; var angles = []; var forces = []; + var tiltXs = []; + var tiltYs = []; + var twists = []; for (var i = 0; i < targets.length; ++i) { touches.push(++touchCounter); var rect = targets[i].getBoundingClientRect(); @@ -52,11 +55,14 @@ rys.push(1); angles.push(0); forces.push(1); + tiltXs.push(0); + tiltYs.push(0); + twists.push(0); } winUtils.sendTouchEvent("touchstart", - touches, xs, ys, rxs, rys, angles, forces, 0); + touches, xs, ys, rxs, rys, angles, forces, tiltXs, tiltYs, twists, 0); winUtils.sendTouchEvent("touchend", - touches, xs, ys, rxs, rys, angles, forces, 0); + touches, xs, ys, rxs, rys, angles, forces, tiltXs, tiltYs, twists, 0); } function next() { diff --git a/dom/interfaces/base/nsIDOMWindowUtils.idl b/dom/interfaces/base/nsIDOMWindowUtils.idl index faefb552491e7..89338882e70f7 100644 --- a/dom/interfaces/base/nsIDOMWindowUtils.idl +++ b/dom/interfaces/base/nsIDOMWindowUtils.idl @@ -393,6 +393,9 @@ interface nsIDOMWindowUtils : nsISupports { * @param rys array of radii in CSS pixels for each touch to be sent * @param rotationAngles array of angles in degrees for each touch to be sent * @param forces array of forces (floats from 0 to 1) for each touch to be sent + * @param tiltXs array of tiltX for each touch to be sent + * @param tiltYs array of tiltY for each touch to be sent + * @param twists array of twist for each touch to be sent * @param count number of touches in this set * @param aModifiers modifiers pressed, using constants defined as MODIFIER_* * @param aIgnoreRootScrollFrame whether the event should ignore viewport bounds @@ -409,6 +412,9 @@ interface nsIDOMWindowUtils : nsISupports { in Array aRys, in Array aRotationAngles, in Array aForces, + in Array aTiltXs, + in Array aTiltYs, + in Array aTwists, in long aModifiers, [optional] in boolean aIgnoreRootScrollFrame); @@ -442,6 +448,9 @@ interface nsIDOMWindowUtils : nsISupports { in Array aRys, in Array aRotationAngles, in Array aForces, + in Array aTiltXs, + in Array aTiltYs, + in Array aTwists, in long aModifiers, [optional] in boolean aIgnoreRootScrollFrame); diff --git a/layout/base/tests/bug970964_inner.html b/layout/base/tests/bug970964_inner.html index a174fe1e9c9f1..e8e7092aea96c 100644 --- a/layout/base/tests/bug970964_inner.html +++ b/layout/base/tests/bug970964_inner.html @@ -54,7 +54,7 @@ function sendTouchEvent(windowUtils, aType, aEvent, aModifiers) { var ids = [], xs=[], ys=[], rxs = [], rys = [], - rotations = [], forces = []; + rotations = [], forces = [], tiltXs = [], tiltYs = [], twists = []; for (var touchType of ["touches", "changedTouches", "targetTouches"]) { for (var i = 0; i < aEvent[touchType].length; i++) { @@ -66,12 +66,15 @@ rys.push(aEvent[touchType][i].radius.y); rotations.push(aEvent[touchType][i].rotationAngle); forces.push(aEvent[touchType][i].force); + tiltXs.push(0); + tiltYs.push(0); + twists.push(0); } } } return windowUtils.sendTouchEvent(aType, ids, xs, ys, rxs, rys, - rotations, forces, + rotations, forces, tiltXs, tiltYs, twists, aModifiers, 0); } diff --git a/layout/base/tests/bug970964_inner2.html b/layout/base/tests/bug970964_inner2.html index d3b3ea3c13aba..51cee6c1ee9d2 100644 --- a/layout/base/tests/bug970964_inner2.html +++ b/layout/base/tests/bug970964_inner2.html @@ -54,7 +54,7 @@ function sendTouchEvent(windowUtils, aType, aEvent, aModifiers) { var ids = [], xs=[], ys=[], rxs = [], rys = [], - rotations = [], forces = []; + rotations = [], forces = [], tiltXs = [], tiltYs = [], twists = []; for (var touchType of ["touches", "changedTouches", "targetTouches"]) { for (var i = 0; i < aEvent[touchType].length; i++) { @@ -66,12 +66,15 @@ rys.push(aEvent[touchType][i].radius.y); rotations.push(aEvent[touchType][i].rotationAngle); forces.push(aEvent[touchType][i].force); + tiltXs.push(0); + tiltYs.push(0); + twists.push(0); } } } return windowUtils.sendTouchEvent(aType, ids, xs, ys, rxs, rys, - rotations, forces, + rotations, forces, tiltXs, tiltYs, twists, aModifiers, 0); } diff --git a/layout/base/tests/marionette/test_accessiblecaret_selection_mode.py b/layout/base/tests/marionette/test_accessiblecaret_selection_mode.py index 003daaa9e9e42..cb73de45cab9b 100644 --- a/layout/base/tests/marionette/test_accessiblecaret_selection_mode.py +++ b/layout/base/tests/marionette/test_accessiblecaret_selection_mode.py @@ -149,12 +149,12 @@ def long_press_on_location(self, el, x=None, y=None): let utils = window.windowUtils; utils.sendTouchEventToWindow('touchstart', [0], [arguments[0]], [arguments[1]], - [1], [1], [0], [1], 0); + [1], [1], [0], [1], [0], [0], [0], 0); utils.sendMouseEventToWindow('mouselongtap', arguments[0], arguments[1], 0, 1, 0); utils.sendTouchEventToWindow('touchend', [0], [arguments[0]], [arguments[1]], - [1], [1], [0], [1], 0); + [1], [1], [0], [1], [0], [0], [0], 0); """, script_args=[target_x, target_y], sandbox="system", diff --git a/layout/base/tests/test_bug993936.html b/layout/base/tests/test_bug993936.html index 8d9ca0c610e59..5325b66a22ed0 100644 --- a/layout/base/tests/test_bug993936.html +++ b/layout/base/tests/test_bug993936.html @@ -41,7 +41,7 @@ function sendTouchEvent(windowUtils, aType, aEvent, aModifiers) { var ids = [], xs=[], ys=[], rxs = [], rys = [], - rotations = [], forces = []; + rotations = [], forces = [], tiltXs = [], tiltYs = [], twists = []; for (var touchType of ["touches", "changedTouches", "targetTouches"]) { for (var i = 0; i < aEvent[touchType].length; i++) { @@ -53,12 +53,15 @@ rys.push(aEvent[touchType][i].radius.y); rotations.push(aEvent[touchType][i].rotationAngle); forces.push(aEvent[touchType][i].force); + tiltXs.push(0); + tiltYs.push(0); + twists.push(0); } } } return windowUtils.sendTouchEvent(aType, ids, xs, ys, rxs, rys, - rotations, forces, + rotations, forces, tiltXs, tiltYs, twists, aModifiers, 0); } diff --git a/layout/generic/test/test_selection_touchevents.html b/layout/generic/test/test_selection_touchevents.html index 51bd0f8cfee6a..082f879d01952 100644 --- a/layout/generic/test/test_selection_touchevents.html +++ b/layout/generic/test/test_selection_touchevents.html @@ -16,7 +16,7 @@ function sendTouch(aType, aX, aY) { var cwu = SpecialPowers.getDOMWindowUtils(window); - cwu.sendTouchEvent(aType, [0], [aX], [aY], [1], [1], [0], [1], 0, true); + cwu.sendTouchEvent(aType, [0], [aX], [aY], [1], [1], [0], [1], [0], [0], [0], 0, true); } function test() diff --git a/remote/marionette/action.sys.mjs b/remote/marionette/action.sys.mjs index 125b0086582ed..75c33710e8e7c 100644 --- a/remote/marionette/action.sys.mjs +++ b/remote/marionette/action.sys.mjs @@ -2042,6 +2042,9 @@ class MultiTouchEventData extends PointerEventData { this.ry = []; this.angle = []; this.force = []; + this.tiltx = []; + this.tilty = []; + this.twist = []; this.#setGlobalState = false; } @@ -2059,6 +2062,9 @@ class MultiTouchEventData extends PointerEventData { this.ry.push(action.height || 1); this.angle.push(0); this.force.push(action.pressure || (this.type === "touchend" ? 0 : 1)); + this.tiltx.push(action.tiltX || 0); + this.tilty.push(action.tiltY || 0); + this.twist.push(action.twist || 0); } update(state, inputSource) { diff --git a/remote/marionette/event.sys.mjs b/remote/marionette/event.sys.mjs index ec3eec340c422..731076d09d63b 100644 --- a/remote/marionette/event.sys.mjs +++ b/remote/marionette/event.sys.mjs @@ -178,6 +178,9 @@ event.synthesizeMultiTouch = function(opts, win) { opts.ry, opts.angle, opts.force, + opts.tiltx, + opts.tilty, + opts.twist, modifiers ); }; diff --git a/remote/marionette/legacyaction.sys.mjs b/remote/marionette/legacyaction.sys.mjs index 0c468b46dc78d..d4ed060282d12 100644 --- a/remote/marionette/legacyaction.sys.mjs +++ b/remote/marionette/legacyaction.sys.mjs @@ -207,6 +207,9 @@ action.Chain.prototype.emitTouchEvent = function(doc, type, touch) { [touch.radiusY], [touch.rotationAngle], [touch.force], + [0], + [0], + [0], 0 ); }; diff --git a/testing/mochitest/tests/SimpleTest/EventUtils.js b/testing/mochitest/tests/SimpleTest/EventUtils.js index 8167456dc6c32..e63c58cf52c75 100644 --- a/testing/mochitest/tests/SimpleTest/EventUtils.js +++ b/testing/mochitest/tests/SimpleTest/EventUtils.js @@ -22,6 +22,8 @@ * synthesizeDrop * synthesizePlainDragAndDrop * synthesizePlainDragAndCancel + * synthesizeTouch + * synthesizeTouchAtCenter * * When adding methods to this file, please add a performance test for it. */ @@ -691,6 +693,9 @@ function synthesizeTouchAtPoint(left, top, aEvent, aWindow = window) { var ry = aEvent.ry || 1; var angle = aEvent.angle || 0; var force = aEvent.force || (aEvent.type === "touchend" ? 0 : 1); + var tiltX = aEvent.tiltX || 0; + var tiltY = aEvent.tiltY || 0; + var twist = aEvent.twist || 0; var modifiers = _parseModifiers(aEvent, aWindow); if ("type" in aEvent && aEvent.type) { @@ -703,6 +708,9 @@ function synthesizeTouchAtPoint(left, top, aEvent, aWindow = window) { [ry], [angle], [force], + [tiltX], + [tiltY], + [twist], modifiers ); } else { @@ -715,6 +723,9 @@ function synthesizeTouchAtPoint(left, top, aEvent, aWindow = window) { [ry], [angle], [force], + [tiltX], + [tiltY], + [twist], modifiers ); utils.sendTouchEvent( @@ -726,6 +737,9 @@ function synthesizeTouchAtPoint(left, top, aEvent, aWindow = window) { [ry], [angle], [force], + [tiltX], + [tiltY], + [twist], modifiers ); } @@ -746,7 +760,12 @@ function synthesizeMouseAtCenter(aTarget, aEvent, aWindow) { } function synthesizeTouchAtCenter(aTarget, aEvent, aWindow) { var rect = aTarget.getBoundingClientRect(); - synthesizeTouch(aTarget, rect.width / 2, rect.height / 2, aEvent, aWindow); + synthesizeTouchAtPoint( + rect.left + rect.width / 2, + rect.top + rect.height / 2, + aEvent, + aWindow + ); } /** diff --git a/testing/web-platform/meta/webdriver/tests/perform_actions/pointer_touch.py.ini b/testing/web-platform/meta/webdriver/tests/perform_actions/pointer_touch.py.ini deleted file mode 100644 index bdb1f0b3b2da7..0000000000000 --- a/testing/web-platform/meta/webdriver/tests/perform_actions/pointer_touch.py.ini +++ /dev/null @@ -1,3 +0,0 @@ -[pointer_touch.py] - [test_touch_pointer_properties_tilt_twist] - expected: FAIL