WebKit Bugzilla
Attachment 360774 Details for
Bug 193962
: Dispatch pointercancel events when content is panned or zoomed on iOS
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-193962-20190131230537.patch (text/plain), 32.95 KB, created by
Antoine Quint
on 2019-01-31 14:05:39 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Antoine Quint
Created:
2019-01-31 14:05:39 PST
Size:
32.95 KB
patch
obsolete
>Subversion Revision: 240805 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index e22c7eecd95d77797abcd83d0981dd4ec722de3d..92b69b6ba150345bafc89655eb8500b9b482b43a 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,38 @@ >+2019-01-31 Antoine Quint <graouts@apple.com> >+ >+ Dispatch pointercancel events when content is panned or zoomed on iOS >+ https://bugs.webkit.org/show_bug.cgi?id=193962 >+ <rdar://problem/47629134> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Expose two new methods on PointerCaptureController so that, given a pointer id, it can be established whether this pointer >+ has been cancelled, which is important because a cancelled pointer should no longer dispatch any further pointer events, and >+ to cancel a pointer. >+ >+ * WebCore.xcodeproj/project.pbxproj: Make PointerCaptureController.h Private so that it can be imported from WebKit. >+ * dom/PointerEvent.h: Remove an unnecessary #if ENABLE(POINTER_EVENTS) since the entire file is already contained in one. >+ Then we add a new create() method that takes an event type, a pointer id and a pointer type (touch vs. pen) that we use >+ to create pointercancel events in PointerCaptureController::cancelPointer(). >+ * page/Page.cpp: >+ (WebCore::Page::Page): Pass the Page as a parameter when creating the PointerCaptureController. >+ * page/PointerCaptureController.cpp: >+ (WebCore::PointerCaptureController::PointerCaptureController): Add a Page reference to the constructor since we'll need >+ the page to access its main frame's EventHandler to perform hit testing in case we do not have a capture target override >+ in cancelPointer(). >+ (WebCore::PointerCaptureController::releasePointerCapture): Drive-by, remove the the implicit parameter since on iOS we >+ don't need to differentiate. We'll bring this back for the macOS work. >+ (WebCore::PointerCaptureController::hasCancelledPointerEventForIdentifier): New method we'll use when dispatching pointer >+ events to identify whether a pointer id has already been cancelled which will allow for _not_ dispatching any further >+ pointer events for this pointer id. >+ (WebCore::PointerCaptureController::pointerEventWillBeDispatched): Keep track of the pointer type so we can preserve it >+ when dispatching pointercancel events for a given pointer id. >+ (WebCore::PointerCaptureController::cancelPointer): Dispatch a pointercancel for the provided pointer id, using the capture >+ target override as the event's target, if there is one, and otherwise hit-testing at the provided location to figure out >+ what the target should be. >+ * page/PointerCaptureController.h: Switch the target overrides from Element* to RefPtr<Element> to ensure it may not be >+ deleted while we still need them. Existing code already ensures these get set to nullptr. >+ > 2019-01-31 Jiewen Tan <jiewen_tan@apple.com> > > Formalize WebKitAdditions mechanism of LoadOptimizer >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index fda715d87e32d57ecc300de52816362ba4c2a6c5..60d0bbd3350529613ed9ff7594649d6843e499fd 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,54 @@ >+2019-01-31 Antoine Quint <graouts@apple.com> >+ >+ Dispatch pointercancel events when content is panned or zoomed on iOS >+ https://bugs.webkit.org/show_bug.cgi?id=193962 >+ <rdar://problem/47629134> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ When a user-agent-provided interaction, such as panning or zooming on iOS, uses a set of touches, we should dispatch a pointercancel >+ event for the pointer ids of the touches involved. To facilitate this, we add a new method on WKContentView to cancel all the pointers >+ matching active touches for a provided UIGestureRecognizer through an async IPC call into the Web process using the new method >+ PointerCaptureController::cancelPointer(). >+ >+ * Platform/spi/ios/UIKitSPI.h: Add the necessary forward declaration for a necessary UIKit SPI allowing us to get the set of last-seen >+ UITouches by the identifier generated for the matching WebKit touch. >+ * UIProcess/API/Cocoa/WKWebView.mm: >+ (-[WKWebView scrollViewWillBeginZooming:withView:]): Dispatch touchcancel events for all pointers involved in a pinch gesture on the >+ top-level UIScrollView. >+ (-[WKWebView _scrollView:adjustedOffsetForOffset:translation:startPoint:locationInView:horizontalVelocity:verticalVelocity:]): Dispatch >+ touchcancel events for all pointers involved in a pan gesture on the top-level UIScrollView. We can infer this by looking at whether the >+ adjusted content offset, after accounting for the permitted touch actions, is different from the original content offset. >+ * UIProcess/PageClient.h: Expose a new virtual cancelPointersForGestureRecognizer() method which will allow the iOS implementation to >+ forward the call to WKContentViewInteraction. >+ (WebKit::PageClient::cancelPointersForGestureRecognizer): >+ * UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h: Expose the WebPageProxy such that we may access it to cancel pointers for >+ a given gesture recognizer from within ScrollingTreeScrollingNodeDelegateIOS. >+ (WebKit::RemoteScrollingCoordinatorProxy::webPageProxy const): >+ * UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.h: >+ * UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm: >+ (-[WKScrollingNodeScrollViewDelegate _scrollView:adjustedOffsetForOffset:translation:startPoint:locationInView:horizontalVelocity:verticalVelocity:]): >+ Dispatch touchcancel events for all pointers involved in a pan gesture on a nested UIScrollView. We can infer this by looking at >+ whether the adjusted content offset, after accounting for the permitted touch actions, is different from the original content offset. >+ (-[WKScrollingNodeScrollViewDelegate scrollViewWillBeginZooming:withView:]): Dispatch touchcancel events for all pointers involved in a >+ pinch gesture on a nested UIScrollView. >+ (-[WKScrollingNodeScrollViewDelegate cancelPointersForGestureRecognizer:]): >+ (WebKit::ScrollingTreeScrollingNodeDelegateIOS::cancelPointersForGestureRecognizer): >+ * UIProcess/WebPageProxy.cpp: >+ (WebKit::WebPageProxy::cancelPointer): >+ * UIProcess/WebPageProxy.h: >+ * UIProcess/ios/PageClientImplIOS.h: >+ * UIProcess/ios/PageClientImplIOS.mm: >+ (WebKit::PageClientImpl::cancelPointersForGestureRecognizer): >+ * UIProcess/ios/WKContentViewInteraction.h: >+ * UIProcess/ios/WKContentViewInteraction.mm: >+ (-[WKContentView cancelPointersForGestureRecognizer:]): Obtain all active UITouch objects for the view and dispatch a pointercancel event, >+ through the WebPageProxy, for all touches associated with the provided gesture recognizer. >+ * WebProcess/WebPage/WebPage.cpp: >+ (WebKit::WebPage::cancelPointer): >+ * WebProcess/WebPage/WebPage.h: >+ * WebProcess/WebPage/WebPage.messages.in: >+ > 2019-01-31 Jiewen Tan <jiewen_tan@apple.com> > > Formalize WebKitAdditions mechanism of LoadOptimizer >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index 6ead73c98949762e2254002883780adf4e7a6a9b..b9ae0beab22cf29f9da2565ea72dd918485e1054 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -2118,7 +2118,7 @@ > 71A1B6081DEE5AD70073BCFB /* modern-media-controls-localized-strings.js in Resources */ = {isa = PBXBuildFile; fileRef = 71A1B6061DEE5A820073BCFB /* modern-media-controls-localized-strings.js */; }; > 71A57DF2154BE25C0009D120 /* SVGPathUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 71A57DF0154BE25C0009D120 /* SVGPathUtilities.h */; }; > 71B28427203CEC4C0036AA5D /* JSCSSAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 71B28426203CEC0D0036AA5D /* JSCSSAnimation.h */; settings = {ATTRIBUTES = (Private, ); }; }; >- 71B5AB2621F1D9F400376E5C /* PointerCaptureController.h in Headers */ = {isa = PBXBuildFile; fileRef = 71B5AB2421F1D9E200376E5C /* PointerCaptureController.h */; }; >+ 71B5AB2621F1D9F400376E5C /* PointerCaptureController.h in Headers */ = {isa = PBXBuildFile; fileRef = 71B5AB2421F1D9E200376E5C /* PointerCaptureController.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 71B7EE0D21B5C6870031C1EF /* TouchAction.h in Headers */ = {isa = PBXBuildFile; fileRef = 71AEE4EB21B5A49C00DDB036 /* TouchAction.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 71C29E32203CE781008F36D2 /* CSSAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 71C29E30203CE76B008F36D2 /* CSSAnimation.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 71C916081D1483A300ACA47D /* UserInterfaceLayoutDirection.h in Headers */ = {isa = PBXBuildFile; fileRef = 71C916071D1483A300ACA47D /* UserInterfaceLayoutDirection.h */; settings = {ATTRIBUTES = (Private, ); }; }; >diff --git a/Source/WebCore/dom/PointerEvent.h b/Source/WebCore/dom/PointerEvent.h >index 25059af033335200318b200e8c097e4d7e4e3c29..3bcfa95376451393ac56d93d9d88e712eaf17b1b 100644 >--- a/Source/WebCore/dom/PointerEvent.h >+++ b/Source/WebCore/dom/PointerEvent.h >@@ -56,7 +56,15 @@ public: > return adoptRef(*new PointerEvent(type, WTFMove(initializer))); > } > >-#if ENABLE(POINTER_EVENTS) >+ static Ref<PointerEvent> create(const AtomicString& type, int32_t pointerId, String pointerType) >+ { >+ Init initializer; >+ initializer.bubbles = true; >+ initializer.pointerId = pointerId; >+ initializer.pointerType = pointerType; >+ return adoptRef(*new PointerEvent(type, WTFMove(initializer))); >+ } >+ > static Ref<PointerEvent> createForPointerCapture(const AtomicString& type, const PointerEvent& pointerEvent) > { > Init initializer; >@@ -66,7 +74,6 @@ public: > initializer.pointerType = pointerEvent.pointerType(); > return adoptRef(*new PointerEvent(type, WTFMove(initializer))); > } >-#endif > > static Ref<PointerEvent> createForBindings() > { >diff --git a/Source/WebCore/page/Page.cpp b/Source/WebCore/page/Page.cpp >index fd66607dcddc40edb928d3063e8d29909c04904c..0783004f107d03c3070aee52f4dffc5b2e96f2d7 100644 >--- a/Source/WebCore/page/Page.cpp >+++ b/Source/WebCore/page/Page.cpp >@@ -216,7 +216,7 @@ Page::Page(PageConfiguration&& pageConfiguration) > , m_userInputBridge(std::make_unique<UserInputBridge>(*this)) > , m_inspectorController(std::make_unique<InspectorController>(*this, pageConfiguration.inspectorClient)) > #if ENABLE(POINTER_EVENTS) >- , m_pointerCaptureController(std::make_unique<PointerCaptureController>()) >+ , m_pointerCaptureController(std::make_unique<PointerCaptureController>(*this)) > #endif > #if ENABLE(POINTER_LOCK) > , m_pointerLockController(std::make_unique<PointerLockController>(*this)) >diff --git a/Source/WebCore/page/PointerCaptureController.cpp b/Source/WebCore/page/PointerCaptureController.cpp >index 65d813d4240da7286d86c20b29c0d6886327c042..1c95922dc2ac9c091b32bf45811f0a353313bab4 100644 >--- a/Source/WebCore/page/PointerCaptureController.cpp >+++ b/Source/WebCore/page/PointerCaptureController.cpp >@@ -29,6 +29,7 @@ > > #include "Document.h" > #include "Element.h" >+#include "EventHandler.h" > #include "EventNames.h" > #include "EventTarget.h" > #include "Page.h" >@@ -36,7 +37,10 @@ > > namespace WebCore { > >-PointerCaptureController::PointerCaptureController() = default; >+PointerCaptureController::PointerCaptureController(Page& page) >+ : m_page(page) >+{ >+} > > ExceptionOr<void> PointerCaptureController::setPointerCapture(Element* capturingTarget, int32_t pointerId) > { >@@ -68,7 +72,7 @@ ExceptionOr<void> PointerCaptureController::setPointerCapture(Element* capturing > return { }; > } > >-ExceptionOr<void> PointerCaptureController::releasePointerCapture(Element* capturingTarget, int32_t pointerId, ImplicitCapture implicit) >+ExceptionOr<void> PointerCaptureController::releasePointerCapture(Element* capturingTarget, int32_t pointerId) > { > // https://w3c.github.io/pointerevents/#releasing-pointer-capture > >@@ -78,7 +82,7 @@ ExceptionOr<void> PointerCaptureController::releasePointerCapture(Element* captu > // 1. If the pointerId provided as the method's argument does not match any of the active pointers and these steps are not > // being invoked as a result of the implicit release of pointer capture, then throw a DOMException with the name NotFoundError. > auto iterator = m_activePointerIdsToCapturingData.find(pointerId); >- if (implicit == ImplicitCapture::No && iterator == m_activePointerIdsToCapturingData.end()) >+ if (iterator == m_activePointerIdsToCapturingData.end()) > return Exception { NotFoundError }; > > // 2. If hasPointerCapture is false for the Element with the specified pointerId, then terminate these steps. >@@ -124,6 +128,12 @@ void PointerCaptureController::touchEndedOrWasCancelledForIdentifier(int32_t poi > m_activePointerIdsToCapturingData.remove(pointerId); > } > >+bool PointerCaptureController::hasCancelledPointerEventForIdentifier(int32_t pointerId) >+{ >+ auto iterator = m_activePointerIdsToCapturingData.find(pointerId); >+ return iterator != m_activePointerIdsToCapturingData.end() && iterator->value.cancelled; >+} >+ > void PointerCaptureController::pointerEventWillBeDispatched(const PointerEvent& event, EventTarget* target) > { > // https://w3c.github.io/pointerevents/#implicit-pointer-capture >@@ -142,7 +152,9 @@ void PointerCaptureController::pointerEventWillBeDispatched(const PointerEvent& > return; > > auto pointerId = event.pointerId(); >- m_activePointerIdsToCapturingData.set(pointerId, CapturingData { }); >+ CapturingData capturingData; >+ capturingData.pointerType = event.pointerType(); >+ m_activePointerIdsToCapturingData.set(pointerId, capturingData); > setPointerCapture(downcast<Element>(target), pointerId); > } > >@@ -171,6 +183,48 @@ void PointerCaptureController::pointerEventWasDispatched(const PointerEvent& eve > processPendingPointerCapture(event); > } > >+void PointerCaptureController::cancelPointer(int32_t pointerId, const IntPoint& documentPoint) >+{ >+ // https://w3c.github.io/pointerevents/#the-pointercancel-event >+ >+ // A user agent MUST fire a pointer event named pointercancel in the following circumstances: >+ // >+ // The user agent has determined that a pointer is unlikely to continue to produce events (for example, because of a hardware event). >+ // After having fired the pointerdown event, if the pointer is subsequently used to manipulate the page viewport (e.g. panning or zooming). >+ // Immediately before drag operation starts [HTML], for the pointer that caused the drag operation. >+ // After firing the pointercancel event, a user agent MUST also fire a pointer event named pointerout followed by firing a pointer event named pointerleave. >+ >+ // https://w3c.github.io/pointerevents/#implicit-release-of-pointer-capture >+ >+ // Immediately after firing the pointerup or pointercancel events, a user agent MUST clear the pending pointer capture target >+ // override for the pointerId of the pointerup or pointercancel event that was just dispatched, and then run Process Pending >+ // Pointer Capture steps to fire lostpointercapture if necessary. After running Process Pending Pointer Capture steps, if the >+ // pointer supports hover, user agent MUST also send corresponding boundary events necessary to reflect the current position of >+ // the pointer with no capture. >+ >+ auto iterator = m_activePointerIdsToCapturingData.find(pointerId); >+ if (iterator == m_activePointerIdsToCapturingData.end()) >+ return; >+ >+ auto& capturingData = iterator->value; >+ if (capturingData.cancelled) >+ return; >+ >+ capturingData.pendingTargetOverride = nullptr; >+ capturingData.cancelled = true; >+ >+ auto& target = capturingData.targetOverride; >+ if (!target) >+ target = m_page.mainFrame().eventHandler().hitTestResultAtPoint(documentPoint, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::AllowChildFrameContent).innerNonSharedElement(); >+ >+ if (!target) >+ return; >+ >+ auto event = PointerEvent::create(eventNames().pointercancelEvent, pointerId, capturingData.pointerType); >+ target->dispatchEvent(event); >+ processPendingPointerCapture(WTFMove(event)); >+} >+ > void PointerCaptureController::processPendingPointerCapture(const PointerEvent& event) > { > // https://w3c.github.io/pointerevents/#process-pending-pointer-capture >diff --git a/Source/WebCore/page/PointerCaptureController.h b/Source/WebCore/page/PointerCaptureController.h >index 8e7d2201835a2f88b812f1c55ef603a3247126a8..720a5774235509659c7a5f40a9aa25186a7ee060 100644 >--- a/Source/WebCore/page/PointerCaptureController.h >+++ b/Source/WebCore/page/PointerCaptureController.h >@@ -38,27 +38,31 @@ class PointerCaptureController { > WTF_MAKE_NONCOPYABLE(PointerCaptureController); > WTF_MAKE_FAST_ALLOCATED; > public: >- explicit PointerCaptureController(); >- >- enum class ImplicitCapture : uint8_t { Yes, No }; >+ explicit PointerCaptureController(Page&); > > ExceptionOr<void> setPointerCapture(Element*, int32_t); >- ExceptionOr<void> releasePointerCapture(Element*, int32_t, ImplicitCapture implicit = ImplicitCapture::No); >+ ExceptionOr<void> releasePointerCapture(Element*, int32_t); > bool hasPointerCapture(Element*, int32_t); > > void pointerLockWasApplied(); > > void touchEndedOrWasCancelledForIdentifier(int32_t); >+ bool hasCancelledPointerEventForIdentifier(int32_t); > void pointerEventWillBeDispatched(const PointerEvent&, EventTarget*); > void pointerEventWasDispatched(const PointerEvent&); >+ WEBCORE_EXPORT void cancelPointer(int32_t, const IntPoint&); > > private: > struct CapturingData { >- Element* pendingTargetOverride; >- Element* targetOverride; >+ RefPtr<Element> pendingTargetOverride; >+ RefPtr<Element> targetOverride; >+ String pointerType; >+ bool cancelled { false }; > }; > > void processPendingPointerCapture(const PointerEvent&); >+ >+ Page& m_page; > HashMap<int32_t, CapturingData> m_activePointerIdsToCapturingData; > }; > >diff --git a/Source/WebKit/Platform/spi/ios/UIKitSPI.h b/Source/WebKit/Platform/spi/ios/UIKitSPI.h >index 53f3ff71e1e8900b02a87b351e5299365c7f99ba..0978e6da47a79d6484b9cf18826bbd4e5ea39278 100644 >--- a/Source/WebKit/Platform/spi/ios/UIKitSPI.h >+++ b/Source/WebKit/Platform/spi/ios/UIKitSPI.h >@@ -1031,6 +1031,11 @@ typedef NSInteger UICompositingMode; > > #endif // USE(APPLE_INTERNAL_SDK) > >+// FIXME: <rdar://problem/47714562> >+@interface UIWebTouchEventsGestureRecognizer () >+@property (nonatomic, readonly) NSMapTable<NSNumber *, UITouch *> *activeTouchesByIdentifier; >+@end >+ > @interface UIPhysicalKeyboardEvent : UIPressesEvent > @end > >diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm b/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm >index 878e3e2f35bf9333c87f0db7793434f59f102023..9a73a36c4fef977e89acc25dffcd3a1c741d8aad 100644 >--- a/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm >+++ b/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm >@@ -2551,6 +2551,10 @@ - (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView * > [_contentView scrollViewWillStartPanOrPinchGesture]; > } > [_contentView willStartZoomOrScroll]; >+ >+#if ENABLE(POINTER_EVENTS) >+ [_contentView cancelPointersForGestureRecognizer:scrollView.pinchGestureRecognizer]; >+#endif > } > > - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView >@@ -2635,8 +2639,10 @@ - (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView > #if ENABLE(POINTER_EVENTS) > - (CGPoint)_scrollView:(UIScrollView *)scrollView adjustedOffsetForOffset:(CGPoint)offset translation:(CGPoint)translation startPoint:(CGPoint)start locationInView:(CGPoint)locationInView horizontalVelocity:(inout double *)hv verticalVelocity:(inout double *)vv > { >- if (![_contentView preventsPanningInXAxis] && ![_contentView preventsPanningInYAxis]) >+ if (![_contentView preventsPanningInXAxis] && ![_contentView preventsPanningInYAxis]) { >+ [_contentView cancelPointersForGestureRecognizer:scrollView.panGestureRecognizer]; > return offset; >+ } > > CGPoint adjustedContentOffset = CGPointMake(offset.x, offset.y); > if ([_contentView preventsPanningInXAxis]) >@@ -2644,6 +2650,11 @@ - (CGPoint)_scrollView:(UIScrollView *)scrollView adjustedOffsetForOffset:(CGPoi > if ([_contentView preventsPanningInYAxis]) > adjustedContentOffset.y = start.y; > >+ if ((![_contentView preventsPanningInXAxis] && adjustedContentOffset.x != start.x) >+ || (![_contentView preventsPanningInYAxis] && adjustedContentOffset.y != start.y)) { >+ [_contentView cancelPointersForGestureRecognizer:scrollView.panGestureRecognizer]; >+ } >+ > return adjustedContentOffset; > } > #endif >diff --git a/Source/WebKit/UIProcess/PageClient.h b/Source/WebKit/UIProcess/PageClient.h >index 4872c94a41d7e28305599d40ceeb946c1e809401..9617d0dac03bef66213d2ed06e86964762392b8f 100644 >--- a/Source/WebKit/UIProcess/PageClient.h >+++ b/Source/WebKit/UIProcess/PageClient.h >@@ -52,6 +52,7 @@ OBJC_CLASS CALayer; > OBJC_CLASS NSFileWrapper; > OBJC_CLASS NSMenu; > OBJC_CLASS NSSet; >+OBJC_CLASS UIGestureRecognizer; > OBJC_CLASS WKDrawingView; > OBJC_CLASS _WKRemoteObjectRegistry; > >@@ -477,6 +478,11 @@ public: > #if HAVE(PENCILKIT) > virtual RetainPtr<WKDrawingView> createDrawingView(WebCore::GraphicsLayer::EmbeddedViewID) { return nullptr; } > #endif >+ >+#if ENABLE(POINTER_EVENTS) >+ virtual void cancelPointersForGestureRecognizer(UIGestureRecognizer*) { } >+#endif >+ > }; > > } // namespace WebKit >diff --git a/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h b/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h >index df0715662f4dc995cbd535ca37e81c26a29d3e13..0a307097793e2be029185f521115b7bd8d119549 100644 >--- a/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h >+++ b/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h >@@ -71,6 +71,7 @@ public: > WebCore::ScrollingNodeID rootScrollingNodeID() const; > > const RemoteLayerTreeHost* layerTreeHost() const; >+ WebPageProxy& webPageProxy() const { return m_webPageProxy; } > > struct RequestedScrollInfo { > bool requestsScrollPositionUpdate { }; >diff --git a/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.h b/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.h >index a34c80c7057dfd0c0c3a9044265725321a7a2cb9..92dbe79ed6c320024739f1e6c0cf1b2a837b4efd 100644 >--- a/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.h >+++ b/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.h >@@ -67,6 +67,7 @@ public: > void updateChildNodesAfterScroll(const WebCore::FloatPoint& scrollPosition); > #if ENABLE(POINTER_EVENTS) > Optional<TouchActionData> touchActionData() const; >+ void cancelPointersForGestureRecognizer(UIGestureRecognizer*); > #endif > > private: >diff --git a/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm b/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm >index dc55da941c037fab634b8e08a11decab32515a45..03957f448ce212b0292eef9efac145a320e7d33c 100644 >--- a/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm >+++ b/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm >@@ -43,6 +43,10 @@ > #import <WebCore/ScrollSnapOffsetsInfo.h> > #endif > >+#if ENABLE(POINTER_EVENTS) >+#import "PageClient.h" >+#endif >+ > @implementation WKScrollingNodeScrollViewDelegate > > - (instancetype)initWithScrollingTreeNodeDelegate:(WebKit::ScrollingTreeScrollingNodeDelegateIOS*)delegate >@@ -141,8 +145,10 @@ - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView > - (CGPoint)_scrollView:(UIScrollView *)scrollView adjustedOffsetForOffset:(CGPoint)offset translation:(CGPoint)translation startPoint:(CGPoint)start locationInView:(CGPoint)locationInView horizontalVelocity:(inout double *)hv verticalVelocity:(inout double *)vv > { > auto touchActionData = _scrollingTreeNodeDelegate->touchActionData(); >- if (!touchActionData) >+ if (!touchActionData) { >+ [self cancelPointersForGestureRecognizer:scrollView.panGestureRecognizer]; > return offset; >+ } > > auto touchActions = touchActionData->touchActions; > if (touchActions == WebCore::TouchAction::Auto || touchActions == WebCore::TouchAction::Manipulation) >@@ -155,8 +161,23 @@ - (CGPoint)_scrollView:(UIScrollView *)scrollView adjustedOffsetForOffset:(CGPoi > if (!touchActions.contains(WebCore::TouchAction::PanY)) > adjustedContentOffset.y = start.y; > >+ if ((touchActions.contains(WebCore::TouchAction::PanX) && adjustedContentOffset.x != start.x) >+ || (touchActions.contains(WebCore::TouchAction::PanY) && adjustedContentOffset.y != start.y)) { >+ [self cancelPointersForGestureRecognizer:scrollView.panGestureRecognizer]; >+ } >+ > return adjustedContentOffset; > } >+ >+- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view >+{ >+ [self cancelPointersForGestureRecognizer:scrollView.pinchGestureRecognizer]; >+} >+ >+- (void)cancelPointersForGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer >+{ >+ _scrollingTreeNodeDelegate->cancelPointersForGestureRecognizer(gestureRecognizer); >+} > #endif > > @end >@@ -334,6 +355,11 @@ Optional<TouchActionData> ScrollingTreeScrollingNodeDelegateIOS::touchActionData > { > return downcast<RemoteScrollingTree>(scrollingTree()).scrollingCoordinatorProxy().touchActionDataForScrollNodeID(scrollingNode().scrollingNodeID()); > } >+ >+void ScrollingTreeScrollingNodeDelegateIOS::cancelPointersForGestureRecognizer(UIGestureRecognizer* gestureRecognizer) >+{ >+ downcast<RemoteScrollingTree>(scrollingTree()).scrollingCoordinatorProxy().webPageProxy().pageClient().cancelPointersForGestureRecognizer(gestureRecognizer); >+} > #endif > > } // namespace WebKit >diff --git a/Source/WebKit/UIProcess/WebPageProxy.cpp b/Source/WebKit/UIProcess/WebPageProxy.cpp >index f8a299508792811026c6bf24967a9563fcca8ee2..3225d437be51ae3fee0303d702b4c44e1d979052 100644 >--- a/Source/WebKit/UIProcess/WebPageProxy.cpp >+++ b/Source/WebKit/UIProcess/WebPageProxy.cpp >@@ -2649,6 +2649,13 @@ void WebPageProxy::handleTouchEvent(const NativeWebTouchEvent& event) > } > #endif // ENABLE(TOUCH_EVENTS) > >+#if ENABLE(POINTER_EVENTS) >+void WebPageProxy::cancelPointer(int32_t pointerId, const WebCore::IntPoint& documentPoint) >+{ >+ m_process->send(Messages::WebPage::CancelPointer(pointerId, documentPoint), m_pageID); >+} >+#endif >+ > void WebPageProxy::scrollBy(ScrollDirection direction, ScrollGranularity granularity) > { > if (!isValid()) >diff --git a/Source/WebKit/UIProcess/WebPageProxy.h b/Source/WebKit/UIProcess/WebPageProxy.h >index 3abd335f97010574a64c47cd94bca03b563a6a46..1e20c4be908df9a69a8e4e8975bb612a957d9aeb 100644 >--- a/Source/WebKit/UIProcess/WebPageProxy.h >+++ b/Source/WebKit/UIProcess/WebPageProxy.h >@@ -790,6 +790,10 @@ public: > void handleTouchEvent(const NativeWebTouchEvent&); > #endif > >+#if ENABLE(POINTER_EVENTS) >+ void cancelPointer(int32_t, const WebCore::IntPoint&); >+#endif >+ > void scrollBy(WebCore::ScrollDirection, WebCore::ScrollGranularity); > void centerSelectionInVisibleArea(); > >diff --git a/Source/WebKit/UIProcess/ios/PageClientImplIOS.h b/Source/WebKit/UIProcess/ios/PageClientImplIOS.h >index 58be76b7aa52e00ae33e1697a77b8529bb8a1533..a3c6d3af89d506677958704dd901667db41e96e1 100644 >--- a/Source/WebKit/UIProcess/ios/PageClientImplIOS.h >+++ b/Source/WebKit/UIProcess/ios/PageClientImplIOS.h >@@ -239,6 +239,10 @@ private: > RetainPtr<WKDrawingView> createDrawingView(WebCore::GraphicsLayer::EmbeddedViewID) override; > #endif > >+#if ENABLE(POINTER_EVENTS) >+ void cancelPointersForGestureRecognizer(UIGestureRecognizer*) override; >+#endif >+ > WKContentView *m_contentView; > RetainPtr<WKEditorUndoTarget> m_undoTarget; > }; >diff --git a/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm b/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm >index 4a992bf234e410056b21a8a89bae858738b7da88..1509cc27429943acbdc35a68f255f9eebbad6272 100644 >--- a/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm >+++ b/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm >@@ -844,6 +844,13 @@ RetainPtr<WKDrawingView> PageClientImpl::createDrawingView(WebCore::GraphicsLaye > } > #endif > >+#if ENABLE(POINTER_EVENTS) >+void PageClientImpl::cancelPointersForGestureRecognizer(UIGestureRecognizer* gestureRecognizer) >+{ >+ [m_contentView cancelPointersForGestureRecognizer:gestureRecognizer]; >+} >+#endif >+ > } // namespace WebKit > > #endif // PLATFORM(IOS_FAMILY) >diff --git a/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h b/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h >index af2f109f72230fa1f1b86132e1e8e45c0b5e255d..fad0bcbae2833bfe1fd7fc9551f46c857dbdea01 100644 >--- a/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h >+++ b/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h >@@ -378,6 +378,10 @@ struct WKAutoCorrectionData { > - (BOOL)canPerformActionForWebView:(SEL)action withSender:(id)sender; > - (id)targetForActionForWebView:(SEL)action withSender:(id)sender; > >+#if ENABLE(POINTER_EVENTS) >+- (void)cancelPointersForGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer; >+#endif >+ > #define DECLARE_WKCONTENTVIEW_ACTION_FOR_WEB_VIEW(_action) \ > - (void)_action ## ForWebView:(id)sender; > FOR_EACH_WKCONTENTVIEW_ACTION(DECLARE_WKCONTENTVIEW_ACTION_FOR_WEB_VIEW) >diff --git a/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm b/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm >index 5eaba0f53cc9b46abd08ed8efdaa1fffbf5f0650..7a986429b152a36c03470961e49405c98e3ec32a 100644 >--- a/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm >+++ b/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm >@@ -1146,6 +1146,22 @@ - (BOOL)resignFirstResponderForWebView > return superDidResign; > } > >+#if ENABLE(POINTER_EVENTS) >+- (void)cancelPointersForGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer >+{ >+ // FIXME: <rdar://problem/47714562> >+ if (![_touchEventGestureRecognizer respondsToSelector:@selector(activeTouchesByIdentifier)]) >+ return; >+ >+ NSMapTable<NSNumber *, UITouch *> *activeTouches = [_touchEventGestureRecognizer activeTouchesByIdentifier]; >+ for (NSNumber *touchIdentifier in activeTouches) { >+ UITouch *touch = [activeTouches objectForKey:touchIdentifier]; >+ if ([touch.gestureRecognizers containsObject:gestureRecognizer]) >+ _page->cancelPointer([touchIdentifier unsignedIntValue], WebCore::roundedIntPoint([touch locationInView:self])); >+ } >+} >+#endif >+ > - (void)_webTouchEventsRecognized:(UIWebTouchEventsGestureRecognizer *)gestureRecognizer > { > if (!_page->isValid()) >diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.cpp b/Source/WebKit/WebProcess/WebPage/WebPage.cpp >index 23a9780a8afe98180bf3703f65cc4e03f3319bff..f080f2ea26ceed194decdabd901c808ce77c33b9 100644 >--- a/Source/WebKit/WebProcess/WebPage/WebPage.cpp >+++ b/Source/WebKit/WebProcess/WebPage/WebPage.cpp >@@ -190,6 +190,7 @@ > #include <WebCore/PlatformKeyboardEvent.h> > #include <WebCore/PlatformMediaSessionManager.h> > #include <WebCore/PluginDocument.h> >+#include <WebCore/PointerCaptureController.h> > #include <WebCore/PrintContext.h> > #include <WebCore/PromisedAttachmentInfo.h> > #include <WebCore/Range.h> >@@ -2796,6 +2797,13 @@ void WebPage::touchEvent(const WebTouchEvent& touchEvent) > } > #endif > >+#if ENABLE(POINTER_EVENTS) >+void WebPage::cancelPointer(int32_t pointerId, const WebCore::IntPoint& documentPoint) >+{ >+ m_page->pointerCaptureController().cancelPointer(pointerId, documentPoint); >+} >+#endif >+ > #if ENABLE(MAC_GESTURE_EVENTS) > static bool handleGestureEvent(const WebGestureEvent& event, Page* page) > { >diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.h b/Source/WebKit/WebProcess/WebPage/WebPage.h >index 1be5906c95d518d3651b9a76c326b100d2f76115..22d05d5af10cfa96b754b147792441d838524752 100644 >--- a/Source/WebKit/WebProcess/WebPage/WebPage.h >+++ b/Source/WebKit/WebProcess/WebPage/WebPage.h >@@ -1240,6 +1240,10 @@ private: > void touchEvent(const WebTouchEvent&); > #endif > >+#if ENABLE(POINTER_EVENTS) >+ void cancelPointer(int32_t, const WebCore::IntPoint&); >+#endif >+ > #if ENABLE(CONTEXT_MENUS) > void contextMenuHidden() { m_isShowingContextMenu = false; } > void contextMenuForKeyEvent(); >diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.messages.in b/Source/WebKit/WebProcess/WebPage/WebPage.messages.in >index 47e9ce6ba7c6992b1d8796b27e0dc898a702f7e8..fc1ce331f5c983fa42c26f8c58f9f895df5801ea 100644 >--- a/Source/WebKit/WebProcess/WebPage/WebPage.messages.in >+++ b/Source/WebKit/WebProcess/WebPage/WebPage.messages.in >@@ -127,6 +127,10 @@ messages -> WebPage LegacyReceiver { > TouchEvent(WebKit::WebTouchEvent event) > #endif > >+#if ENABLE(POINTER_EVENTS) >+ CancelPointer(int32_t pointerId, WebCore::IntPoint documentPoint) >+#endif >+ > #if ENABLE(INPUT_TYPE_COLOR) > DidEndColorPicker() > DidChooseColor(WebCore::Color color)
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
Flags:
dino
:
review+
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 193962
: 360774