WebKit Bugzilla
Attachment 370417 Details for
Bug 198124
: [iOS] Compatibility mouse events aren't prevented by calling preventDefault() on pointerdown
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-198124-20190522193438.patch (text/plain), 48.45 KB, created by
Antoine Quint
on 2019-05-22 10:34:39 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Antoine Quint
Created:
2019-05-22 10:34:39 PDT
Size:
48.45 KB
patch
obsolete
>Subversion Revision: 245620 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 65957a86b220418a9a15a08e785319b0ec1b6679..efbc6c56df00c4e7613ebb7e1d3747614692e557 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,46 @@ >+2019-05-22 Antoine Quint <graouts@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 NOBODY (OOPS!). >+ >+ 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::forgetPointer() 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::forgetPointer): >+ (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-21 Jer Noble <jer.noble@apple.com> > > Media controls don't show in WK2 video fullscreen sometimes >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index 31d28687cb0fe02da46dfa966f9d899f0511e35e..60dee9275bead3d0c5441464e7a47f59f73fbb72 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,53 @@ >+2019-05-22 Antoine Quint <graouts@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 NOBODY (OOPS!). >+ >+ 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 >+ forgetPointer() 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::forgetPointer): >+ (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::forgetPointer): >+ > 2019-05-22 Ross Kirsling <ross.kirsling@sony.com> > > Unreviewed fix for non-unified build after r245320. >@@ -323,7 +373,7 @@ > (WebKit::LocalStorageDatabase::updateDatabaseWithChangedItems): > (WebKit::LocalStorageDatabase::databaseIsEmpty): > * NetworkProcess/WebStorage/LocalStorageDatabase.h: Renamed from Source/WebKit/UIProcess/WebStorage/LocalStorageDatabase.h. >- * NetworkProcess/WebStorage/LocalStorageDatabaseTracker.cpp: Renamed from Source/WebKit/UIProcess/WebStorage/LocalStorageDatabaseTracker.cpp. >+ * NetworkProcess/WebStorage/LocalStorageDatabaseTracker.cpp: Renamed from Source/WebKit/UIProcess/WebStorage/LocalStorageDatabaseTracker.pp. > (WebKit::LocalStorageDatabaseTracker::create): > (WebKit::LocalStorageDatabaseTracker::LocalStorageDatabaseTracker): > (WebKit::LocalStorageDatabaseTracker::~LocalStorageDatabaseTracker): >diff --git a/Source/WebCore/Headers.cmake b/Source/WebCore/Headers.cmake >index 83427f0375de1e6d8e7bfde1dde88a7e00a637f7..22ecc9c575d73def2471d9510837c0703143339c 100644 >--- a/Source/WebCore/Headers.cmake >+++ b/Source/WebCore/Headers.cmake >@@ -419,7 +419,6 @@ set(WebCore_PRIVATE_FRAMEWORK_HEADERS > dom/NodeRenderStyle.h > dom/NodeTraversal.h > dom/OverflowEvent.h >- dom/PointerID.h > dom/Position.h > dom/ProcessingInstruction.h > dom/ProgressEvent.h >@@ -926,6 +925,7 @@ set(WebCore_PRIVATE_FRAMEWORK_HEADERS > platform/PlatformTouchEvent.h > platform/PlatformTouchPoint.h > platform/PlatformWheelEvent.h >+ platform/PointerID.h > platform/PopupMenu.h > platform/PopupMenuClient.h > platform/PopupMenuStyle.h >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index 522b6d08cc0d39a34d5c15426668006d0e1ba892..eadef33bf85243f6de81bd2280fd9d84c5af458d 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -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 /* missingImage@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = CDF419991AB0DA14004E64E1 /* missingImage@3x.png */; }; >@@ -16998,11 +16998,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 */, >@@ -25296,6 +25296,7 @@ > BCBB8AB513F1AFB000734DF0 /* PODInterval.h */, > BCBB8AB613F1AFB000734DF0 /* PODIntervalTree.h */, > BCBB8AB713F1AFB000734DF0 /* PODRedBlackTree.h */, >+ 71EADCD622087E6D0065A45F /* PointerID.h */, > 0668E1890ADD9624004128E0 /* PopupMenu.h */, > ABC128760B33AA6D00C693D5 /* PopupMenuClient.h */, > BC3BE12A0E98092F00835588 /* PopupMenuStyle.h */, >@@ -27457,7 +27458,6 @@ > 317D3FF1215599E20034E3B9 /* PointerEvent.cpp */, > 317D3FF2215599E30034E3B9 /* PointerEvent.h */, > 317D3FEF215599E10034E3B9 /* PointerEvent.idl */, >- 71EADCD622087E6D0065A45F /* PointerID.h */, > 5189F0DD10B46B0E00F3C739 /* PopStateEvent.cpp */, > 5174E20810A1F44F00F95E6F /* PopStateEvent.h */, > 5174E20B10A1F49A00F95E6F /* PopStateEvent.idl */, >diff --git a/Source/WebCore/dom/Element.cpp b/Source/WebCore/dom/Element.cpp >index 6ac9bc3115222c306e5e79a00924d0708f36f212..540a861acfcf4a5e16cbd7635381044e4dd7ae5e 100644 >--- a/Source/WebCore/dom/Element.cpp >+++ b/Source/WebCore/dom/Element.cpp >@@ -303,8 +303,14 @@ bool Element::dispatchMouseEvent(const PlatformMouseEvent& platformEvent, const > > 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 @@ bool Element::dispatchMouseEvent(const PlatformMouseEvent& platformEvent, const > return false; > } > } >+#endif > } > #endif > >diff --git a/Source/WebCore/dom/PointerEvent.h b/Source/WebCore/dom/PointerEvent.h >index d51de26c30d69c953f053467d0d88876ccd1115d..8e04aa7ff545708c4f1541456613bc1d631dce37 100644 >--- a/Source/WebCore/dom/PointerEvent.h >+++ b/Source/WebCore/dom/PointerEvent.h >@@ -40,7 +40,7 @@ namespace WebCore { > 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 @@ public: > static const String& mousePointerType(); > static const String& penPointerType(); > static const String& touchPointerType(); >- static PointerID defaultMousePointerIdentifier() { return 1; } > > virtual ~PointerEvent(); > >@@ -113,7 +112,7 @@ private: > 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 }; >diff --git a/Source/WebCore/dom/PointerID.h b/Source/WebCore/dom/PointerID.h >deleted file mode 100644 >index 20da947dd6fed21d8faa73ac95ed68c65d01ff37..0000000000000000000000000000000000000000 >--- a/Source/WebCore/dom/PointerID.h >+++ /dev/null >@@ -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) >diff --git a/Source/WebCore/page/PointerCaptureController.cpp b/Source/WebCore/page/PointerCaptureController.cpp >index 83ab79df45c555705f4c4c54c6940fe282cce5e9..2d1664574423a65afc57f5ab1cade1d3d8d2050e 100644 >--- a/Source/WebCore/page/PointerCaptureController.cpp >+++ b/Source/WebCore/page/PointerCaptureController.cpp >@@ -47,7 +47,7 @@ PointerCaptureController::PointerCaptureController(Page& page) > #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::elementWasRemoved(Element& element) > } > } > >-void PointerCaptureController::touchEndedOrWasCancelledForIdentifier(PointerID pointerId) >+void PointerCaptureController::forgetPointer(PointerID pointerId) > { > m_activePointerIdsToCapturingData.remove(pointerId); > } >diff --git a/Source/WebCore/page/PointerCaptureController.h b/Source/WebCore/page/PointerCaptureController.h >index 4bcfadcf1b6c3eefe88f41f0e0e95468cb66ff0c..90882adda1435742ce08538aab7a347ac9f5e1e4 100644 >--- a/Source/WebCore/page/PointerCaptureController.h >+++ b/Source/WebCore/page/PointerCaptureController.h >@@ -52,7 +52,7 @@ public: > void dispatchEventForTouchAtIndex(EventTarget&, const PlatformTouchEvent&, unsigned, bool isPrimary, WindowProxy&); > #endif > >- void touchEndedOrWasCancelledForIdentifier(PointerID); >+ WEBCORE_EXPORT void forgetPointer(PointerID); > bool hasCancelledPointerEventForIdentifier(PointerID); > bool preventsCompatibilityMouseEventsForIdentifier(PointerID); > void dispatchEvent(PointerEvent&, EventTarget*); >diff --git a/Source/WebCore/platform/PlatformMouseEvent.h b/Source/WebCore/platform/PlatformMouseEvent.h >index 01cba04b6efdf9aed844fcd1a4ab83c86932bd44..0179c6321b7743e9d4bcf2194886df39d2145356 100644 >--- a/Source/WebCore/platform/PlatformMouseEvent.h >+++ b/Source/WebCore/platform/PlatformMouseEvent.h >@@ -28,6 +28,7 @@ > > #include "IntPoint.h" > #include "PlatformEvent.h" >+#include "PointerID.h" > #include <wtf/WindowsExtras.h> > > #if PLATFORM(GTK) >@@ -61,7 +62,7 @@ const double ForceAtForceClick = 2; > } > > 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 @@ const double ForceAtForceClick = 2; > , 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 @@ const double ForceAtForceClick = 2; > 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 @@ const double ForceAtForceClick = 2; > unsigned m_modifierFlags; > double m_force { 0 }; > SyntheticClickType m_syntheticClickType { NoTap }; >+ PointerID m_pointerId { mousePointerID() }; > > #if PLATFORM(MAC) > int m_eventNumber; >diff --git a/Source/WebCore/platform/PointerID.h b/Source/WebCore/platform/PointerID.h >new file mode 100644 >index 0000000000000000000000000000000000000000..9109bc69636cdaad62bc2a45fa3c9b5c2048649a >--- /dev/null >+++ b/Source/WebCore/platform/PointerID.h >@@ -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; >+ >+inline PointerID mousePointerID() { return 1; } >+ >+} >diff --git a/Source/WebKit/UIProcess/WebPageProxy.h b/Source/WebKit/UIProcess/WebPageProxy.h >index c0e92e31c514f38076013054a5d02b5c6e659ddf..caa44c3fa17ba1d0c68af0cff093e7687ce1a97b 100644 >--- a/Source/WebKit/UIProcess/WebPageProxy.h >+++ b/Source/WebKit/UIProcess/WebPageProxy.h >@@ -1212,8 +1212,12 @@ public: > #if PLATFORM(IOS_FAMILY) > void willStartUserTriggeredZooming(); > >+#if ENABLE(POINTER_EVENTS) >+ void forgetPointer(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); >diff --git a/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm b/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm >index cce9adbfe4adbc8569da6daded35fca9a22a5b39..d29cbf3031ce831ce3c2722578d340ad4e7d72c2 100644 >--- a/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm >+++ b/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm >@@ -727,6 +727,9 @@ - (void)setupInteraction > [_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 @@ - (void)cleanupInteraction > [_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 @@ - (void)_singleTapDidReset:(UITapGestureRecognizer *)gestureRecognizer > { > ASSERT(gestureRecognizer == _singleTapGestureRecognizer); > cancelPotentialTapIfNecessary(self); >+#if ENABLE(POINTER_EVENTS) >+ if (auto* singleTapTouchIdentifier = [_singleTapGestureRecognizer lastActiveTouchIdentifier]) >+ _page->forgetPointer([singleTapTouchIdentifier unsignedIntValue]); >+#endif > } > > - (void)_doubleTapDidFail:(UITapGestureRecognizer *)gestureRecognizer >@@ -2375,7 +2385,12 @@ - (void)_singleTapRecognized:(UITapGestureRecognizer *)gestureRecognizer > > 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]; >diff --git a/Source/WebKit/UIProcess/ios/WKSyntheticTapGestureRecognizer.h b/Source/WebKit/UIProcess/ios/WKSyntheticTapGestureRecognizer.h >index 2feffb1370a71774a131157039141de5850976a9..0f21522cbc44bae8d00a32c6f8e588c3d7f197dc 100644 >--- a/Source/WebKit/UIProcess/ios/WKSyntheticTapGestureRecognizer.h >+++ b/Source/WebKit/UIProcess/ios/WKSyntheticTapGestureRecognizer.h >@@ -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 >diff --git a/Source/WebKit/UIProcess/ios/WKSyntheticTapGestureRecognizer.m b/Source/WebKit/UIProcess/ios/WKSyntheticTapGestureRecognizer.m >index b49fc34c80696cabf1703144211c17cf7cce3a56..244198812667d73a453923b056a5cbb85b80837b 100644 >--- a/Source/WebKit/UIProcess/ios/WKSyntheticTapGestureRecognizer.m >+++ b/Source/WebKit/UIProcess/ios/WKSyntheticTapGestureRecognizer.m >@@ -70,6 +70,26 @@ - (void)reset > { > [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; >+ return; >+ } >+ } >+#endif > } > > @end >diff --git a/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm b/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm >index fabafef1eb9af86b965c73aeb99abf73d51b726c..555e120afa3b223a113ffcd706e52e8d1ef0588c 100644 >--- a/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm >+++ b/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm >@@ -836,15 +836,22 @@ void WebPageProxy::willStartUserTriggeredZooming() > process().send(Messages::WebPage::WillStartUserTriggeredZooming(), m_pageID); > } > >+#if ENABLE(POINTER_EVENTS) >+void WebPageProxy::forgetPointer(WebCore::PointerID pointerId) >+{ >+ process().send(Messages::WebPage::ForgetPointer(pointerId), m_pageID); >+} >+#endif >+ > void WebPageProxy::potentialTapAtPosition(const WebCore::FloatPoint& position, bool shouldRequestMagnificationInformation, uint64_t& requestID) > { > hideValidationMessage(); > 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() >diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.h b/Source/WebKit/WebProcess/WebPage/WebPage.h >index 5fc519b39b3f8f53671b31eccf79b7b8d3c37700..2622a57378fb99a8cf15138486e7a29fd3be6e57 100644 >--- a/Source/WebKit/WebProcess/WebPage/WebPage.h >+++ b/Source/WebKit/WebProcess/WebPage/WebPage.h >@@ -622,9 +622,13 @@ public: > bool allowsUserScaling() const; > bool hasStablePageScaleFactor() const { return m_hasStablePageScaleFactor; } > >+#if ENABLE(POINTER_EVENTS) >+ void forgetPointer(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 @@ private: > 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 @@ private: > 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 }; >diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.messages.in b/Source/WebKit/WebProcess/WebPage/WebPage.messages.in >index 4dc67bf9625bb2fccc8baff63f8245df9e2594b5..add51045220e1e177c9f927f324ee75e76b60d11 100644 >--- a/Source/WebKit/WebProcess/WebPage/WebPage.messages.in >+++ b/Source/WebKit/WebProcess/WebPage/WebPage.messages.in >@@ -51,9 +51,10 @@ messages -> WebPage LegacyReceiver { > 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) > >+ ForgetPointer(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() >diff --git a/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm b/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm >index 1874d043ed49f9fffee46f51b02c4d6e15c80bb2..425914d7d002f7ec78d406ea56aaf633dc8ad90d 100644 >--- a/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm >+++ b/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm >@@ -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,14 +564,14 @@ void WebPage::updateSelectionAppearance() > 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); > 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 @@ void WebPage::generateSyntheticEditingCommand(SyntheticEditingCommandType comman > 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 @@ void WebPage::handleSyntheticClick(Node& nodeRespondingToClick, const WebCore::F > 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,22 +660,23 @@ void WebPage::handleSyntheticClick(Node& nodeRespondingToClick, const WebCore::F > 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; > > 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,19 +689,20 @@ void WebPage::completePendingSyntheticClickForContentChangeObserver() > // 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."); > } > > 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 @@ void WebPage::completeSyntheticClick(Node& nodeRespondingToClick, const WebCore: > 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 @@ void WebPage::completeSyntheticClick(Node& nodeRespondingToClick, const WebCore: > > // 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 @@ void WebPage::potentialTapAtPosition(uint64_t requestID, const WebCore::FloatPoi > #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 @@ void WebPage::commitPotentialTap(OptionSet<WebEvent::Modifier> modifiers, uint64 > commitPotentialTapFailed(); > } else > #endif >- handleSyntheticClick(*nodeRespondingToClick, adjustedPoint, modifiers); >+ handleSyntheticClick(*nodeRespondingToClick, adjustedPoint, modifiers, pointerId); > } else > commitPotentialTapFailed(); > >@@ -1033,6 +1036,13 @@ void WebPage::tapHighlightAtPosition(uint64_t requestID, const FloatPoint& posit > sendTapHighlightForNodeIfNecessary(requestID, mainframe.nodeRespondingToClickEvents(position, adjustedPoint)); > } > >+#if ENABLE(POINTER_EVENTS) >+void WebPage::forgetPointer(WebCore::PointerID pointerId) >+{ >+ m_page->pointerCaptureController().forgetPointer(pointerId); >+} >+#endif >+ > void WebPage::inspectorNodeSearchMovedToPosition(const FloatPoint& position) > { > IntPoint adjustedPoint = roundedIntPoint(position); >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 3360915e7923a934366b3e9ff38a235a0d7841f8..5e74ba8fed7964f2b230c409feae287e967f3ac2 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,16 @@ >+2019-05-22 Antoine Quint <graouts@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 NOBODY (OOPS!). >+ >+ 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 Per Arne Vollan <pvollan@apple.com> > > Layout Test http/tests/security/showModalDialog-sync-cross-origin-page-load2.html is failing >diff --git a/LayoutTests/imported/w3c/ChangeLog b/LayoutTests/imported/w3c/ChangeLog >index 14c6b957e3413b75b277c5ae10e4652cbbe88931..f2f64958764712460072593ef5807dcbd81c3f29 100644 >--- a/LayoutTests/imported/w3c/ChangeLog >+++ b/LayoutTests/imported/w3c/ChangeLog >@@ -1,3 +1,17 @@ >+2019-05-22 Antoine Quint <graouts@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 NOBODY (OOPS!). >+ >+ 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-21 Antoine Quint <graouts@apple.com> > > [macOS] Compatibility mouse events aren't prevented by calling preventDefault() on pointerdown >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver-vendor.js b/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver-vendor.js >index 312b48edcc5ce105c2186fcac42479316a5c26b2..c4bb28a43b514fd80f5730df8df290191930b8ab 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver-vendor.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver-vendor.js >@@ -46,7 +46,7 @@ function dispatchMouseActions(actions) > }); > } > >-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 @@ function dispatchTouchActions(actions) > 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 @@ window.test_driver_internal.action_sequence = function(sources) > > logDebug(() => JSON.stringify(pointerSource)); > >- if (pointerType === "mouse") >- return dispatchMouseActions(pointerSource.actions); > if (pointerType === "touch") > return dispatchTouchActions(pointerSource.actions); >+ if ("createTouch" in document) >+ return dispatchTouchActions(pointerSource.actions, { insertPauseAfterPointerUp: true }); >+ if (pointerType === "mouse") >+ return dispatchMouseActions(pointerSource.actions); > }; >diff --git a/LayoutTests/platform/ios/imported/w3c/web-platform-tests/pointerevents/pointerevent_suppress_compat_events_on_click-expected.txt b/LayoutTests/platform/ios/imported/w3c/web-platform-tests/pointerevents/pointerevent_suppress_compat_events_on_click-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..e708d73f05bd3b05f00c7405ee395d5e975661d2 >--- /dev/null >+++ b/LayoutTests/platform/ios/imported/w3c/web-platform-tests/pointerevents/pointerevent_suppress_compat_events_on_click-expected.txt >@@ -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 >+
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 198124
:
370415
|
370417
|
372625