Branch: refs/heads/main Home: https://github.com/WebKit/WebKit Commit: 1d53e9e772799fdf249e97101b2fb4b88d7891c8 https://github.com/WebKit/WebKit/commit/1d53e9e772799fdf249e97101b2fb4b88d7891c8 Author: Wenson Hsieh <wenson_hs...@apple.com> Date: 2023-08-04 (Fri, 04 Aug 2023)
Changed paths: M Source/WTF/wtf/PlatformHave.h M Source/WebKit/Platform/spi/ios/UIKitSPI.h M Source/WebKit/SourcesCocoa.txt M Source/WebKit/UIProcess/ios/WKContentViewInteraction.h M Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm R Source/WebKit/UIProcess/ios/WKMouseGestureRecognizer.h R Source/WebKit/UIProcess/ios/WKMouseGestureRecognizer.mm A Source/WebKit/UIProcess/ios/WKMouseInteraction.h A Source/WebKit/UIProcess/ios/WKMouseInteraction.mm M Source/WebKit/WebKit.xcodeproj/project.pbxproj M Tools/TestWebKitAPI/Tests/WebKitCocoa/iOSMouseSupport.mm Log Message: ----------- Hover and pointer events on iPad/Catalyst should not rely on _UIHoverEventRespondable https://bugs.webkit.org/show_bug.cgi?id=259826 rdar://113396945 Reviewed by Tim Horton and Abrar Rahman Protyasha. Currently, (non-synthetic) mouse events — e.g., `mousemove`, `mouseup`, `mousedown` — are dispatched through `WKMouseGestureRecognizer`, which both: • Listens for mousedown/mouseup and mouse drags via `-touches(Began|Moved|Ended):withEvent:`. • Listens for mousemove when no button is pressed via the `_UIHoverEventRespondable` methods, `-_hover(Entered|Moved|Exited):withEvent:`. This same gesture is also used to recognize hover when using an Pencil on newer iPad models. This implementation is convenient in many ways since we have a single gesture recognizer capable of servicing all non-touch, pointer-related event dispatch; however, it also relies heavily on private (and even internal) pointer support in UIKit. Since both of the above criteria are achievable today via `UIHoverGestureRecognizer`, we can move away from `_UIHoverEventRespondable` altogether. To achieve this, we: 1. Add a `UIGestureRecognizer` to listen for active "mouse touches"; importantly, this gesture only recognizes events while the user is clicking or dragging with a trackpad. 2. Add two `UIHoverGestureRecognizer`s to listen for passive hover events, when the user is either moving the cursor over web content without any mouse button held down, or when using an Pencil with the pointer near the screen. 3. To help manage the lifetimes of these gestures and provide a common interface for notifying the content view when it's time to dispatch new mouse events, we encapsulate the three gestures above into a single `UIInteraction` — `WKMouseInteraction` — which exposes all the same functionality as the former `WKMouseGestureRecognizer`, but through an internal delegate method hook implemented by `WKContentView`. There should be no change in behavior; see below for details. * Source/WebKit/SourcesCocoa.txt: * Source/WebKit/UIProcess/ios/WKContentViewInteraction.h: * Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView cleanUpInteraction]): (-[WKContentView _removeDefaultGestureRecognizers]): (-[WKContentView _addDefaultGestureRecognizers]): Replace any uses of `_mouseGestureRecognizer` and `_pencilHoverGestureRecognizer` with `_mouseInteraction`. (-[WKContentView gestureRecognizer:shouldReceiveTouch:]): (-[WKContentView gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:]): (-[WKContentView _showShareSheet:inRect:completionHandler:]): (-[WKContentView deferringGestureRecognizer:shouldDeferOtherGestureRecognizer:]): Replace a couple of class checks with a check for `-[WKMouseInteraction hasGesture:]`. (-[WKContentView setUpMouseGestureRecognizer]): (-[WKContentView mouseInteraction:changedWithEvent:]): (-[WKContentView _configureMouseGestureRecognizer]): Use `-setEnabled:` to either enable or disable all three of the hover gestures encapsulated by the new mouse interaction. (-[WKContentView mouseGestureRecognizerChanged:]): Deleted. Replace this with a delegate method implementation for `-mouseInteraction:changedWithEvent:`; like before, this is invoked in response to mouse or pencil activity that should dispatch a `mousemove`, `mousedown` or `mouseup` event to the page. * Source/WebKit/UIProcess/ios/WKMouseGestureRecognizer.mm: Removed. * Source/WebKit/UIProcess/ios/WKMouseInteraction.h: Renamed from Source/WebKit/UIProcess/ios/WKMouseGestureRecognizer.h. * Source/WebKit/UIProcess/ios/WKMouseInteraction.mm: Added. Replace `WKMouseGestureRecognizer` with `WKMouseInteraction`. (-[WKMouseTouchGestureRecognizer initWithInteraction:]): (-[WKMouseTouchGestureRecognizer touchesBegan:withEvent:]): (-[WKMouseTouchGestureRecognizer touchesMoved:withEvent:]): (-[WKMouseTouchGestureRecognizer touchesEnded:withEvent:]): (-[WKMouseTouchGestureRecognizer touchesCancelled:withEvent:]): See (1) above; this listens for mouse drags and mouse clicks by implementing the `-touches*:` subclassing hooks, and calling into `-_updateMouseTouches:` below. (-[WKMouseInteraction initWithDelegate:]): (-[WKMouseInteraction _resetCachedState]): (-[WKMouseInteraction hasGesture:]): (-[WKMouseInteraction view]): (-[WKMouseInteraction isEnabled]): (-[WKMouseInteraction _forEachGesture:]): (-[WKMouseInteraction setEnabled:]): (-[WKMouseInteraction mouseTouch]): (-[WKMouseInteraction mouseTouchGestureRecognizer]): (-[WKMouseInteraction _activeGesture]): (pointerType): (-[WKMouseInteraction createMouseEventWithType:wasCancelled:]): This method was directly carried over from `WKMouseGestureRecognizer`, and is still used to convert gesture recognizer and `UITouch` state into platform mouse events to be dispatched to the page. (-[WKMouseInteraction willMoveToView:]): (-[WKMouseInteraction didMoveToView:]): Implement basic `UIInteraction` protocol functionality, by respectively adding and removing three managed gesture recognizers when adding or removing the interaction. (-[WKMouseInteraction gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:]): (-[WKMouseInteraction gestureRecognizer:shouldReceiveTouch:]): Limit touches to those dispatched by pointing devices (e.g. Pencil or trackpad). Additionally save the `UITouch` associated with the touch event, so that we can reference it later inside of `-_hoverGestureRecognized:`. (-[WKMouseInteraction _hoverGestureRecognized:]): Invoked whenever either the pointer or pencil hover gestures are recognized, when hovering over the web view without clicking or dragging. (-[WKMouseInteraction _updateMouseTouches:]): Invoked whenever the user clicks and drags with a trackpad. (-[WKMouseInteraction locationInView:]): * Source/WebKit/WebKit.xcodeproj/project.pbxproj: * Tools/TestWebKitAPI/Tests/WebKitCocoa/iOSMouseSupport.mm: (-[WKTestingTouch locationInView:]): (-[WKTestingTouch setLocationInView:]): (-[WKTestingTouch setTapCount:]): (-[WKTestingTouch setPhase:]): (-[WKTestingTouch phase]): (-[WKTestingTouch _isPointerTouch]): (TestWebKitAPI::MouseEventTestHarness::MouseEventTestHarness): (TestWebKitAPI::MouseEventTestHarness::mouseMove): (TestWebKitAPI::MouseEventTestHarness::mouseDown): (TestWebKitAPI::MouseEventTestHarness::mouseUp): (TestWebKitAPI::MouseEventTestHarness::mouseCancel): (TestWebKitAPI::MouseEventTestHarness::webView const): (TestWebKitAPI::MouseEventTestHarness::mouseInteraction const): Update various API tests to be compatible with the new mouse interaction. We also clean up the testing logic here by introducing a new helper class, `MouseEventTestHarness`, that encapsulates logic for simulating mouse moves and clicks through a combination of directly invoking gesture recognizer methods and swizzling. (-[WKTestingEvent locationInView:]): Deleted. (-[WKTestingEvent _setButtonMask:]): Deleted. (-[WKTestingEvent _buttonMask]): Deleted. (mouseGesture): Deleted. (handleUpdatedSelection): Deleted. (simulateEditContextMenuAppearance): Deleted. Canonical link: https://commits.webkit.org/266610@main _______________________________________________ webkit-changes mailing list webkit-changes@lists.webkit.org https://lists.webkit.org/mailman/listinfo/webkit-changes