[webkit-changes] [WebKit/WebKit] 1d53e9: Hover and pointer events on iPad/Catalyst should n...
Wenson Hsieh
noreply at github.com
Fri Aug 4 18:57:22 PDT 2023
Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 1d53e9e772799fdf249e97101b2fb4b88d7891c8
https://github.com/WebKit/WebKit/commit/1d53e9e772799fdf249e97101b2fb4b88d7891c8
Author: Wenson Hsieh <wenson_hsieh at 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
More information about the webkit-changes
mailing list