Title: [245639] trunk
Revision
245639
Author
grao...@webkit.org
Date
2019-05-22 12:58:15 -0700 (Wed, 22 May 2019)

Log Message

[iOS] Compatibility mouse events aren't prevented by calling preventDefault() on pointerdown
https://bugs.webkit.org/show_bug.cgi?id=198124
<rdar://problem/50410863>

Reviewed by Tim Horton.

LayoutTests/imported/w3c:

We add basic support to run a test that wasn't specifically designed for a touch-based interaction such that the test
at imported/w3c/web-platform-tests/pointerevents/pointerevent_suppress_compat_events_on_click.html may run on iOS. The
trick here is to add a pause after a touch ends to avoid the likelihood or two tap gestures triggering a double tap.

* web-platform-tests/resources/testdriver-vendor.js:

Source/WebCore:

This fix builds atop the one made for wkb.ug/198072 which fixes this bug on macOS alone.

In order to correctly prevent "compatibility" mouse events from being dispatched when the initial "pointerdown" event had preventDefault()
called while handled, we need to pass the PointerID for the touch that triggered a tap gesture in the UI process down in the Web process
and into the resulting PlatformMouseEvent. This will allow upon dispatch of a PlatformMouseEvent to call into PointerCaptureController
to identify if the dispatch of mouse events is allowed for the event's PointerID.

To support this, some refactoring was required. The PointerID header is now under platform/ such that PlatformMouseEvent may safely use it.
Additionally, PointerEvent::defaultMousePointerIdentifier() is now a global mousePointerID defined in PointerID.h.

Finally, PointerCaptureController::touchEndedOrWasCancelledForIdentifier() has been renamed to PointerCaptureController::touchWithIdentifierWasRemoved() and
has WEBCORE_EXPORT such that it may be called from WebKit as the indication that a pointer is no longer active will now be initiated in WebKit
on the UI process side.

Testing is covered by the pre-existing imported/w3c/web-platform-tests/pointerevents/pointerevent_suppress_compat_events_on_click.html
which will now run on iOS through a change to WebKitAdditions.

* Headers.cmake:
* WebCore.xcodeproj/project.pbxproj:
* dom/Element.cpp:
(WebCore::Element::dispatchMouseEvent): When dealing with a mouse event on iOS, check whether the mouse event's PointerID allows for compatibility
mouse events to be dispatched using PointerCaptureController::preventsCompatibilityMouseEventsForIdentifier(). The "click" event is not a compatibility
mouse event.
* dom/PointerEvent.h:
* page/PointerCaptureController.cpp:
(WebCore::PointerCaptureController::PointerCaptureController):
(WebCore::PointerCaptureController::touchWithIdentifierWasRemoved):
(WebCore::PointerCaptureController::touchEndedOrWasCancelledForIdentifier): Deleted.
* page/PointerCaptureController.h:
* platform/PlatformMouseEvent.h:
(WebCore::PlatformMouseEvent::PlatformMouseEvent):
(WebCore::PlatformMouseEvent::pointerId const):
* platform/PointerID.h: Renamed from Source/WebCore/dom/PointerID.h.
(WebCore::mousePointerID):

Source/WebKit:

In order to correctly prevent "compatibility" mouse events from being dispatched when the initial "pointerdown" event had preventDefault()
called while handled, we need to pass the PointerID for the touch that triggered a tap gesture in the UI process down in the Web process
and into the resulting PlatformMouseEvent.

This means we need to identify the touch identifier, which is the same as the PointerID used for Pointer Events, in the single tap gesture
recognizer, an instance of WKSyntheticTapGestureRecognizer. To do this, we subclass the -[UIResponder touchesEnded:withEvent:] method and
track the touch identifier as the lastActiveTouchIdentifier, a new public property of WKSyntheticTapGestureRecognizer. To allow for this,
we need the support of the content view's UIWebTouchEventsGestureRecognizer which is exposed to the WKSyntheticTapGestureRecognizer as its
supportingWebTouchEventsGestureRecognizer property. This lastActiveTouchIdentifier property is cleared as the gesture recognizer is reset.

This allows the content view to pass the PointerID down to the Web process starting from -[WKContentView _singleTapRecognized:], going
through WebPageProxy::commitPotentialTap() and eventually WebPage::completeSyntheticClick().

While we used to tell the PointerCaptureController that a PointerID was no longer active when a given touch ended or was canceled (in
WebKitAdditions code), we can no longer do this as the dispatch of a synthetic tap is performed asynchronously and will happen past the
dispatch of "pointerup" and "pointercancel" Pointer Events. To clear inactive PointerIDs from the PointerCaptureController, we add a new
touchWithIdentifierWasRemoved() method on the WebPage and its proxy. When the WKSyntheticTapGestureRecognizer resets and -[WKContentView _singleTapDidReset:]
is called, we call that method which allows for only active PointerIDs to be tracked by the PointerCaptureController.

* UIProcess/WebPageProxy.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView setupInteraction]):
(-[WKContentView cleanupInteraction]):
(-[WKContentView _singleTapDidReset:]):
(-[WKContentView _singleTapRecognized:]):
* UIProcess/ios/WKSyntheticTapGestureRecognizer.h:
* UIProcess/ios/WKSyntheticTapGestureRecognizer.m:
(-[WKSyntheticTapGestureRecognizer reset]):
(-[WKSyntheticTapGestureRecognizer touchesEnded:withEvent:]):
* UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::touchWithIdentifierWasRemoved):
(WebKit::WebPageProxy::commitPotentialTap):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::dispatchSyntheticMouseMove):
(WebKit::WebPage::handleSyntheticClick):
(WebKit::WebPage::completePendingSyntheticClickForContentChangeObserver):
(WebKit::WebPage::completeSyntheticClick):
(WebKit::WebPage::commitPotentialTap):
(WebKit::WebPage::touchWithIdentifierWasRemoved):

LayoutTests:

We're adding an iOS-specific expectation since this test prints out the pointer type detected while it runs, which is "touch"
on iOS and "mouse" in the expectation that already exists for macOS.

* platform/ios/imported/w3c/web-platform-tests/pointerevents/pointerevent_suppress_compat_events_on_click-expected.txt: Added.

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (245638 => 245639)


