forked from mirrors/gecko-dev
Bug 1895742 - Return HandledByContent for touches prevented by touch-action. r=botond,geckoview-reviewers,tthibaud, a=dmeehan
Similar to what we did in bug 1785754, specifically in hg.mozilla.org/integration/autoland/rev/e05ed4cedf9f , but not eager cases. Differential Revision: https://phabricator.services.mozilla.com/D212487
This commit is contained in:
parent
8ff7f2494c
commit
7861db93b4
5 changed files with 66 additions and 20 deletions
|
|
@ -876,7 +876,7 @@ AsyncPanZoomController::GetPinchLockMode() {
|
|||
}
|
||||
|
||||
PointerEventsConsumableFlags AsyncPanZoomController::ArePointerEventsConsumable(
|
||||
TouchBlockState* aBlock, const MultiTouchInput& aInput) {
|
||||
TouchBlockState* aBlock, const MultiTouchInput& aInput) const {
|
||||
uint32_t touchPoints = aInput.mTouches.Length();
|
||||
if (touchPoints == 0) {
|
||||
// Cant' do anything with zero touch points
|
||||
|
|
|
|||
|
|
@ -1536,7 +1536,7 @@ class AsyncPanZoomController {
|
|||
* govern dynamic toolbar and pull-to-refresh behaviour).
|
||||
*/
|
||||
PointerEventsConsumableFlags ArePointerEventsConsumable(
|
||||
TouchBlockState* aBlock, const MultiTouchInput& aInput);
|
||||
TouchBlockState* aBlock, const MultiTouchInput& aInput) const;
|
||||
|
||||
/**
|
||||
* Clear internal state relating to touch input handling.
|
||||
|
|
|
|||
|
|
@ -1007,10 +1007,11 @@ void InputQueue::SetBrowserGestureResponse(uint64_t aInputBlockId,
|
|||
ProcessQueue();
|
||||
}
|
||||
|
||||
static APZHandledResult GetHandledResultFor(
|
||||
const AsyncPanZoomController* aApzc,
|
||||
const InputBlockState& aCurrentInputBlock, nsEventStatus aEagerStatus) {
|
||||
if (aCurrentInputBlock.ShouldDropEvents()) {
|
||||
static APZHandledResult GetHandledResultFor(const AsyncPanZoomController* aApzc,
|
||||
InputBlockState* aCurrentInputBlock,
|
||||
nsEventStatus aEagerStatus,
|
||||
const InputData& aEvent) {
|
||||
if (aCurrentInputBlock->ShouldDropEvents()) {
|
||||
return APZHandledResult{APZHandledPlace::HandledByContent, aApzc};
|
||||
}
|
||||
|
||||
|
|
@ -1018,6 +1019,20 @@ static APZHandledResult GetHandledResultFor(
|
|||
return APZHandledResult{APZHandledPlace::HandledByContent, aApzc};
|
||||
}
|
||||
|
||||
if (aEvent.mInputType == MULTITOUCH_INPUT) {
|
||||
// If the event is a multi touch event and is disallowed by touch-action,
|
||||
// treat it as if a touch event listener had preventDefault()-ed it.
|
||||
PointerEventsConsumableFlags consumableFlags =
|
||||
aApzc->ArePointerEventsConsumable(aCurrentInputBlock->AsTouchBlock(),
|
||||
aEvent.AsMultiTouchInput());
|
||||
if (!consumableFlags.mAllowedByTouchAction) {
|
||||
APZHandledResult result =
|
||||
APZHandledResult{APZHandledPlace::HandledByContent, aApzc};
|
||||
result.mOverscrollDirections = ScrollDirections();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (aApzc->IsRootContent()) {
|
||||
// If the eager status was eIgnore, we would have returned an eager result
|
||||
// of Unhandled if there had been no event handler. Now that we know the
|
||||
|
|
@ -1033,14 +1048,14 @@ static APZHandledResult GetHandledResultFor(
|
|||
}
|
||||
|
||||
bool mayTriggerPullToRefresh =
|
||||
aCurrentInputBlock.GetOverscrollHandoffChain()
|
||||
aCurrentInputBlock->GetOverscrollHandoffChain()
|
||||
->ScrollingUpWillTriggerPullToRefresh(aApzc);
|
||||
if (mayTriggerPullToRefresh) {
|
||||
return APZHandledResult{APZHandledPlace::Unhandled, aApzc, true};
|
||||
}
|
||||
|
||||
auto [willMoveDynamicToolbar, rootApzc] =
|
||||
aCurrentInputBlock.GetOverscrollHandoffChain()
|
||||
aCurrentInputBlock->GetOverscrollHandoffChain()
|
||||
->ScrollingDownWillMoveDynamicToolbar(aApzc);
|
||||
if (!willMoveDynamicToolbar) {
|
||||
return APZHandledResult{APZHandledPlace::HandledByContent, aApzc};
|
||||
|
|
@ -1113,7 +1128,8 @@ bool InputQueue::ProcessQueue() {
|
|||
"\n",
|
||||
curBlock, curBlock->GetBlockId());
|
||||
APZHandledResult handledResult =
|
||||
GetHandledResultFor(target, *curBlock, it->second.mEagerStatus);
|
||||
GetHandledResultFor(target, curBlock, it->second.mEagerStatus,
|
||||
*(mQueuedInputs[0]->Input()));
|
||||
it->second.mCallback(curBlock->GetBlockId(), handledResult);
|
||||
// The callback is one-shot; discard it after calling it.
|
||||
mInputBlockCallbacks.erase(it);
|
||||
|
|
|
|||
|
|
@ -26,15 +26,43 @@
|
|||
<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%";
|
||||
switch (searchParams.get("descendants")) {
|
||||
case "subframe": {
|
||||
const scrolledContents = document.createElement("div");
|
||||
scrolledContents.style.height = "100%";
|
||||
|
||||
div.appendChild(scrolledContents);
|
||||
div.style.overflow = "auto";
|
||||
div.appendChild(scrolledContents);
|
||||
div.style.overflow = "auto";
|
||||
|
||||
div = scrolledContents;
|
||||
div = scrolledContents;
|
||||
break;
|
||||
}
|
||||
case "svg": {
|
||||
const svg = document.createElementNS(
|
||||
"http://www.w3.org/2000/svg",
|
||||
"svg"
|
||||
);
|
||||
svg.setAttribute("viewBox", "0 0 16 8");
|
||||
svg.style.position = "absolute";
|
||||
const path = document.createElementNS(
|
||||
"http://www.w3.org/2000/svg",
|
||||
"path"
|
||||
);
|
||||
path.setAttribute("width", "100");
|
||||
path.setAttribute(
|
||||
"d",
|
||||
"M8 1a7 7 0 1 1-7 7 7 7 0 0 1 7-7zm0 3a1 1 0 1 1-1 1 1 1 0 0 1 1-1zm0 3a1 1 0 0 1 1 1v3a1 1 0 0 1-2 0V8a1 1 0 0 1 1-1z"
|
||||
);
|
||||
path.setAttribute("fill-rule", "evenodd");
|
||||
path.setAttribute("fill", "green");
|
||||
svg.appendChild(path);
|
||||
|
||||
div.appendChild(svg);
|
||||
div.style.position = "absolute";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (searchParams.has("scrollable")) {
|
||||
// Scrollable for dynamic toolbar purposes.
|
||||
div.style.height = "100vh";
|
||||
|
|
|
|||
|
|
@ -80,13 +80,15 @@ class InputResultDetailTest : BaseSessionTest() {
|
|||
fun testTouchAction() {
|
||||
sessionRule.display?.run { setDynamicToolbarMaxHeight(20) }
|
||||
|
||||
for (subframe in arrayOf(true, false)) {
|
||||
for (descendants in arrayOf("subframe", "svg", "nothing")) {
|
||||
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&"
|
||||
when (descendants) {
|
||||
"subframe" -> url += "descendants=subframe&"
|
||||
"svg" -> url += "descendants=svg&"
|
||||
"nothing" -> {}
|
||||
}
|
||||
if (scrollable) {
|
||||
url += "scrollable&"
|
||||
|
|
@ -103,7 +105,7 @@ class InputResultDetailTest : BaseSessionTest() {
|
|||
// the pan-x and pan-y cases.
|
||||
var expectedPlace = if (touchAction == "none") {
|
||||
PanZoomController.INPUT_RESULT_HANDLED_CONTENT
|
||||
} else if (scrollable && !subframe) {
|
||||
} else if (scrollable && descendants != "subframe") {
|
||||
PanZoomController.INPUT_RESULT_HANDLED
|
||||
} else {
|
||||
PanZoomController.INPUT_RESULT_UNHANDLED
|
||||
|
|
@ -123,7 +125,7 @@ class InputResultDetailTest : BaseSessionTest() {
|
|||
|
||||
var value = sessionRule.waitForResult(sendDownEvent(50f, 20f))
|
||||
assertResultDetail(
|
||||
"`subframe=$subframe, scrollable=$scrollable, event=$event, touch-action=$touchAction`",
|
||||
"`descendants=$descendants, scrollable=$scrollable, event=$event, touch-action=$touchAction`",
|
||||
value,
|
||||
expectedPlace,
|
||||
expectedScrollableDirections,
|
||||
|
|
|
|||
Loading…
Reference in a new issue