mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 06:43:32 +00:00
Bug 1785754 - Return HandledByContent (eagerly) for touches prevented by touch-action. r=dlrobertson,hiro,geckoview-reviewers,m_kato
Note, changes to the delayed-result codepath are not required because touched prevented by touch-action always get an eager HandledByContent result. Differential Revision: https://phabricator.services.mozilla.com/D164586
This commit is contained in:
parent
7b3b788267
commit
abcee8d2c9
@ -74,11 +74,28 @@ void APZEventResult::SetStatusForTouchEvent(
|
||||
const InputBlockState& aBlock, TargetConfirmationFlags aFlags,
|
||||
PointerEventsConsumableFlags aConsumableFlags,
|
||||
const AsyncPanZoomController* aTarget) {
|
||||
// Note, we need to continue setting mStatus to eIgnore in the {mHasRoom=true,
|
||||
// mAllowedByTouchAction=false} case because this is the behaviour expected by
|
||||
// APZEventState::ProcessTouchEvent() when it determines when to send a
|
||||
// `pointercancel` event. TODO: Use something more descriptive than
|
||||
// nsEventStatus for this purpose.
|
||||
bool consumable = aConsumableFlags.IsConsumable();
|
||||
mStatus =
|
||||
consumable ? nsEventStatus_eConsumeDoDefault : nsEventStatus_eIgnore;
|
||||
if (mHandledResult && !aFlags.mDispatchToContent && !consumable) {
|
||||
// Set result to Unhandled if we set the status to eIgnore, unless it
|
||||
|
||||
// If the touch event's effect is disallowed by touch-action, treat it as if
|
||||
// a touch event listener had preventDefault()-ed it (i.e. return
|
||||
// HandledByContent, except we can do it eagerly rather than having to wait
|
||||
// for the listener to run).
|
||||
if (!aConsumableFlags.mAllowedByTouchAction) {
|
||||
mHandledResult =
|
||||
Some(APZHandledResult{APZHandledPlace::HandledByContent, aTarget});
|
||||
return;
|
||||
}
|
||||
|
||||
if (mHandledResult && !aFlags.mDispatchToContent &&
|
||||
!aConsumableFlags.mHasRoom) {
|
||||
// Set result to Unhandled if we have no room to scroll, unless it
|
||||
// was HandledByContent because we're over a dispatch-to-content region,
|
||||
// in which case it should remain HandledByContent.
|
||||
mHandledResult->mPlace = APZHandledPlace::Unhandled;
|
||||
|
@ -22,6 +22,26 @@ body {
|
||||
</style>
|
||||
<body>
|
||||
<div style="width: 100%; height: 50vh; touch-action: auto;"></div>
|
||||
<div style="width: 100%; height: 50vh; touch-action: none;"></div>
|
||||
<script>
|
||||
const searchParams = new URLSearchParams(location.search);
|
||||
let div = document.querySelector('div');
|
||||
if (searchParams.has("subframe")) {
|
||||
const scrolledContents = document.createElement("div");
|
||||
scrolledContents.style.height = "100%";
|
||||
|
||||
div.appendChild(scrolledContents);
|
||||
div.style.overflow = "auto";
|
||||
|
||||
div = scrolledContents;
|
||||
}
|
||||
if (searchParams.has("scrollable")) {
|
||||
// Scrollable for dynamic toolbar purposes.
|
||||
div.style.height = "100vh";
|
||||
}
|
||||
div.style.touchAction = searchParams.get("touch-action");
|
||||
if (searchParams.has("event")) {
|
||||
div.addEventListener("touchstart", e => {});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -85,25 +85,66 @@ class InputResultDetailTest : BaseSessionTest() {
|
||||
@Test
|
||||
fun testTouchAction() {
|
||||
sessionRule.display?.run { setDynamicToolbarMaxHeight(20) }
|
||||
setupDocument(TOUCH_ACTION_HTML_PATH)
|
||||
|
||||
var value = sessionRule.waitForResult(sendDownEvent(50f, 20f))
|
||||
assertResultDetail(
|
||||
"`touch-action: auto`",
|
||||
value,
|
||||
PanZoomController.INPUT_RESULT_HANDLED,
|
||||
PanZoomController.SCROLLABLE_FLAG_BOTTOM,
|
||||
(PanZoomController.OVERSCROLL_FLAG_HORIZONTAL or PanZoomController.OVERSCROLL_FLAG_VERTICAL)
|
||||
)
|
||||
for (subframe in arrayOf(true, false)) {
|
||||
for (scrollable in arrayOf(true, false)) {
|
||||
for (event in arrayOf(true, false)) {
|
||||
for (touchAction in arrayOf("auto", "none", "pan-x", "pan-y")) {
|
||||
var url = TOUCH_ACTION_HTML_PATH + "?"
|
||||
if (subframe) {
|
||||
url += "subframe&"
|
||||
}
|
||||
if (scrollable) {
|
||||
url += "scrollable&"
|
||||
}
|
||||
if (event) {
|
||||
url += "event&"
|
||||
}
|
||||
url += ("touch-action=" + touchAction)
|
||||
|
||||
value = sessionRule.waitForResult(sendDownEvent(50f, 75f))
|
||||
assertResultDetail(
|
||||
"`touch-action: none`",
|
||||
value,
|
||||
PanZoomController.INPUT_RESULT_UNHANDLED,
|
||||
PanZoomController.SCROLLABLE_FLAG_NONE,
|
||||
PanZoomController.OVERSCROLL_FLAG_NONE
|
||||
)
|
||||
setupDocument(url)
|
||||
|
||||
// Since sendDownEvent() just sends a touch-down, APZ doesn't
|
||||
// yet know the direction, hence it allows scrolling in both
|
||||
// the pan-x and pan-y cases.
|
||||
var expectedPlace = if (touchAction == "none" || (subframe && scrollable)) {
|
||||
PanZoomController.INPUT_RESULT_HANDLED_CONTENT
|
||||
} else if (scrollable) {
|
||||
PanZoomController.INPUT_RESULT_HANDLED
|
||||
} else {
|
||||
PanZoomController.INPUT_RESULT_UNHANDLED
|
||||
}
|
||||
|
||||
var expectedScrollableDirections = if (scrollable) {
|
||||
PanZoomController.SCROLLABLE_FLAG_BOTTOM
|
||||
} else {
|
||||
PanZoomController.SCROLLABLE_FLAG_NONE
|
||||
}
|
||||
|
||||
// FIXME: There are a couple of bugs here:
|
||||
// 1. In the case where touch-action allows the scrolling, the
|
||||
// overscroll directions shouldn't depend on the presence of
|
||||
// an event handler, but they do.
|
||||
// 2. In the case where touch-action doesn't allow the scrolling,
|
||||
// the overscroll directions should probably be NONE.
|
||||
var expectedOverscrollDirections = if (touchAction != "none" && !scrollable && event) {
|
||||
PanZoomController.OVERSCROLL_FLAG_NONE
|
||||
} else {
|
||||
(PanZoomController.OVERSCROLL_FLAG_HORIZONTAL or PanZoomController.OVERSCROLL_FLAG_VERTICAL)
|
||||
}
|
||||
|
||||
var value = sessionRule.waitForResult(sendDownEvent(50f, 20f))
|
||||
assertResultDetail(
|
||||
"`subframe=$subframe, scrollable=$scrollable, event=$event, touch-action=$touchAction`",
|
||||
value,
|
||||
expectedPlace,
|
||||
expectedScrollableDirections,
|
||||
expectedOverscrollDirections
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@WithDisplay(width = 100, height = 100)
|
||||
|
@ -523,9 +523,9 @@ class PanZoomControllerTest : BaseSessionTest() {
|
||||
setupDocument(TOUCH_ACTION_WHEEL_LISTENER_HTML_PATH)
|
||||
var value = sessionRule.waitForResult(sendDownEvent(50f, 50f))
|
||||
assertThat(
|
||||
"The input result should be UNHANDLED",
|
||||
"The input result should be HANDLED_CONTENT",
|
||||
value,
|
||||
equalTo(PanZoomController.INPUT_RESULT_UNHANDLED)
|
||||
equalTo(PanZoomController.INPUT_RESULT_HANDLED_CONTENT)
|
||||
)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user