--- trunk/LayoutTests/ChangeLog	2019-05-22 19:27:49 UTC (rev 245638)
+++ trunk/LayoutTests/ChangeLog	2019-05-22 19:58:15 UTC (rev 245639)
@@ -1,3 +1,16 @@
+2019-05-22  Antoine Quint  <grao...@apple.com>
+
+        [iOS] Compatibility mouse events aren't prevented by calling preventDefault() on pointerdown
+        https://bugs.webkit.org/show_bug.cgi?id=198124
+        <rdar://problem/50410863>
+
+        Reviewed by Tim Horton.
+
+        We're adding an iOS-specific expectation since this test prints out the pointer type detected while it runs, which is "touch"
+        on iOS and "mouse" in the expectation that already exists for macOS.
+
+        * platform/ios/imported/w3c/web-platform-tests/pointerevents/pointerevent_suppress_compat_events_on_click-expected.txt: Added.
+
 2019-05-22  Jiewen Tan  <jiewen_...@apple.com>
 
         [WebAuthN] Support Attestation Conveyance Preference

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (245638 => 245639)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2019-05-22 19:27:49 UTC (rev 245638)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2019-05-22 19:58:15 UTC (rev 245639)
@@ -1,3 +1,17 @@
+2019-05-22  Antoine Quint  <grao...@apple.com>
+
+        [iOS] Compatibility mouse events aren't prevented by calling preventDefault() on pointerdown
+        https://bugs.webkit.org/show_bug.cgi?id=198124
+        <rdar://problem/50410863>
+
+        Reviewed by Tim Horton.
+
+        We add basic support to run a test that wasn't specifically designed for a touch-based interaction such that the test
+        at imported/w3c/web-platform-tests/pointerevents/pointerevent_suppress_compat_events_on_click.html may run on iOS. The
+        trick here is to add a pause after a touch ends to avoid the likelihood or two tap gestures triggering a double tap.
+
+        * web-platform-tests/resources/testdriver-vendor.js:
+
 2019-05-22  Youenn Fablet  <you...@apple.com>
 
         Implement Feature policy self/none/* parsing

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver-vendor.js (245638 => 245639)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver-vendor.js	2019-05-22 19:27:49 UTC (rev 245638)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver-vendor.js	2019-05-22 19:58:15 UTC (rev 245639)
@@ -46,7 +46,7 @@
     });
 }
 
-function dispatchTouchActions(actions)
+function dispatchTouchActions(actions, options = { insertPauseAfterPointerUp: false })
 {
     if (!window.testRunner || typeof window.testRunner.runUIScript !== "function")
         return Promise.reject(new Error("window.testRunner.runUIScript() is undefined."));
@@ -99,6 +99,9 @@
             touch.x = x;
             touch.y = y;
             id++;
+            // We need to add a pause after a pointer up to ensure that a subsequent tap may be recognized as such.
+            if (options.insertPauseAfterPointerUp)
+                timeOffsetIncrease = 0.5;
             break;
         case "pause":
             timeOffsetIncrease = action.duration / 1000;
@@ -173,8 +176,10 @@
 
     logDebug(() => JSON.stringify(pointerSource));
 
+    if (pointerType === "touch")
+        return dispatchTouchActions(pointerSource.actions);
+    if ("createTouch" in document)
+        return dispatchTouchActions(pointerSource.actions, { insertPauseAfterPointerUp: true });
     if (pointerType === "mouse")
         return dispatchMouseActions(pointerSource.actions);
-    if (pointerType === "touch")
-        return dispatchTouchActions(pointerSource.actions);
 };

Added: trunk/LayoutTests/platform/ios/imported/w3c/web-platform-tests/pointerevents/pointerevent_suppress_compat_events_on_click-expected.txt (0 => 245639)


--- trunk/LayoutTests/platform/ios/imported/w3c/web-platform-tests/pointerevents/pointerevent_suppress_compat_events_on_click-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/ios/imported/w3c/web-platform-tests/pointerevents/pointerevent_suppress_compat_events_on_click-expected.txt	2019-05-22 19:58:15 UTC (rev 245639)
@@ -0,0 +1,20 @@
+Pointer Event: Suppress compatibility mouse events on click
+
+When a pointerdown is canceled, a click/tap shouldn't fire any compatibility mouse events except click event.
+
+Click or tap on Target0.
+Click or tap on Target1.
+Click Done.
+Target0
+Target1
+Done
+The following pointer types were detected: touch.
+
+The following events were logged: click@target0, mousedown@target1, mouseup@target1, click@target1.
+
+
+PASS Suppress compat mouse events on click 
+PASS primary pointer pointerdown@target0 
+PASS primary pointer pointerdown@target1 
+PASS Event log 
+

Modified: trunk/Source/WebCore/ChangeLog (245638 => 245639)


--- trunk/Source/WebCore/ChangeLog	2019-05-22 19:27:49 UTC (rev 245638)
+++ trunk/Source/WebCore/ChangeLog	2019-05-22 19:58:15 UTC (rev 245639)
@@ -1,3 +1,46 @@
+2019-05-22  Antoine Quint  <grao...@apple.com>
+
+        [iOS] Compatibility mouse events aren't prevented by calling preventDefault() on pointerdown
+        https://bugs.webkit.org/show_bug.cgi?id=198124
+        <rdar://problem/50410863>
+
+        Reviewed by Tim Horton.
+
+        This fix builds atop the one made for wkb.ug/198072 which fixes this bug on macOS alone.
+
+        In order to correctly prevent "compatibility" mouse events from being dispatched when the initial "pointerdown" event had preventDefault()
+        called while handled, we need to pass the PointerID for the touch that triggered a tap gesture in the UI process down in the Web process
+        and into the resulting PlatformMouseEvent. This will allow upon dispatch of a PlatformMouseEvent to call into PointerCaptureController
+        to identify if the dispatch of mouse events is allowed for the event's PointerID.
+
+        To support this, some refactoring was required. The PointerID header is now under platform/ such that PlatformMouseEvent may safely use it.
+        Additionally, PointerEvent::defaultMousePointerIdentifier() is now a global mousePointerID defined in PointerID.h.
+
+        Finally, PointerCaptureController::touchEndedOrWasCancelledForIdentifier() has been renamed to PointerCaptureController::touchWithIdentifierWasRemoved() and
+        has WEBCORE_EXPORT such that it may be called from WebKit as the indication that a pointer is no longer active will now be initiated in WebKit
+        on the UI process side.
+
+        Testing is covered by the pre-existing imported/w3c/web-platform-tests/pointerevents/pointerevent_suppress_compat_events_on_click.html
+        which will now run on iOS through a change to WebKitAdditions.
+
+        * Headers.cmake:
+        * WebCore.xcodeproj/project.pbxproj:
+        * dom/Element.cpp:
+        (WebCore::Element::dispatchMouseEvent): When dealing with a mouse event on iOS, check whether the mouse event's PointerID allows for compatibility
+        mouse events to be dispatched using PointerCaptureController::preventsCompatibilityMouseEventsForIdentifier(). The "click" event is not a compatibility
+        mouse event.
+        * dom/PointerEvent.h:
+        * page/PointerCaptureController.cpp:
+        (WebCore::PointerCaptureController::PointerCaptureController):
+        (WebCore::PointerCaptureController::touchWithIdentifierWasRemoved):
+        (WebCore::PointerCaptureController::touchEndedOrWasCancelledForIdentifier): Deleted.
+        * page/PointerCaptureController.h:
+        * platform/PlatformMouseEvent.h:
+        (WebCore::PlatformMouseEvent::PlatformMouseEvent):
+        (WebCore::PlatformMouseEvent::pointerId const):
+        * platform/PointerID.h: Renamed from Source/WebCore/dom/PointerID.h.
+        (WebCore::mousePointerID):
+
 2019-05-22  Jiewen Tan  <jiewen_...@apple.com>
 
         [WebAuthN] Support Attestation Conveyance Preference

Modified: trunk/Source/WebCore/Headers.cmake (245638 => 245639)


--- trunk/Source/WebCore/Headers.cmake	2019-05-22 19:27:49 UTC (rev 245638)
+++ trunk/Source/WebCore/Headers.cmake	2019-05-22 19:58:15 UTC (rev 245639)
@@ -420,7 +420,6 @@
     dom/NodeRenderStyle.h
     dom/NodeTraversal.h
     dom/OverflowEvent.h
-    dom/PointerID.h
     dom/Position.h
     dom/ProcessingInstruction.h
     dom/ProgressEvent.h
@@ -928,6 +927,7 @@
     platform/PlatformTouchEvent.h
     platform/PlatformTouchPoint.h
     platform/PlatformWheelEvent.h
+    platform/PointerID.h
     platform/PopupMenu.h
     platform/PopupMenuClient.h
     platform/PopupMenuStyle.h

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (245638 => 245639)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2019-05-22 19:27:49 UTC (rev 245638)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2019-05-22 19:58:15 UTC (rev 245639)
@@ -931,7 +931,7 @@
 		316FE1180E6E1DA700BF6088 /* ImplicitAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 316FE10E0E6E1DA700BF6088 /* ImplicitAnimation.h */; };
 		316FE11A0E6E1DA700BF6088 /* KeyframeAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 316FE1100E6E1DA700BF6088 /* KeyframeAnimation.h */; };
 		31741AAD16636609008A5B7E /* SimulatedClickOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 31741AAB16635E45008A5B7E /* SimulatedClickOptions.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		317D3FF3215599F40034E3B9 /* PointerEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 317D3FF2215599E30034E3B9 /* PointerEvent.h */; };
