[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