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];