+		317D3FF3215599F40034E3B9 /* PointerEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 317D3FF2215599E30034E3B9 /* PointerEvent.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		31815A311F9A6C8F00FCBF89 /* ImageBitmap.h in Headers */ = {isa = PBXBuildFile; fileRef = 31D26BBF1F86D189008FF255 /* ImageBitmap.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		318436DE21B9DAAF00ED383E /* WebGPULayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 318436DB21B9DAA000ED383E /* WebGPULayer.h */; };
 		318891611AB7EEA100EA627B /* missingim...@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = CDF419991AB0DA14004E64E1 /* missingim...@3x.png */; };
@@ -17009,11 +17009,11 @@
 		1CA0C2F621EEDAD200A11860 /* AST */ = {
 			isa = PBXGroup;
 			children = (
-				5215862C229377B7005925EF /* WHLSLAST.h */,
 				1C840B9021EC30F900D0500D /* WHLSLAddressSpace.h */,
 				C21BF72521CD89E200227979 /* WHLSLArrayReferenceType.h */,
 				C21BF70921CD89CA00227979 /* WHLSLArrayType.h */,
 				C21BF73021CD89ED00227979 /* WHLSLAssignmentExpression.h */,
+				5215862C229377B7005925EF /* WHLSLAST.h */,
 				C21BF70A21CD89CB00227979 /* WHLSLBaseFunctionAttribute.h */,
 				C21BF6FA21CD89BE00227979 /* WHLSLBaseSemantic.h */,
 				C21BF71E21CD89DC00227979 /* WHLSLBlock.h */,
@@ -25314,6 +25314,7 @@
 				BCBB8AB513F1AFB000734DF0 /* PODInterval.h */,
 				BCBB8AB613F1AFB000734DF0 /* PODIntervalTree.h */,
 				BCBB8AB713F1AFB000734DF0 /* PODRedBlackTree.h */,
+				71EADCD622087E6D0065A45F /* PointerID.h */,
 				0668E1890ADD9624004128E0 /* PopupMenu.h */,
 				ABC128760B33AA6D00C693D5 /* PopupMenuClient.h */,
 				BC3BE12A0E98092F00835588 /* PopupMenuStyle.h */,
@@ -27475,7 +27476,6 @@
 				317D3FF1215599E20034E3B9 /* PointerEvent.cpp */,
 				317D3FF2215599E30034E3B9 /* PointerEvent.h */,
 				317D3FEF215599E10034E3B9 /* PointerEvent.idl */,
-				71EADCD622087E6D0065A45F /* PointerID.h */,
 				5189F0DD10B46B0E00F3C739 /* PopStateEvent.cpp */,
 				5174E20810A1F44F00F95E6F /* PopStateEvent.h */,
 				5174E20B10A1F49A00F95E6F /* PopStateEvent.idl */,

Modified: trunk/Source/WebCore/dom/Element.cpp (245638 => 245639)


--- trunk/Source/WebCore/dom/Element.cpp	2019-05-22 19:27:49 UTC (rev 245638)
+++ trunk/Source/WebCore/dom/Element.cpp	2019-05-22 19:58:15 UTC (rev 245639)
@@ -303,8 +303,14 @@
 
     bool didNotSwallowEvent = true;
 
-#if ENABLE(POINTER_EVENTS) && !ENABLE(TOUCH_EVENTS)
+#if ENABLE(POINTER_EVENTS)
     if (RuntimeEnabledFeatures::sharedFeatures().pointerEventsEnabled()) {
+#if ENABLE(TOUCH_EVENTS)
+        if (auto* page = document().page()) {
+            if (mouseEvent->type() != eventNames().clickEvent && page->pointerCaptureController().preventsCompatibilityMouseEventsForIdentifier(platformEvent.pointerId()))
+                return false;
+        }
+#else
         if (auto pointerEvent = PointerEvent::create(mouseEvent)) {
             if (auto* page = document().page()) {
                 page->pointerCaptureController().dispatchEvent(*pointerEvent, this);
@@ -317,6 +323,7 @@
                     return false;
             }
         }
+#endif
     }
 #endif
 

Modified: trunk/Source/WebCore/dom/PointerEvent.h (245638 => 245639)


--- trunk/Source/WebCore/dom/PointerEvent.h	2019-05-22 19:27:49 UTC (rev 245638)
+++ trunk/Source/WebCore/dom/PointerEvent.h	2019-05-22 19:58:15 UTC (rev 245639)
@@ -40,7 +40,7 @@
 class PointerEvent final : public MouseEvent {
 public:
     struct Init : MouseEventInit {
-        PointerID pointerId { PointerEvent::defaultMousePointerIdentifier() };
+        PointerID pointerId { mousePointerID };
         double width { 1 };
         double height { 1 };
         float pressure { 0 };
@@ -85,7 +85,6 @@
     static const String& mousePointerType();
     static const String& penPointerType();
     static const String& touchPointerType();
-    static PointerID defaultMousePointerIdentifier() { return 1; }
 
     virtual ~PointerEvent();
 
@@ -113,7 +112,7 @@
     PointerEvent(const AtomicString& type, const PlatformTouchEvent&, IsCancelable isCancelable, unsigned touchIndex, bool isPrimary, Ref<WindowProxy>&&);
 #endif
 
-    PointerID m_pointerId { PointerEvent::defaultMousePointerIdentifier() };
+    PointerID m_pointerId { mousePointerID };
     double m_width { 1 };
     double m_height { 1 };
     float m_pressure { 0 };

Deleted: trunk/Source/WebCore/dom/PointerID.h (245638 => 245639)


--- trunk/Source/WebCore/dom/PointerID.h	2019-05-22 19:27:49 UTC (rev 245638)
+++ trunk/Source/WebCore/dom/PointerID.h	2019-05-22 19:58:15 UTC (rev 245639)
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2019 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#pragma once
-
-#if ENABLE(POINTER_EVENTS)
-
-namespace WebCore {
-
-using PointerID = int32_t;
-
-}
-
-#endif // ENABLE(POINTER_EVENTS)

Modified: trunk/Source/WebCore/page/PointerCaptureController.cpp (245638 => 245639)


--- trunk/Source/WebCore/page/PointerCaptureController.cpp	2019-05-22 19:27:49 UTC (rev 245638)
+++ trunk/Source/WebCore/page/PointerCaptureController.cpp	2019-05-22 19:58:15 UTC (rev 245639)
@@ -47,7 +47,7 @@
 #if !ENABLE(TOUCH_EVENTS)
     CapturingData capturingData;
     capturingData.pointerType = PointerEvent::mousePointerType();
-    m_activePointerIdsToCapturingData.set(PointerEvent::defaultMousePointerIdentifier(), capturingData);
+    m_activePointerIdsToCapturingData.set(mousePointerID, capturingData);
 #endif
 }
 
@@ -146,7 +146,7 @@
     }
 }
 
-void PointerCaptureController::touchEndedOrWasCancelledForIdentifier(PointerID pointerId)
+void PointerCaptureController::touchWithIdentifierWasRemoved(PointerID pointerId)
 {
     m_activePointerIdsToCapturingData.remove(pointerId);
 }

Modified: trunk/Source/WebCore/page/PointerCaptureController.h (245638 => 245639)


--- trunk/Source/WebCore/page/PointerCaptureController.h	2019-05-22 19:27:49 UTC (rev 245638)
+++ trunk/Source/WebCore/page/PointerCaptureController.h	2019-05-22 19:58:15 UTC (rev 245639)
@@ -52,7 +52,7 @@
     void dispatchEventForTouchAtIndex(EventTarget&, const PlatformTouchEvent&, unsigned, bool isPrimary, WindowProxy&);
 #endif
 
-    void touchEndedOrWasCancelledForIdentifier(PointerID);
+    WEBCORE_EXPORT void touchWithIdentifierWasRemoved(PointerID);
     bool hasCancelledPointerEventForIdentifier(PointerID);
     bool preventsCompatibilityMouseEventsForIdentifier(PointerID);
     void dispatchEvent(PointerEvent&, EventTarget*);

Modified: trunk/Source/WebCore/platform/PlatformMouseEvent.h (245638 => 245639)


--- trunk/Source/WebCore/platform/PlatformMouseEvent.h	2019-05-22 19:27:49 UTC (rev 245638)
+++ trunk/Source/WebCore/platform/PlatformMouseEvent.h	2019-05-22 19:58:15 UTC (rev 245639)
@@ -28,6 +28,7 @@
 
 #include "IntPoint.h"
 #include "PlatformEvent.h"
+#include "PointerID.h"
 #include <wtf/WindowsExtras.h>
 
 #if PLATFORM(GTK)
@@ -61,7 +62,7 @@
         }
 
         PlatformMouseEvent(const IntPoint& position, const IntPoint& globalPosition, MouseButton button, PlatformEvent::Type type,
-                           int clickCount, bool shiftKey, bool ctrlKey, bool altKey, bool metaKey, WallTime timestamp, double force, SyntheticClickType syntheticClickType)
+                           int clickCount, bool shiftKey, bool ctrlKey, bool altKey, bool metaKey, WallTime timestamp, double force, SyntheticClickType syntheticClickType, PointerID pointerId = mousePointerID)
             : PlatformEvent(type, shiftKey, ctrlKey, altKey, metaKey, timestamp)
             , m_position(position)
             , m_globalPosition(globalPosition)
