Cherry-pick 86b293809dda. rdar://141662290
Cherry-pick 474e17e9c9a8. rdar://141662290
REGRESSION (iOS 18.2): Scrolling does not work on websites built on Flutter
https://bugs.webkit.org/show_bug.cgi?id=284859
rdar://140119315
Reviewed by Wenson Hsieh and Richard Robinson.
"Child" events (coalesced and predicted events) of a given pointer event must
have the same pointer identifier as their parent; the spec says so, and Flutter
strongly depends on this.
We did not implement it this way; the child events get a pointer identifier of 0.
* Source/WebKit/UIProcess/ios/WKTouchEventsGestureRecognizer.mm:
(-[WKTouchEventsGestureRecognizer _touchEventForChildTouch:withParent:]):
(-[WKTouchEventsGestureRecognizer _recordTouches:ofType:forEvent:]):
(-[WKTouchEventsGestureRecognizer _processTouches:withEvent:type:]):
(-[WKTouchEventsGestureRecognizer _touchEventForTouch:]): Deleted.
(-[WKTouchEventsGestureRecognizer _recordTouches:type:coalescedTouches:predictedTouches:]):
Instead of adding coalesced and predicted events from a random touch, take them
from the first touch, and propagate the pointer identifier from the first touch
onto them.
Later, we should get them from *each* touch instead of just one, to properly
support multiple touches.
Canonical link: https://commits.webkit.org/287988@main
Canonical link: https://commits.webkit.org/283286.605@safari-7620.2.4.10-branch
diff --git a/Source/WebKit/UIProcess/ios/WKTouchEventsGestureRecognizer.mm b/Source/WebKit/UIProcess/ios/WKTouchEventsGestureRecognizer.mm
index 8adc3df..9e70e48 100644
--- a/Source/WebKit/UIProcess/ios/WKTouchEventsGestureRecognizer.mm
+++ b/Source/WebKit/UIProcess/ios/WKTouchEventsGestureRecognizer.mm
@@ -229,7 +229,7 @@
}
}
-- (WebKit::WKTouchEvent)_touchEventForTouch:(UITouch *)touch
+- (WebKit::WKTouchEvent)_touchEventForChildTouch:(UITouch *)touch withParent:(const WebKit::WKTouchPoint&)parentTouchPoint
{
auto locationInWindow = [touch locationInView:nil];
auto locationInViewport = [[self view] convertPoint:locationInWindow fromView:nil];
@@ -237,7 +237,7 @@
WebKit::WKTouchPoint touchPoint;
touchPoint.locationInDocumentCoordinates = locationInViewport;
touchPoint.locationInScreenCoordinates = locationInWindow;
- touchPoint.identifier = 0;
+ touchPoint.identifier = parentTouchPoint.identifier;
touchPoint.phase = touch.phase;
touchPoint.majorRadiusInScreenCoordinates = touch.majorRadius;
touchPoint.force = touch.maximumPossibleForce > 0 ? touch.force / touch.maximumPossibleForce : 0;
@@ -262,7 +262,7 @@
return event;
}
-- (void)_recordTouches:(NSSet<UITouch *> *)touches type:(WebKit::WKTouchEventType)type coalescedTouches:(NSArray<UITouch *> *)coalescedTouches predictedTouches:(NSArray<UITouch *> *)predictedTouches
+- (void)_recordTouches:(NSSet<UITouch *> *)touches ofType:(WebKit::WKTouchEventType)type forEvent:(UIEvent *)event
{
_lastTouchEvent.type = type;
_lastTouchEvent.inJavaScriptGesture = false;
@@ -287,14 +287,6 @@
_lastTouchEvent.coalescedEvents = { };
_lastTouchEvent.predictedEvents = { };
- if (type == WebKit::WKTouchEventType::Change) {
- for (UITouch *coalescedTouch in coalescedTouches)
- _lastTouchEvent.coalescedEvents.append([self _touchEventForTouch:coalescedTouch]);
-
- for (UITouch *predictedTouch in predictedTouches)
- _lastTouchEvent.predictedEvents.append([self _touchEventForTouch:predictedTouch]);
- }
-
NSUInteger touchIndex = 0;
[_activeTouchesByIdentifier removeAllObjects];
@@ -343,6 +335,15 @@
touchPoint.azimuthAngle = 0;
}
+ // FIXME (284852): Instead of retrieving coalesced and predicted touches from the first touch, we should store them per-touch.
+ if (!touchIndex && type == WebKit::WKTouchEventType::Change) {
+ for (UITouch *coalescedTouch in [event coalescedTouchesForTouch:touch])
+ _lastTouchEvent.coalescedEvents.append([self _touchEventForChildTouch:coalescedTouch withParent:touchPoint]);
+
+ for (UITouch *predictedTouch in [event predictedTouchesForTouch:touch])
+ _lastTouchEvent.predictedEvents.append([self _touchEventForChildTouch:predictedTouch withParent:touchPoint]);
+ }
+
++touchIndex;
if ((touchPoint.phase == UITouchPhaseEnded) || (touchPoint.phase == UITouchPhaseCancelled)) {
@@ -465,7 +466,7 @@
if (lastExpectedWKEventTypeForTouches(touches) != type)
return;
- [self _recordTouches:touches type:type coalescedTouches:[event coalescedTouchesForTouch:touches.anyObject] predictedTouches:[event predictedTouchesForTouch:touches.anyObject]];
+ [self _recordTouches:touches ofType:type forEvent:event];
[self performAction];