mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
Bug 1648630 - Part 3: Propagate layers id to touch event properly for Fission; r=kats
Differential Revision: https://phabricator.services.mozilla.com/D81869
This commit is contained in:
parent
71ad0b0850
commit
dc0bf3f975
@ -45,6 +45,7 @@ add_task(async function test_main() {
|
||||
},
|
||||
{ url: httpURL("helper_fission_animation_styling_in_oopif.html") },
|
||||
{ url: httpURL("helper_fission_force_empty_hit_region.html") },
|
||||
{ url: httpURL("helper_fission_touch.html") },
|
||||
// add additional tests here
|
||||
];
|
||||
if (isWebRender) {
|
||||
|
99
gfx/layers/apz/test/mochitest/helper_fission_touch.html
Normal file
99
gfx/layers/apz/test/mochitest/helper_fission_touch.html
Normal file
@ -0,0 +1,99 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test to ensure touch events for OOP iframes</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script src="/tests/SimpleTest/paint_listener.js"></script>
|
||||
<script src="helper_fission_utils.js"></script>
|
||||
<script src="apz_test_utils.js"></script>
|
||||
<script src="apz_test_native_event_utils.js"></script>
|
||||
<script>
|
||||
|
||||
fission_subtest_init();
|
||||
|
||||
FissionTestHelper.startTestPromise
|
||||
.then(waitUntilApzStable)
|
||||
.then(loadOOPIFrame("testframe", "helper_fission_empty.html"))
|
||||
.then(waitUntilApzStable)
|
||||
.then(runAsyncContinuation(test))
|
||||
.then(FissionTestHelper.subtestDone, FissionTestHelper.subtestDone);
|
||||
|
||||
|
||||
let code_for_oopif_to_run = function() {
|
||||
let listener = function(e) {
|
||||
let result = { type: e.type, touches: [] };
|
||||
dump(`OOPIF got ${e.type}\n`);
|
||||
for (let touch of e.touches) {
|
||||
result.touches.push({
|
||||
identifier: touch.identifier,
|
||||
clientX: touch.clientX,
|
||||
clientY: touch.clientY
|
||||
});
|
||||
dump(` identifier ${touch.identifier} at ${touch.clientX},${touch.clientY}\n`);
|
||||
}
|
||||
FissionTestHelper.fireEventInEmbedder("OOPIF:TouchEvent", result);
|
||||
};
|
||||
document.addEventListener("touchstart", listener, {once: true});
|
||||
document.addEventListener("touchmove", listener, {once: true});
|
||||
document.addEventListener("touchend", listener, {once: true});
|
||||
dump("OOPIF registered touch listener\n");
|
||||
return true;
|
||||
};
|
||||
|
||||
function failsafe() {
|
||||
let failListener = function(e) {
|
||||
dump(`${location.href} got ${e.type}\n`);
|
||||
ok(false, `The OOPIF hosting page should not have gotten the ${e.type}`);
|
||||
setTimeout(FissionTestHelper.subtestDone, 0);
|
||||
};
|
||||
// Catch and fail faster on the case where the touch event ends up not going
|
||||
// to the iframe like it should. Otherwise the test hangs until timeout which
|
||||
// is more painful.
|
||||
document.addEventListener("touchstart", failListener, {once: true});
|
||||
document.addEventListener("touchmove", failListener, {once: true});
|
||||
document.addEventListener("touchend", failListener, {once: true});
|
||||
}
|
||||
|
||||
function waitForTouchEvent(aType) {
|
||||
return promiseOneEvent(window, "OOPIF:TouchEvent", function(e) {
|
||||
return e.data.type === aType;
|
||||
});
|
||||
}
|
||||
|
||||
async function* test() {
|
||||
let iframeElement = document.getElementById("testframe");
|
||||
|
||||
let iframeResponse = await FissionTestHelper.sendToOopif(iframeElement, `(${code_for_oopif_to_run})()`);
|
||||
dump("OOPIF response: " + JSON.stringify(iframeResponse) + "\n");
|
||||
ok(iframeResponse, "code_for_oopif_to_run successfully installed");
|
||||
|
||||
iframePromise = Promise.all([waitForTouchEvent("touchstart"),
|
||||
waitForTouchEvent("touchmove"),
|
||||
waitForTouchEvent("touchend")]);
|
||||
yield* synthesizeNativeTouchSequences(document.body,
|
||||
[[{x: 100, y: 100}], [{x: 150, y: 150}], [{x: 150, y: 150}]], function() {
|
||||
dump("Finished synthesizing touch tap, waiting for OOPIF message...\n");
|
||||
});
|
||||
await iframePromise;
|
||||
}
|
||||
|
||||
</script>
|
||||
<style>
|
||||
body, html {
|
||||
margin: 0;
|
||||
}
|
||||
div {
|
||||
width: 500px;
|
||||
}
|
||||
iframe {
|
||||
width: 400px;
|
||||
height: 300px;
|
||||
border: solid 1px black;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="failsafe()">
|
||||
<div><iframe id="testframe"></iframe></div>
|
||||
</body>
|
||||
</html>
|
@ -19,12 +19,14 @@ namespace mozilla {
|
||||
|
||||
nsDataHashtable<nsUint32HashKey, TouchManager::TouchInfo>*
|
||||
TouchManager::sCaptureTouchList;
|
||||
layers::LayersId TouchManager::sCaptureTouchLayersId;
|
||||
|
||||
/*static*/
|
||||
void TouchManager::InitializeStatics() {
|
||||
NS_ASSERTION(!sCaptureTouchList, "InitializeStatics called multiple times!");
|
||||
sCaptureTouchList =
|
||||
new nsDataHashtable<nsUint32HashKey, TouchManager::TouchInfo>;
|
||||
sCaptureTouchLayersId = layers::LayersId{0};
|
||||
}
|
||||
|
||||
/*static*/
|
||||
@ -98,6 +100,7 @@ void TouchManager::EvictTouches(Document* aLimitToDocument) {
|
||||
for (uint32_t i = 0; i < touches.Length(); ++i) {
|
||||
EvictTouchPoint(touches[i], aLimitToDocument);
|
||||
}
|
||||
sCaptureTouchLayersId = layers::LayersId{0};
|
||||
}
|
||||
|
||||
/* static */
|
||||
@ -225,6 +228,14 @@ bool TouchManager::PreHandleEvent(WidgetEvent* aEvent, nsEventStatus* aStatus,
|
||||
// queue
|
||||
if (touchEvent->mTouches.Length() == 1) {
|
||||
EvictTouches();
|
||||
// Per
|
||||
// https://w3c.github.io/touch-events/#touchevent-implementer-s-note,
|
||||
// all touch event should be dispatched to the same document that first
|
||||
// touch event associated to. We cache layers id of the first touchstart
|
||||
// event, all subsequent touch events will use the same layers id.
|
||||
sCaptureTouchLayersId = aEvent->mLayersId;
|
||||
} else {
|
||||
touchEvent->mLayersId = sCaptureTouchLayersId;
|
||||
}
|
||||
// Add any new touches to the queue
|
||||
WidgetTouchEvent::TouchArray& touches = touchEvent->mTouches;
|
||||
@ -253,6 +264,7 @@ bool TouchManager::PreHandleEvent(WidgetEvent* aEvent, nsEventStatus* aStatus,
|
||||
// Check for touches that changed. Mark them add to queue
|
||||
WidgetTouchEvent* touchEvent = aEvent->AsTouchEvent();
|
||||
WidgetTouchEvent::TouchArray& touches = touchEvent->mTouches;
|
||||
touchEvent->mLayersId = sCaptureTouchLayersId;
|
||||
bool haveChanged = false;
|
||||
for (int32_t i = touches.Length(); i;) {
|
||||
--i;
|
||||
@ -326,6 +338,7 @@ bool TouchManager::PreHandleEvent(WidgetEvent* aEvent, nsEventStatus* aStatus,
|
||||
// need to make sure we only remove touches that are ending here
|
||||
WidgetTouchEvent* touchEvent = aEvent->AsTouchEvent();
|
||||
WidgetTouchEvent::TouchArray& touches = touchEvent->mTouches;
|
||||
touchEvent->mLayersId = sCaptureTouchLayersId;
|
||||
for (int32_t i = touches.Length(); i;) {
|
||||
--i;
|
||||
Touch* touch = touches[i];
|
||||
@ -363,6 +376,7 @@ bool TouchManager::PreHandleEvent(WidgetEvent* aEvent, nsEventStatus* aStatus,
|
||||
// is received.
|
||||
WidgetTouchEvent* touchEvent = aEvent->AsTouchEvent();
|
||||
WidgetTouchEvent::TouchArray& touches = touchEvent->mTouches;
|
||||
touchEvent->mLayersId = sCaptureTouchLayersId;
|
||||
for (uint32_t i = 0; i < touches.Length(); ++i) {
|
||||
Touch* touch = touches[i];
|
||||
if (!touch) {
|
||||
|
@ -72,7 +72,9 @@ class TouchManager {
|
||||
nsCOMPtr<nsIContent> mNonAnonymousTarget;
|
||||
bool mConvertToPointer;
|
||||
};
|
||||
|
||||
static nsDataHashtable<nsUint32HashKey, TouchInfo>* sCaptureTouchList;
|
||||
static layers::LayersId sCaptureTouchLayersId;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -185,6 +185,7 @@ WidgetTouchEvent MultiTouchInput::ToWidgetTouchEvent(nsIWidget* aWidget) const {
|
||||
event.mTimeStamp = this->mTimeStamp;
|
||||
event.mFlags.mHandledByAPZ = mHandledByAPZ;
|
||||
event.mFocusSequenceNumber = mFocusSequenceNumber;
|
||||
event.mLayersId = mLayersId;
|
||||
|
||||
for (size_t i = 0; i < mTouches.Length(); i++) {
|
||||
*event.mTouches.AppendElement() = mTouches[i].ToNewDOMTouch();
|
||||
|
Loading…
Reference in New Issue
Block a user