@@ -70,6 +71,7 @@
             , m_modifierFlags(0)
             , m_force(force)
             , m_syntheticClickType(syntheticClickType)
+            , m_pointerId(pointerId)
 #if PLATFORM(MAC)
             , m_eventNumber(0)
             , m_menuTypeForEvent(0)
@@ -91,6 +93,7 @@
         unsigned modifierFlags() const { return m_modifierFlags; }
         double force() const { return m_force; }
         SyntheticClickType syntheticClickType() const { return m_syntheticClickType; }
+        PointerID pointerId() const { return m_pointerId; }
 
 #if PLATFORM(GTK) 
         explicit PlatformMouseEvent(GdkEventButton*);
@@ -121,6 +124,7 @@
         unsigned m_modifierFlags;
         double m_force { 0 };
         SyntheticClickType m_syntheticClickType { NoTap };
+        PointerID m_pointerId { mousePointerID };
 
 #if PLATFORM(MAC)
         int m_eventNumber;

Copied: trunk/Source/WebCore/platform/PointerID.h (from rev 245638, trunk/Source/WebCore/dom/PointerID.h) (0 => 245639)


--- trunk/Source/WebCore/platform/PointerID.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/PointerID.h	2019-05-22 19:58:15 UTC (rev 245639)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#pragma once
+
+namespace WebCore {
+
+using PointerID = int32_t;
+
+static PointerID mousePointerID = 1;
+
+}

Modified: trunk/Source/WebKit/ChangeLog (245638 => 245639)


