Closed Bug 1014189 Opened 11 years ago Closed 10 years ago

APZ potentially doesn't untransform events correctly when there are touch listeners

Categories

(Core :: Panning and Zooming, defect)

All
Gonk (Firefox OS)
defect
Not set
normal

Tracking

()

RESOLVED INVALID

People

(Reporter: kats, Unassigned)

References

Details

There is a scenario where the APZ code may not untransform events correctly. Consider the case where there is a page scrolled to y=500 CSS pixels, and the user delivers three events: a touchstart at (screen-relative pixels) y=100, a touchmove at y=200, and a second touchmove at y=300. If there are no touch event listeners registered, and the page is pannable, then the two touchmove events will cause the page to pan as soon as the events are delivered. Therefore, the async transform will get used when untransforming the events. That is, the content will receive all the events at y=600 CSS pixels. However, if there is a touch event listener, then the touch events get queued up in the APZ and don't cause a pan to happen right away. Instead, we wait potentially up to 300ms for content to call preventDefault on the events before doing the pan. During this time, incoming touch events are still "untransformed" and passed along to content, but in this case the untransformation will be a no-op because the APZC hasn't done any panning yet. Once it receives word that preventDefault() was not called, it then executes the touch events and does the panning. This results in events already passed along to content not having the correct coordinates; in this example they would have CSS coordinates y=600, 700, and 800. Fixing this requires that input events going into the APZ block until we know whether or not the block has been prevent-defaulted, which is a significant change to event routing. Therefore I'm making this block the input-thread bug; hopefully this can be addressed as part of that work. Note that in practice we may not even be hitting this case as it requires a perfect storm of conditions to trigger: the page needs to have touch event listeners but not be prevent-defaulting the events, and the timing has to work out that we get a significant number of touch events while in the WAITING_CONTENT_RESPONSE state where we don't know whether or not content has responded. Additionally, the panning threshold we have in APZC might mask this problem to some extent because it effectively keeps the async transform empty for a little bit longer.
Thinking about this further I realize now that there isn't actually anything to fix here. For starters, there's no way we can process the pan before the touch listener gets it (because of the prevent-default problem). Also, the touch listener should get the actual coordinates of what the user is touching (which would be 600,700,800) not what the user would have touched in some alternate reality where the touch listener didn't exist. If the touch listener does decide to prevent-default the events then this should be based on the actual coordinates the finger is moving around on.
Status: NEW → RESOLVED
Closed: 10 years ago
Resolution: --- → INVALID
You need to log in before you can comment on or make changes to this bug.