--- trunk/Source/WebKit/ChangeLog	2019-05-22 19:27:49 UTC (rev 245638)
+++ trunk/Source/WebKit/ChangeLog	2019-05-22 19:58:15 UTC (rev 245639)
@@ -1,3 +1,53 @@
+2019-05-22  Antoine Quint  <grao...@apple.com>
+
+        [iOS] Compatibility mouse events aren't prevented by calling preventDefault() on pointerdown
+        https://bugs.webkit.org/show_bug.cgi?id=198124
+        <rdar://problem/50410863>
+
+        Reviewed by Tim Horton.
+
+        In order to correctly prevent "compatibility" mouse events from being dispatched when the initial "pointerdown" event had preventDefault()
+        called while handled, we need to pass the PointerID for the touch that triggered a tap gesture in the UI process down in the Web process
+        and into the resulting PlatformMouseEvent.
+
+        This means we need to identify the touch identifier, which is the same as the PointerID used for Pointer Events, in the single tap gesture
+        recognizer, an instance of WKSyntheticTapGestureRecognizer. To do this, we subclass the -[UIResponder touchesEnded:withEvent:] method and
+        track the touch identifier as the lastActiveTouchIdentifier, a new public property of WKSyntheticTapGestureRecognizer. To allow for this,
+        we need the support of the content view's UIWebTouchEventsGestureRecognizer which is exposed to the WKSyntheticTapGestureRecognizer as its
+        supportingWebTouchEventsGestureRecognizer property. This lastActiveTouchIdentifier property is cleared as the gesture recognizer is reset.
+
+        This allows the content view to pass the PointerID down to the Web process starting from -[WKContentView _singleTapRecognized:], going
+        through WebPageProxy::commitPotentialTap() and eventually WebPage::completeSyntheticClick().
+
+        While we used to tell the PointerCaptureController that a PointerID was no longer active when a given touch ended or was canceled (in
+        WebKitAdditions code), we can no longer do this as the dispatch of a synthetic tap is performed asynchronously and will happen past the
+        dispatch of "pointerup" and "pointercancel" Pointer Events. To clear inactive PointerIDs from the PointerCaptureController, we add a new
+        touchWithIdentifierWasRemoved() method on the WebPage and its proxy. When the WKSyntheticTapGestureRecognizer resets and -[WKContentView _singleTapDidReset:]
+        is called, we call that method which allows for only active PointerIDs to be tracked by the PointerCaptureController.
+
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView setupInteraction]):
+        (-[WKContentView cleanupInteraction]):
+        (-[WKContentView _singleTapDidReset:]):
+        (-[WKContentView _singleTapRecognized:]):
+        * UIProcess/ios/WKSyntheticTapGestureRecognizer.h:
+        * UIProcess/ios/WKSyntheticTapGestureRecognizer.m:
+        (-[WKSyntheticTapGestureRecognizer reset]):
+        (-[WKSyntheticTapGestureRecognizer touchesEnded:withEvent:]):
+        * UIProcess/ios/WebPageProxyIOS.mm:
+        (WebKit::WebPageProxy::touchWithIdentifierWasRemoved):
+        (WebKit::WebPageProxy::commitPotentialTap):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::dispatchSyntheticMouseMove):
+        (WebKit::WebPage::handleSyntheticClick):
+        (WebKit::WebPage::completePendingSyntheticClickForContentChangeObserver):
+        (WebKit::WebPage::completeSyntheticClick):
+        (WebKit::WebPage::commitPotentialTap):
+        (WebKit::WebPage::touchWithIdentifierWasRemoved):
+
 2019-05-22  Jiewen Tan  <jiewen_...@apple.com>
 
         [WebAuthN] Support Attestation Conveyance Preference

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (245638 => 245639)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2019-05-22 19:27:49 UTC (rev 245638)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2019-05-22 19:58:15 UTC (rev 245639)
@@ -1212,8 +1212,12 @@
 #if PLATFORM(IOS_FAMILY)
     void willStartUserTriggeredZooming();
 
+#if ENABLE(POINTER_EVENTS)
+    void touchWithIdentifierWasRemoved(WebCore::PointerID);
+#endif
+
     void potentialTapAtPosition(const WebCore::FloatPoint&, bool shouldRequestMagnificationInformation, uint64_t& requestID);
-    void commitPotentialTap(OptionSet<WebKit::WebEvent::Modifier>, uint64_t layerTreeTransactionIdAtLastTouchStart);
+    void commitPotentialTap(OptionSet<WebKit::WebEvent::Modifier>, uint64_t layerTreeTransactionIdAtLastTouchStart, WebCore::PointerID);
     void cancelPotentialTap();
     void tapHighlightAtPosition(const WebCore::FloatPoint&, uint64_t& requestID);
     void handleTap(const WebCore::FloatPoint&, OptionSet<WebKit::WebEvent::Modifier>, uint64_t layerTreeTransactionIdAtLastTouchStart);

Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (245638 => 245639)


--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2019-05-22 19:27:49 UTC (rev 245638)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2019-05-22 19:58:15 UTC (rev 245639)
@@ -727,6 +727,9 @@
     [_singleTapGestureRecognizer setDelegate:self];
     [_singleTapGestureRecognizer setGestureIdentifiedTarget:self action:@selector(_singleTapIdentified:)];
     [_singleTapGestureRecognizer setResetTarget:self action:@selector(_singleTapDidReset:)];
+#if ENABLE(POINTER_EVENTS)
+    [_singleTapGestureRecognizer setSupportingWebTouchEventsGestureRecognizer:_touchEventGestureRecognizer.get()];
+#endif
     [self addGestureRecognizer:_singleTapGestureRecognizer.get()];
 
     _nonBlockingDoubleTapGestureRecognizer = adoptNS([[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(_nonBlockingDoubleTapRecognized:)]);
@@ -864,6 +867,9 @@
     [_singleTapGestureRecognizer setDelegate:nil];
     [_singleTapGestureRecognizer setGestureIdentifiedTarget:nil action:nil];
     [_singleTapGestureRecognizer setResetTarget:nil action:nil];
+#if ENABLE(POINTER_EVENTS)
+    [_singleTapGestureRecognizer setSupportingWebTouchEventsGestureRecognizer:nil];
+#endif
     [self removeGestureRecognizer:_singleTapGestureRecognizer.get()];
 
     [_highlightLongPressGestureRecognizer setDelegate:nil];
@@ -2312,6 +2318,10 @@
 {
     ASSERT(gestureRecognizer == _singleTapGestureRecognizer);
     cancelPotentialTapIfNecessary(self);
+#if ENABLE(POINTER_EVENTS)
+    if (auto* singleTapTouchIdentifier = [_singleTapGestureRecognizer lastActiveTouchIdentifier])
+        _page->touchWithIdentifierWasRemoved([singleTapTouchIdentifier unsignedIntValue]);
+#endif
 }
 
 - (void)_doubleTapDidFail:(UITapGestureRecognizer *)gestureRecognizer
@@ -2375,7 +2385,12 @@
 
     RELEASE_LOG(ViewGestures, "Single tap recognized - commit potential tap (%p)", self);
 
-    _page->commitPotentialTap(WebKit::webEventModifierFlags(gestureRecognizerModifierFlags(gestureRecognizer)), _layerTreeTransactionIdAtLastTouchStart);
+    WebCore::PointerID pointerId = WebCore::mousePointerID;
+#if ENABLE(POINTER_EVENTS)
+    if (auto* singleTapTouchIdentifier = [_singleTapGestureRecognizer lastActiveTouchIdentifier])
+        pointerId = [singleTapTouchIdentifier unsignedIntValue];
+#endif
+    _page->commitPotentialTap(WebKit::webEventModifierFlags(gestureRecognizerModifierFlags(gestureRecognizer)), _layerTreeTransactionIdAtLastTouchStart, pointerId);
 
     if (!_isExpectingFastSingleTapCommit)
         [self _finishInteraction];

Modified: trunk/Source/WebKit/UIProcess/ios/WKSyntheticTapGestureRecognizer.h (245638 => 245639)


--- trunk/Source/WebKit/UIProcess/ios/WKSyntheticTapGestureRecognizer.h	2019-05-22 19:27:49 UTC (rev 245638)
+++ trunk/Source/WebKit/UIProcess/ios/WKSyntheticTapGestureRecognizer.h	2019-05-22 19:58:15 UTC (rev 245639)
@@ -35,6 +35,10 @@
 - (void)setGestureIdentifiedTarget:(id)target action:(SEL)action;
 - (void)setGestureFailedTarget:(id)target action:(SEL)action;
 - (void)setResetTarget:(id)target action:(SEL)action;
+#if ENABLE(POINTER_EVENTS)
+@property (nonatomic, weak) UIWebTouchEventsGestureRecognizer *supportingWebTouchEventsGestureRecognizer;
+@property (nonatomic, readonly) NSNumber *lastActiveTouchIdentifier;
+#endif
 @end
 
 #endif

Modified: trunk/Source/WebKit/UIProcess/ios/WKSyntheticTapGestureRecognizer.m (245638 => 245639)


--- trunk/Source/WebKit/UIProcess/ios/WKSyntheticTapGestureRecognizer.m	2019-05-22 19:27:49 UTC (rev 245638)
+++ trunk/Source/WebKit/UIProcess/ios/WKSyntheticTapGestureRecognizer.m	2019-05-22 19:58:15 UTC (rev 245639)
@@ -70,8 +70,28 @@
 {
     [super reset];
     [_resetTarget performSelector:_resetAction withObject:self];
+    _lastActiveTouchIdentifier = nil;
 }
 
+- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
+{
+    [super touchesEnded:touches withEvent:event];
+    if (!_supportingWebTouchEventsGestureRecognizer)
+        return;
+
+#if ENABLE(POINTER_EVENTS) && HAVE(UI_WEB_TOUCH_EVENTS_GESTURE_RECOGNIZER_WITH_ACTIVE_TOUCHES_BY_ID)
+    // FIXME: <rdar://problem/48035706>
+    NSMapTable<NSNumber *, UITouch *> *activeTouches = [_supportingWebTouchEventsGestureRecognizer activeTouchesByIdentifier];
+    for (NSNumber *touchIdentifier in activeTouches) {
+        UITouch *touch = [activeTouches objectForKey:touchIdentifier];
+        if ([touch.gestureRecognizers containsObject:self]) {
+            _lastActiveTouchIdentifier = touchIdentifier;
+            break;
+        }
+    }
+#endif
+}
+
 @end
 
 #endif

Modified: trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm (245638 => 245639)


--- trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm	2019-05-22 19:27:49 UTC (rev 245638)
+++ trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm	2019-05-22 19:58:15 UTC (rev 245639)
@@ -836,6 +836,13 @@
     process().send(Messages::WebPage::WillStartUserTriggeredZooming(), m_pageID);
 }
 
+#if ENABLE(POINTER_EVENTS)
+void WebPageProxy::touchWithIdentifierWasRemoved(WebCore::PointerID pointerId)
+{
+    process().send(Messages::WebPage::TouchWithIdentifierWasRemoved(pointerId), m_pageID);
+}
+#endif
+
 void WebPageProxy::potentialTapAtPosition(const WebCore::FloatPoint& position, bool shouldRequestMagnificationInformation, uint64_t& requestID)
 {
     hideValidationMessage();
@@ -842,9 +849,9 @@
     process().send(Messages::WebPage::PotentialTapAtPosition(requestID, position, shouldRequestMagnificationInformation), m_pageID);
 }
 
-void WebPageProxy::commitPotentialTap(OptionSet<WebEvent::Modifier> modifiers, uint64_t layerTreeTransactionIdAtLastTouchStart)
+void WebPageProxy::commitPotentialTap(OptionSet<WebEvent::Modifier> modifiers, uint64_t layerTreeTransactionIdAtLastTouchStart, WebCore::PointerID pointerId)
 {
-    process().send(Messages::WebPage::CommitPotentialTap(modifiers, layerTreeTransactionIdAtLastTouchStart), m_pageID);
+    process().send(Messages::WebPage::CommitPotentialTap(modifiers, layerTreeTransactionIdAtLastTouchStart, pointerId), m_pageID);
 }
 
 void WebPageProxy::cancelPotentialTap()

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (245638 => 245639)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2019-05-22 19:27:49 UTC (rev 245638)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2019-05-22 19:58:15 UTC (rev 245639)
@@ -622,9 +622,13 @@
     bool allowsUserScaling() const;
     bool hasStablePageScaleFactor() const { return m_hasStablePageScaleFactor; }
 
+#if ENABLE(POINTER_EVENTS)
+    void touchWithIdentifierWasRemoved(WebCore::PointerID);
+#endif
+
     void handleTap(const WebCore::IntPoint&, OptionSet<WebKit::WebEvent::Modifier>, uint64_t lastLayerTreeTransactionId);
     void potentialTapAtPosition(uint64_t requestID, const WebCore::FloatPoint&, bool shouldRequestMagnificationInformation);
-    void commitPotentialTap(OptionSet<WebKit::WebEvent::Modifier>, uint64_t lastLayerTreeTransactionId);
+    void commitPotentialTap(OptionSet<WebKit::WebEvent::Modifier>, uint64_t lastLayerTreeTransactionId, WebCore::PointerID);
     void commitPotentialTapFailed();
     void cancelPotentialTap();
     void cancelPotentialTapInFrame(WebFrame&);
@@ -1234,8 +1238,8 @@
     void getFocusedElementInformation(FocusedElementInformation&);
     void platformInitializeAccessibility();
     void generateSyntheticEditingCommand(SyntheticEditingCommandType);
-    void handleSyntheticClick(WebCore::Node& nodeRespondingToClick, const WebCore::FloatPoint& location, OptionSet<WebKit::WebEvent::Modifier>);
-    void completeSyntheticClick(WebCore::Node& nodeRespondingToClick, const WebCore::FloatPoint& location, OptionSet<WebKit::WebEvent::Modifier>, WebCore::SyntheticClickType);
+    void handleSyntheticClick(WebCore::Node& nodeRespondingToClick, const WebCore::FloatPoint& location, OptionSet<WebKit::WebEvent::Modifier>, WebCore::PointerID = WebCore::mousePointerID);
+    void completeSyntheticClick(WebCore::Node& nodeRespondingToClick, const WebCore::FloatPoint& location, OptionSet<WebKit::WebEvent::Modifier>, WebCore::SyntheticClickType, WebCore::PointerID = WebCore::mousePointerID);
     void sendTapHighlightForNodeIfNecessary(uint64_t requestID, WebCore::Node*);
     void resetTextAutosizing();
     WebCore::VisiblePosition visiblePositionInFocusedNodeForPoint(const WebCore::Frame&, const WebCore::IntPoint&, bool isInteractingWithFocusedElement);
@@ -1844,6 +1848,7 @@
     WebCore::FloatPoint m_pendingSyntheticClickLocation;
     WebCore::FloatRect m_previousExposedContentRect;
     OptionSet<WebKit::WebEvent::Modifier> m_pendingSyntheticClickModifiers;
+    WebCore::PointerID m_pendingSyntheticClickPointerId { 0 };
     FocusedElementIdentifier m_currentFocusedElementIdentifier { 0 };
     Optional<DynamicViewportSizeUpdateID> m_pendingDynamicViewportSizeUpdateID;
     double m_lastTransactionPageScaleFactor { 0 };

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (245638 => 245639)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in	2019-05-22 19:27:49 UTC (rev 245638)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in	2019-05-22 19:58:15 UTC (rev 245639)
@@ -51,9 +51,10 @@
     SetOverrideViewportArguments(Optional<WebCore::ViewportArguments> arguments)
     DynamicViewportSizeUpdate(WebCore::FloatSize viewLayoutSize, WebCore::FloatSize maximumUnobscuredSize, WebCore::FloatRect targetExposedContentRect, WebCore::FloatRect targetUnobscuredRect, WebCore::FloatRect targetUnobscuredRectInScrollViewCoordinates, WebCore::RectEdges<float> targetUnobscuredSafeAreaInsets, double scale, int32_t deviceOrientation, uint64_t dynamicViewportSizeUpdateID)
 
+    TouchWithIdentifierWasRemoved(WebCore::PointerID pointerId)
     HandleTap(WebCore::IntPoint point, OptionSet<WebKit::WebEvent::Modifier> modifiers, uint64_t lastLayerTreeTransactionId)
     PotentialTapAtPosition(uint64_t requestID, WebCore::FloatPoint point, bool shouldRequestMagnificationInformation)
-    CommitPotentialTap(OptionSet<WebKit::WebEvent::Modifier> modifiers, uint64_t lastLayerTreeTransactionId)
+    CommitPotentialTap(OptionSet<WebKit::WebEvent::Modifier> modifiers, uint64_t lastLayerTreeTransactionId, WebCore::PointerID pointerId)
     CancelPotentialTap()
     TapHighlightAtPosition(uint64_t requestID, WebCore::FloatPoint point)
     DidRecognizeLongPress()

Modified: trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm (245638 => 245639)


--- trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm	2019-05-22 19:27:49 UTC (rev 245638)
+++ trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm	2019-05-22 19:58:15 UTC (rev 245639)
@@ -108,6 +108,7 @@
 #import <WebCore/Pasteboard.h>
 #import <WebCore/PlatformKeyboardEvent.h>
 #import <WebCore/PlatformMouseEvent.h>
+#import <WebCore/PointerCaptureController.h>
 #import <WebCore/Quirks.h>
 #import <WebCore/RenderBlock.h>
 #import <WebCore/RenderImage.h>
@@ -563,7 +564,7 @@
         didChangeSelection();
 }
 
-static void dispatchSyntheticMouseMove(Frame& mainFrame, const WebCore::FloatPoint& location, OptionSet<WebEvent::Modifier> modifiers)
+static void dispatchSyntheticMouseMove(Frame& mainFrame, const WebCore::FloatPoint& location, OptionSet<WebEvent::Modifier> modifiers, WebCore::PointerID pointerId = WebCore::mousePointerID)
 {
     IntPoint roundedAdjustedPoint = roundedIntPoint(location);
     auto shiftKey = modifiers.contains(WebEvent::Modifier::ShiftKey);
@@ -570,7 +571,7 @@
     auto ctrlKey = modifiers.contains(WebEvent::Modifier::ControlKey);
     auto altKey = modifiers.contains(WebEvent::Modifier::AltKey);
     auto metaKey = modifiers.contains(WebEvent::Modifier::MetaKey);
-    auto mouseEvent = PlatformMouseEvent(roundedAdjustedPoint, roundedAdjustedPoint, NoButton, PlatformEvent::MouseMoved, 0, shiftKey, ctrlKey, altKey, metaKey, WallTime::now(), WebCore::ForceAtClick, WebCore::NoTap);
+    auto mouseEvent = PlatformMouseEvent(roundedAdjustedPoint, roundedAdjustedPoint, NoButton, PlatformEvent::MouseMoved, 0, shiftKey, ctrlKey, altKey, metaKey, WallTime::now(), WebCore::ForceAtClick, WebCore::NoTap, pointerId);
     // FIXME: Pass caps lock state.
     mainFrame.eventHandler().dispatchSyntheticMouseMove(mouseEvent);
 }
@@ -627,10 +628,10 @@
     frame.eventHandler().keyEvent(keyEvent);
 }
 
-void WebPage::handleSyntheticClick(Node& nodeRespondingToClick, const WebCore::FloatPoint& location, OptionSet<WebEvent::Modifier> modifiers)
+void WebPage::handleSyntheticClick(Node& nodeRespondingToClick, const WebCore::FloatPoint& location, OptionSet<WebEvent::Modifier> modifiers, WebCore::PointerID pointerId)
 {
     if (!nodeRespondingToClick.document().settings().contentChangeObserverEnabled()) {
-        completeSyntheticClick(nodeRespondingToClick, location, modifiers, WebCore::OneFingerTap);
+        completeSyntheticClick(nodeRespondingToClick, location, modifiers, WebCore::OneFingerTap, pointerId);
         return;
     }
 
@@ -639,7 +640,7 @@
         LOG_WITH_STREAM(ContentObservation, stream << "handleSyntheticClick: node(" << &nodeRespondingToClick << ") " << location);
         ContentChangeObserver::MouseMovedScope observingScope(respondingDocument);
         auto& mainFrame = m_page->mainFrame();
-        dispatchSyntheticMouseMove(mainFrame, location, modifiers);
+        dispatchSyntheticMouseMove(mainFrame, location, modifiers, pointerId);
         mainFrame.document()->updateStyleIfNeeded();
     }
 
@@ -659,10 +660,11 @@
         m_pendingSyntheticClickNode = &nodeRespondingToClick;
         m_pendingSyntheticClickLocation = location;
         m_pendingSyntheticClickModifiers = modifiers;
+        m_pendingSyntheticClickPointerId = pointerId;
         return;
     }
 
-    callOnMainThread([protectedThis = makeRefPtr(this), targetNode = Ref<Node>(nodeRespondingToClick), location, modifiers, observedContentChange, targetNodeTriggersClick] {
+    callOnMainThread([protectedThis = makeRefPtr(this), targetNode = Ref<Node>(nodeRespondingToClick), location, modifiers, observedContentChange, targetNodeTriggersClick, pointerId] {
         if (protectedThis->m_isClosed || !protectedThis->corePage())
             return;
 
@@ -669,12 +671,12 @@
         auto shouldStayAtHoverState = observedContentChange == WKContentVisibilityChange && !targetNodeTriggersClick;
         if (shouldStayAtHoverState) {
             // The move event caused new contents to appear. Don't send synthetic click event, but just ensure that the mouse is on the most recent content.
-            dispatchSyntheticMouseMove(protectedThis->corePage()->mainFrame(), location, modifiers);
+            dispatchSyntheticMouseMove(protectedThis->corePage()->mainFrame(), location, modifiers, pointerId);
             LOG(ContentObservation, "handleSyntheticClick: Observed meaningful visible change -> hover.");
             return;
         }
         LOG(ContentObservation, "handleSyntheticClick: calling completeSyntheticClick -> click.");
-        protectedThis->completeSyntheticClick(targetNode, location, modifiers, WebCore::OneFingerTap);
+        protectedThis->completeSyntheticClick(targetNode, location, modifiers, WebCore::OneFingerTap, pointerId);
     });
 }
 
@@ -687,10 +689,10 @@
     // Only dispatch the click if the document didn't get changed by any timers started by the move event.
     if (observedContentChange == WKContentNoChange) {
         LOG(ContentObservation, "No chage was observed -> click.");
-        completeSyntheticClick(*m_pendingSyntheticClickNode, m_pendingSyntheticClickLocation, m_pendingSyntheticClickModifiers, WebCore::OneFingerTap);
+        completeSyntheticClick(*m_pendingSyntheticClickNode, m_pendingSyntheticClickLocation, m_pendingSyntheticClickModifiers, WebCore::OneFingerTap, m_pendingSyntheticClickPointerId);
     } else {
         // Ensure that the mouse is on the most recent content.
-        dispatchSyntheticMouseMove(m_page->mainFrame(), m_pendingSyntheticClickLocation, m_pendingSyntheticClickModifiers);
+        dispatchSyntheticMouseMove(m_page->mainFrame(), m_pendingSyntheticClickLocation, m_pendingSyntheticClickModifiers, m_pendingSyntheticClickPointerId);
         LOG(ContentObservation, "Observed meaningful visible change -> hover.");
     }
 
@@ -697,9 +699,10 @@
     m_pendingSyntheticClickNode = nullptr;
     m_pendingSyntheticClickLocation = FloatPoint();
     m_pendingSyntheticClickModifiers = { };
+    m_pendingSyntheticClickPointerId = 0;
 }
 
-void WebPage::completeSyntheticClick(Node& nodeRespondingToClick, const WebCore::FloatPoint& location, OptionSet<WebEvent::Modifier> modifiers, SyntheticClickType syntheticClickType)
+void WebPage::completeSyntheticClick(Node& nodeRespondingToClick, const WebCore::FloatPoint& location, OptionSet<WebEvent::Modifier> modifiers, SyntheticClickType syntheticClickType, WebCore::PointerID pointerId)
 {
     IntPoint roundedAdjustedPoint = roundedIntPoint(location);
     Frame& mainframe = m_page->mainFrame();
@@ -718,11 +721,11 @@
     bool altKey = modifiers.contains(WebEvent::Modifier::AltKey);
     bool metaKey = modifiers.contains(WebEvent::Modifier::MetaKey);
 
-    tapWasHandled |= mainframe.eventHandler().handleMousePressEvent(PlatformMouseEvent(roundedAdjustedPoint, roundedAdjustedPoint, LeftButton, PlatformEvent::MousePressed, 1, shiftKey, ctrlKey, altKey, metaKey, WallTime::now(), WebCore::ForceAtClick, syntheticClickType));
+    tapWasHandled |= mainframe.eventHandler().handleMousePressEvent(PlatformMouseEvent(roundedAdjustedPoint, roundedAdjustedPoint, LeftButton, PlatformEvent::MousePressed, 1, shiftKey, ctrlKey, altKey, metaKey, WallTime::now(), WebCore::ForceAtClick, syntheticClickType, pointerId));
     if (m_isClosed)
         return;
 
-    tapWasHandled |= mainframe.eventHandler().handleMouseReleaseEvent(PlatformMouseEvent(roundedAdjustedPoint, roundedAdjustedPoint, LeftButton, PlatformEvent::MouseReleased, 1, shiftKey, ctrlKey, altKey, metaKey, WallTime::now(), WebCore::ForceAtClick, syntheticClickType));
+    tapWasHandled |= mainframe.eventHandler().handleMouseReleaseEvent(PlatformMouseEvent(roundedAdjustedPoint, roundedAdjustedPoint, LeftButton, PlatformEvent::MouseReleased, 1, shiftKey, ctrlKey, altKey, metaKey, WallTime::now(), WebCore::ForceAtClick, syntheticClickType, pointerId));
     if (m_isClosed)
         return;
 
@@ -738,7 +741,7 @@
 
     // Only send a synthetic mouse out event if synthetic mouse move events were sent; this is true when ContentChangeObserver is enabled.
     if (nodeRespondingToClick.document().settings().contentChangeObserverEnabled() && !tapWasHandled && nodeRespondingToClick.document().frame())
-        nodeRespondingToClick.document().frame()->eventHandler().dispatchSyntheticMouseOut(PlatformMouseEvent(roundedAdjustedPoint, roundedAdjustedPoint, LeftButton, PlatformEvent::NoType, 0, shiftKey, ctrlKey, altKey, metaKey, WallTime::now(), 0, WebCore::NoTap));
+        nodeRespondingToClick.document().frame()->eventHandler().dispatchSyntheticMouseOut(PlatformMouseEvent(roundedAdjustedPoint, roundedAdjustedPoint, LeftButton, PlatformEvent::NoType, 0, shiftKey, ctrlKey, altKey, metaKey, WallTime::now(), 0, WebCore::NoTap, pointerId));
 
     if (m_isClosed)
         return;
@@ -959,7 +962,7 @@
 #endif
 }
 
-void WebPage::commitPotentialTap(OptionSet<WebEvent::Modifier> modifiers, uint64_t lastLayerTreeTransactionId)
+void WebPage::commitPotentialTap(OptionSet<WebEvent::Modifier> modifiers, uint64_t lastLayerTreeTransactionId, WebCore::PointerID pointerId)
 {
     if (!m_potentialTapNode || (!m_potentialTapNode->renderer() && !is<HTMLAreaElement>(m_potentialTapNode.get()))) {
         commitPotentialTapFailed();
@@ -983,7 +986,7 @@
             commitPotentialTapFailed();
         } else
 #endif
-            handleSyntheticClick(*nodeRespondingToClick, adjustedPoint, modifiers);
+            handleSyntheticClick(*nodeRespondingToClick, adjustedPoint, modifiers, pointerId);
     } else
         commitPotentialTapFailed();
 
@@ -1033,6 +1036,13 @@
     sendTapHighlightForNodeIfNecessary(requestID, mainframe.nodeRespondingToClickEvents(position, adjustedPoint));
 }
 
+#if ENABLE(POINTER_EVENTS)
+void WebPage::touchWithIdentifierWasRemoved(WebCore::PointerID pointerId)
+{
+    m_page->pointerCaptureController().touchWithIdentifierWasRemoved(pointerId);
+}
+#endif
+
 void WebPage::inspectorNodeSearchMovedToPosition(const FloatPoint& position)
 {
     IntPoint adjustedPoint = roundedIntPoint(position);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to