Title: [289463] trunk/Source/WebKit
Revision
289463
Author
[email protected]
Date
2022-02-09 01:30:46 -0800 (Wed, 09 Feb 2022)

Log Message

WKHoverPlatter should scale up the platter content to make it easier to see
https://bugs.webkit.org/show_bug.cgi?id=236289

Reviewed by Wenson Hsieh.

* Shared/NativeWebMouseEvent.h:
* Shared/ios/NativeWebMouseEventIOS.mm:
(WebKit::NativeWebMouseEvent::NativeWebMouseEvent):
Add a NativeWebMouseEvent constructor that takes most properties from
another event, but allows overriding the positions and deltas.

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::interactableRegionsInRootViewCoordinates):
* UIProcess/WebPageProxy.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::interactableRegionsInRootViewCoordinates):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:
Add a method to count the number of clickable elements in a given rectangle.
This is just a first attempt at the heuristic; this will get more complex in the future.

* UIProcess/ios/WKContentViewInteraction.h:
Add a selection assistant suppression reason for WKHoverPlatter.

* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView _createAndConfigureHighlightLongPressGestureRecognizer]):
Factor out highlight-long-press gesture creation like long-press. Bail if the platter is enabled.

(-[WKContentView setUpInteraction]):
Disable the selection assistant if WKHoverPlatter wants to use long press.

(-[WKContentView cleanUpInteraction]):
(-[WKContentView _locationForGesture:]):
(-[WKContentView _startPointForGesture:]):
Add funnels for extracting the primary location or starting location from
a gesture, allowing WKHoverPlatter to mutate it if it is currently engaged.

(-[WKContentView _highlightLongPressRecognized:]):
(-[WKContentView _doubleTapRecognizedForDoubleClick:]):
(-[WKContentView _twoFingerSingleTapGestureRecognized:]):
(-[WKContentView _singleTapIdentified:]):
(-[WKContentView _singleTapRecognized:]):
(-[WKContentView _doubleTapRecognized:]):
(-[WKContentView _nonBlockingDoubleTapRecognized:]):
(-[WKContentView _twoFingerDoubleTapRecognized:]):
Adopt _locationForGesture/_startPointForGesture.

(-[WKContentView _longPressRecognized:]):
Adopt _locationForGesture/_startPointForGesture.
Redirect a recognized long press to WKHoverPlatter if it wants to use long press.

(-[WKContentView _shouldUseContextMenus]):
Disable context menus if WKHoverPlatter wants to use long press.

(-[WKContentView setUpDragAndDropInteractions]):
Disable drag and drop if WKHoverPlatter wants to use long press.

(-[WKContentView mouseGestureRecognizerChanged:]):
Allow WKHoverPlatter to mutate the location of mouse events if it is currently engaged.

(-[WKContentView numberOfLinksForHoverPlatter:inRect:completionHandler:]):
* UIProcess/ios/WKHoverPlatter.h:
* UIProcess/ios/WKHoverPlatter.mm:
(-[WKHoverPlatter initWithView:delegate:]):
(-[WKHoverPlatter didReceiveMouseEvent:]):
(-[WKHoverPlatter didLongPressAtPoint:]):
(-[WKHoverPlatter platterBoundingRect]):
(-[WKHoverPlatter linkSearchRect]):
(-[WKHoverPlatter update]):
(-[WKHoverPlatter updateDebugIndicator]):
(-[WKHoverPlatter dismissPlatterWithAnimation:]):
(-[WKHoverPlatter didFinishDismissalAnimation:]):
(-[WKHoverPlatter clearLayers]):
(-[WKHoverPlatter adjustedPointForPoint:]):
(-[WKHoverPlatter adjustedEventForEvent:]):
(setAdditionalPlatterLayerProperties): Deleted.
(addAdditionalIncomingAnimations): Deleted.
(addAdditionalDismissalAnimations): Deleted.
(-[WKHoverPlatter setHoverPoint:]): Deleted.
(-[WKHoverPlatter requestPositionInformationForCurrentHoverPoint]): Deleted.
(-[WKHoverPlatter didReceivePositionInformation:]): Deleted.
(-[WKHoverPlatter didFinishAnimationForShadow:]): Deleted.
* UIProcess/ios/WKHoverPlatterParameters.h:
* UIProcess/ios/WKHoverPlatterParameters.mm:
(-[WKHoverPlatterParameters setDefaultValues]):
(-[WKHoverPlatterParameters enabled]):
(+[WKHoverPlatterParameters settingsControllerModule]):
(addAdditionalPlatterLayoutParameters): Deleted.
(setDefaultValuesForAdditionalPlatterLayoutParameters): Deleted.
Adjust WKHoverPlatter to scale up its content, and adjust the shape
and animations.

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (289462 => 289463)


--- trunk/Source/WebKit/ChangeLog	2022-02-09 09:15:58 UTC (rev 289462)
+++ trunk/Source/WebKit/ChangeLog	2022-02-09 09:30:46 UTC (rev 289463)
@@ -1,3 +1,97 @@
+2022-02-09  Tim Horton  <[email protected]>
+
+        WKHoverPlatter should scale up the platter content to make it easier to see
+        https://bugs.webkit.org/show_bug.cgi?id=236289
+
+        Reviewed by Wenson Hsieh.
+
+        * Shared/NativeWebMouseEvent.h:
+        * Shared/ios/NativeWebMouseEventIOS.mm:
+        (WebKit::NativeWebMouseEvent::NativeWebMouseEvent):
+        Add a NativeWebMouseEvent constructor that takes most properties from
+        another event, but allows overriding the positions and deltas.
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::interactableRegionsInRootViewCoordinates):
+        * UIProcess/WebPageProxy.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::interactableRegionsInRootViewCoordinates):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+        Add a method to count the number of clickable elements in a given rectangle.
+        This is just a first attempt at the heuristic; this will get more complex in the future.
+
+        * UIProcess/ios/WKContentViewInteraction.h:
+        Add a selection assistant suppression reason for WKHoverPlatter.
+
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView _createAndConfigureHighlightLongPressGestureRecognizer]):
+        Factor out highlight-long-press gesture creation like long-press. Bail if the platter is enabled.
+
+        (-[WKContentView setUpInteraction]):
+        Disable the selection assistant if WKHoverPlatter wants to use long press.
+
+        (-[WKContentView cleanUpInteraction]):
+        (-[WKContentView _locationForGesture:]):
+        (-[WKContentView _startPointForGesture:]):
+        Add funnels for extracting the primary location or starting location from
+        a gesture, allowing WKHoverPlatter to mutate it if it is currently engaged.
+
+        (-[WKContentView _highlightLongPressRecognized:]):
+        (-[WKContentView _doubleTapRecognizedForDoubleClick:]):
+        (-[WKContentView _twoFingerSingleTapGestureRecognized:]):
+        (-[WKContentView _singleTapIdentified:]):
+        (-[WKContentView _singleTapRecognized:]):
+        (-[WKContentView _doubleTapRecognized:]):
+        (-[WKContentView _nonBlockingDoubleTapRecognized:]):
+        (-[WKContentView _twoFingerDoubleTapRecognized:]):
+        Adopt _locationForGesture/_startPointForGesture.
+
+        (-[WKContentView _longPressRecognized:]):
+        Adopt _locationForGesture/_startPointForGesture.
+        Redirect a recognized long press to WKHoverPlatter if it wants to use long press.
+
+        (-[WKContentView _shouldUseContextMenus]):
+        Disable context menus if WKHoverPlatter wants to use long press.
+
+        (-[WKContentView setUpDragAndDropInteractions]):
+        Disable drag and drop if WKHoverPlatter wants to use long press.
+
+        (-[WKContentView mouseGestureRecognizerChanged:]):
+        Allow WKHoverPlatter to mutate the location of mouse events if it is currently engaged.
+
+        (-[WKContentView numberOfLinksForHoverPlatter:inRect:completionHandler:]):
+        * UIProcess/ios/WKHoverPlatter.h:
+        * UIProcess/ios/WKHoverPlatter.mm:
+        (-[WKHoverPlatter initWithView:delegate:]):
+        (-[WKHoverPlatter didReceiveMouseEvent:]):
+        (-[WKHoverPlatter didLongPressAtPoint:]):
+        (-[WKHoverPlatter platterBoundingRect]):
+        (-[WKHoverPlatter linkSearchRect]):
+        (-[WKHoverPlatter update]):
+        (-[WKHoverPlatter updateDebugIndicator]):
+        (-[WKHoverPlatter dismissPlatterWithAnimation:]):
+        (-[WKHoverPlatter didFinishDismissalAnimation:]):
+        (-[WKHoverPlatter clearLayers]):
+        (-[WKHoverPlatter adjustedPointForPoint:]):
+        (-[WKHoverPlatter adjustedEventForEvent:]):
+        (setAdditionalPlatterLayerProperties): Deleted.
+        (addAdditionalIncomingAnimations): Deleted.
+        (addAdditionalDismissalAnimations): Deleted.
+        (-[WKHoverPlatter setHoverPoint:]): Deleted.
+        (-[WKHoverPlatter requestPositionInformationForCurrentHoverPoint]): Deleted.
+        (-[WKHoverPlatter didReceivePositionInformation:]): Deleted.
+        (-[WKHoverPlatter didFinishAnimationForShadow:]): Deleted.
+        * UIProcess/ios/WKHoverPlatterParameters.h:
+        * UIProcess/ios/WKHoverPlatterParameters.mm:
+        (-[WKHoverPlatterParameters setDefaultValues]):
+        (-[WKHoverPlatterParameters enabled]):
+        (+[WKHoverPlatterParameters settingsControllerModule]):
+        (addAdditionalPlatterLayoutParameters): Deleted.
+        (setDefaultValuesForAdditionalPlatterLayoutParameters): Deleted.
+        Adjust WKHoverPlatter to scale up its content, and adjust the shape
+        and animations.
+
 2022-02-09  Carlos Garcia Campos  <[email protected]>
 
         Unreviewed. Update OptionsGTK.cmake and NEWS for 2.35.3 release

Modified: trunk/Source/WebKit/Shared/NativeWebMouseEvent.h (289462 => 289463)


--- trunk/Source/WebKit/Shared/NativeWebMouseEvent.h	2022-02-09 09:15:58 UTC (rev 289462)
+++ trunk/Source/WebKit/Shared/NativeWebMouseEvent.h	2022-02-09 09:30:46 UTC (rev 289463)
@@ -71,6 +71,7 @@
 #elif PLATFORM(IOS_FAMILY)
     NativeWebMouseEvent(::WebEvent *);
     NativeWebMouseEvent(Type, Button, unsigned short buttons, const WebCore::IntPoint& position, const WebCore::IntPoint& globalPosition, float deltaX, float deltaY, float deltaZ, int clickCount, OptionSet<Modifier>, WallTime timestamp, double force, GestureWasCancelled, const String& pointerType);
+    NativeWebMouseEvent(const NativeWebMouseEvent&, const WebCore::IntPoint& position, const WebCore::IntPoint& globalPosition, float deltaX, float deltaY, float deltaZ);
 #elif USE(LIBWPE)
     NativeWebMouseEvent(struct wpe_input_pointer_event*, float deviceScaleFactor);
 #elif PLATFORM(WIN)

Modified: trunk/Source/WebKit/Shared/ios/NativeWebMouseEventIOS.mm (289462 => 289463)


--- trunk/Source/WebKit/Shared/ios/NativeWebMouseEventIOS.mm	2022-02-09 09:15:58 UTC (rev 289462)
+++ trunk/Source/WebKit/Shared/ios/NativeWebMouseEventIOS.mm	2022-02-09 09:30:46 UTC (rev 289463)
@@ -43,6 +43,11 @@
 {
 }
 
+NativeWebMouseEvent::NativeWebMouseEvent(const NativeWebMouseEvent& otherEvent, const WebCore::IntPoint& position, const WebCore::IntPoint& globalPosition, float deltaX, float deltaY, float deltaZ)
+    : WebMouseEvent(otherEvent.type(), otherEvent.button(), otherEvent.buttons(), position, globalPosition, deltaX, deltaY, deltaZ, otherEvent.clickCount(), otherEvent.modifiers(), otherEvent.timestamp(), otherEvent.force(), otherEvent.syntheticClickType(), otherEvent.pointerId(), otherEvent.pointerType(), otherEvent.gestureWasCancelled())
+{
+}
+
 } // namespace WebKit
 
 #endif // PLATFORM(IOS_FAMILY)

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (289462 => 289463)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2022-02-09 09:15:58 UTC (rev 289462)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2022-02-09 09:30:46 UTC (rev 289463)
@@ -11156,6 +11156,11 @@
     return m_configuration->captivePortalModeEnabled();
 }
 
+void WebPageProxy::interactableRegionsInRootViewCoordinates(FloatRect rect, CompletionHandler<void(Vector<FloatRect>)>&& completionHandler)
+{
+    sendWithAsyncReply(Messages::WebPage::InteractableRegionsInRootViewCoordinates(rect), WTFMove(completionHandler));
+}
+
 #if PLATFORM(COCOA)
 void WebPageProxy::appPrivacyReportTestingData(CompletionHandler<void(const AppPrivacyReportTestingData&)>&& completionHandler)
 {

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (289462 => 289463)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2022-02-09 09:15:58 UTC (rev 289462)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2022-02-09 09:30:46 UTC (rev 289463)
@@ -2059,6 +2059,8 @@
     void classifyModalContainerControls(Vector<String>&& texts, CompletionHandler<void(Vector<WebCore::ModalContainerControlType>&&)>&&);
     void decidePolicyForModalContainer(OptionSet<WebCore::ModalContainerControlType>, CompletionHandler<void(WebCore::ModalContainerDecision)>&&);
 
+    void interactableRegionsInRootViewCoordinates(WebCore::FloatRect, CompletionHandler<void(Vector<WebCore::FloatRect>)>&&);
+
 private:
     WebPageProxy(PageClient&, WebProcessProxy&, Ref<API::PageConfiguration>&&);
     void platformInitialize();

Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h (289462 => 289463)


--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h	2022-02-09 09:15:58 UTC (rev 289462)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h	2022-02-09 09:30:46 UTC (rev 289463)
@@ -222,7 +222,8 @@
 enum SuppressSelectionAssistantReason : uint8_t {
     EditableRootIsTransparentOrFullyClipped = 1 << 0,
     FocusedElementIsTooSmall = 1 << 1,
-    InteractionIsHappening = 1 << 2
+    InteractionIsHappening = 1 << 2,
+    HoverPlatterEnabled = 1 << 3,
 };
 
 struct WKSelectionDrawingInfo {

Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (289462 => 289463)


--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2022-02-09 09:15:58 UTC (rev 289462)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2022-02-09 09:30:46 UTC (rev 289463)
@@ -885,6 +885,19 @@
     [_singleTapGestureRecognizer requireGestureRecognizerToFail:_doubleTapGestureRecognizer.get()];
 }
 
+- (void)_createAndConfigureHighlightLongPressGestureRecognizer
+{
+#if HAVE(UIKIT_WITH_MOUSE_SUPPORT)
+    if (WKHoverPlatterDomain.rootSettings.platterEnabledForLongPress)
+        return;
+#endif
+
+    _highlightLongPressGestureRecognizer = adoptNS([[WKHighlightLongPressGestureRecognizer alloc] initWithTarget:self action:@selector(_highlightLongPressRecognized:)]);
+    [_highlightLongPressGestureRecognizer setDelay:highlightDelay];
+    [_highlightLongPressGestureRecognizer setDelegate:self];
+    [self addGestureRecognizer:_highlightLongPressGestureRecognizer.get()];
+}
+
 - (void)_createAndConfigureLongPressGestureRecognizer
 {
     _longPressGestureRecognizer = adoptNS([[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(_longPressRecognized:)]);
@@ -1013,11 +1026,7 @@
     [_twoFingerDoubleTapGestureRecognizer setDelegate:self];
     [self addGestureRecognizer:_twoFingerDoubleTapGestureRecognizer.get()];
 
-    _highlightLongPressGestureRecognizer = adoptNS([[WKHighlightLongPressGestureRecognizer alloc] initWithTarget:self action:@selector(_highlightLongPressRecognized:)]);
-    [_highlightLongPressGestureRecognizer setDelay:highlightDelay];
-    [_highlightLongPressGestureRecognizer setDelegate:self];
-    [self addGestureRecognizer:_highlightLongPressGestureRecognizer.get()];
-
+    [self _createAndConfigureHighlightLongPressGestureRecognizer];
     [self _createAndConfigureLongPressGestureRecognizer];
 
 #if HAVE(LINK_PREVIEW)
@@ -1287,6 +1296,11 @@
     [self _handleDOMPasteRequestWithResult:WebCore::DOMPasteAccessResponse::DeniedForGesture];
     [self _cancelPendingKeyEventHandler];
 
+#if HAVE(UIKIT_WITH_MOUSE_SUPPORT)
+    if (WKHoverPlatterDomain.rootSettings.platterEnabledForLongPress)
+        [self _startSuppressingSelectionAssistantForReason:WebKit::HoverPlatterEnabled];
+#endif
+
     _cachedSelectedTextRange = nil;
 }
 
@@ -3089,23 +3103,49 @@
     return _latestTapID;
 }
 
+- (CGPoint)_locationForGesture:(UIGestureRecognizer *)gestureRecognizer
+{
+    auto location = [gestureRecognizer locationInView:self];
+
+#if HAVE(UIKIT_WITH_MOUSE_SUPPORT)
+    if (WKHoverPlatterDomain.rootSettings.enabled)
+        return [_hoverPlatter adjustedPointForPoint:location];
+#endif
+
+    return location;
+}
+
+- (CGPoint)_startPointForGesture:(UILongPressGestureRecognizer *)gestureRecognizer
+{
+    auto location = [gestureRecognizer startPoint];
+
+#if HAVE(UIKIT_WITH_MOUSE_SUPPORT)
+    if (WKHoverPlatterDomain.rootSettings.enabled)
+        return [_hoverPlatter adjustedPointForPoint:location];
+#endif
+
+    return location;
+}
+
 - (void)_highlightLongPressRecognized:(UILongPressGestureRecognizer *)gestureRecognizer
 {
     ASSERT(gestureRecognizer == _highlightLongPressGestureRecognizer);
     [self _resetIsDoubleTapPending];
 
-    _lastInteractionLocation = gestureRecognizer.startPoint;
+    auto startPoint = [self _startPointForGesture:gestureRecognizer];
 
+    _lastInteractionLocation = startPoint;
+
     switch ([gestureRecognizer state]) {
     case UIGestureRecognizerStateBegan:
         _longPressCanClick = YES;
         cancelPotentialTapIfNecessary(self);
-        _page->tapHighlightAtPosition([gestureRecognizer startPoint], [self nextTapIdentifier]);
+        _page->tapHighlightAtPosition(startPoint, [self nextTapIdentifier]);
         _isTapHighlightIDValid = YES;
         break;
     case UIGestureRecognizerStateEnded:
         if (_longPressCanClick && _positionInformation.isElement) {
-            [self _attemptSyntheticClickAtLocation:gestureRecognizer.startPoint modifierFlags:gestureRecognizer.modifierFlags];
+            [self _attemptSyntheticClickAtLocation:startPoint modifierFlags:gestureRecognizer.modifierFlags];
             [self _finishInteraction];
         } else
             [self _cancelInteraction];
@@ -3122,7 +3162,7 @@
 
 - (void)_doubleTapRecognizedForDoubleClick:(UITapGestureRecognizer *)gestureRecognizer
 {
-    _page->handleDoubleTapForDoubleClickAtPoint(WebCore::IntPoint(gestureRecognizer.location), WebKit::webEventModifierFlags(gestureRecognizer.modifierFlags), _layerTreeTransactionIdAtLastInteractionStart);
+    _page->handleDoubleTapForDoubleClickAtPoint(WebCore::IntPoint([self _locationForGesture:gestureRecognizer]), WebKit::webEventModifierFlags(gestureRecognizer.modifierFlags), _layerTreeTransactionIdAtLastInteractionStart);
 }
 
 - (void)_twoFingerSingleTapGestureRecognized:(UITapGestureRecognizer *)gestureRecognizer
@@ -3129,7 +3169,7 @@
 {
     _isTapHighlightIDValid = YES;
     _isExpectingFastSingleTapCommit = YES;
-    _page->handleTwoFingerTapAtPoint(WebCore::roundedIntPoint(gestureRecognizer.centroid), WebKit::webEventModifierFlags(gestureRecognizer.modifierFlags | UIKeyModifierCommand), [self nextTapIdentifier]);
+    _page->handleTwoFingerTapAtPoint(WebCore::roundedIntPoint([self _locationForGesture:gestureRecognizer]), WebKit::webEventModifierFlags(gestureRecognizer.modifierFlags | UIKeyModifierCommand), [self nextTapIdentifier]);
 }
 
 - (void)_longPressRecognized:(UILongPressGestureRecognizer *)gestureRecognizer
@@ -3137,9 +3177,18 @@
     ASSERT(gestureRecognizer == _longPressGestureRecognizer);
     [self _resetIsDoubleTapPending];
     [self _cancelTouchEventGestureRecognizer];
+
+#if HAVE(UIKIT_WITH_MOUSE_SUPPORT)
+    if (WKHoverPlatterDomain.rootSettings.platterEnabledForLongPress) {
+        [_hoverPlatter didLongPressAtPoint:gestureRecognizer.startPoint];
+        _lastInteractionLocation = gestureRecognizer.startPoint;
+        return;
+    }
+#endif
+
     _page->didRecognizeLongPress();
 
-    _lastInteractionLocation = gestureRecognizer.startPoint;
+    _lastInteractionLocation = [self _startPointForGesture:gestureRecognizer];
 
     if ([gestureRecognizer state] == UIGestureRecognizerStateBegan) {
         SEL action = "" _actionForLongPress];
@@ -3163,7 +3212,6 @@
     _potentialTapInProgress = NO;
 }
 
-
 - (void)_singleTapIdentified:(UITapGestureRecognizer *)gestureRecognizer
 {
     ASSERT(gestureRecognizer == _singleTapGestureRecognizer);
@@ -3176,7 +3224,7 @@
     if (shouldRequestMagnificationInformation)
         RELEASE_LOG(ViewGestures, "Single tap identified. Request details on potential zoom. (%p, pageProxyID=%llu)", self, _page->identifier().toUInt64());
 
-    _page->potentialTapAtPosition(gestureRecognizer.location, shouldRequestMagnificationInformation, [self nextTapIdentifier]);
+    _page->potentialTapAtPosition([self _locationForGesture:gestureRecognizer], shouldRequestMagnificationInformation, [self nextTapIdentifier]);
     _potentialTapInProgress = YES;
     _isTapHighlightIDValid = YES;
     _isExpectingFastSingleTapCommit = !_doubleTapGestureRecognizer.get().enabled;
@@ -3250,7 +3298,7 @@
 
     ASSERT(_potentialTapInProgress);
 
-    _lastInteractionLocation = gestureRecognizer.location;
+    _lastInteractionLocation = [self _locationForGesture:gestureRecognizer];
 
     [self _endPotentialTapAndEnableDoubleTapGesturesIfNecessary];
 
@@ -3280,9 +3328,10 @@
     RELEASE_LOG(ViewGestures, "Identified a double tap (%p, pageProxyID=%llu)", self, _page->identifier().toUInt64());
 
     [self _resetIsDoubleTapPending];
-    _lastInteractionLocation = gestureRecognizer.location;
 
-    _smartMagnificationController->handleSmartMagnificationGesture(gestureRecognizer.location);
+    auto location = [self _locationForGesture:gestureRecognizer];
+    _lastInteractionLocation = location;
+    _smartMagnificationController->handleSmartMagnificationGesture(location);
 }
 
 - (void)_resetIsDoubleTapPending
@@ -3292,7 +3341,7 @@
 
 - (void)_nonBlockingDoubleTapRecognized:(UITapGestureRecognizer *)gestureRecognizer
 {
-    _lastInteractionLocation = gestureRecognizer.location;
+    _lastInteractionLocation = [self _locationForGesture:gestureRecognizer];
     _isDoubleTapPending = YES;
 }
 
@@ -3299,9 +3348,10 @@
 - (void)_twoFingerDoubleTapRecognized:(UITapGestureRecognizer *)gestureRecognizer
 {
     [self _resetIsDoubleTapPending];
-    _lastInteractionLocation = gestureRecognizer.location;
 
-    _smartMagnificationController->handleResetMagnificationGesture(gestureRecognizer.location);
+    auto location = [self _locationForGesture:gestureRecognizer];
+    _lastInteractionLocation = location;
+    _smartMagnificationController->handleResetMagnificationGesture(location);
 }
 
 - (void)_attemptSyntheticClickAtLocation:(CGPoint)location modifierFlags:(UIKeyModifierFlags)modifierFlags
@@ -7853,6 +7903,10 @@
 
 - (BOOL)_shouldUseContextMenus
 {
+#if HAVE(UIKIT_WITH_MOUSE_SUPPORT)
+    if (WKHoverPlatterDomain.rootSettings.platterEnabledForLongPress)
+        return NO;
+#endif
 #if HAVE(LINK_PREVIEW) && USE(UICONTEXTMENU)
     return linkedOnOrAfter(SDKVersion::FirstThatHasUIContextMenuInteraction);
 #endif
@@ -8224,6 +8278,11 @@
 
 - (void)setUpDragAndDropInteractions
 {
+#if HAVE(UIKIT_WITH_MOUSE_SUPPORT)
+    if (WKHoverPlatterDomain.rootSettings.platterEnabledForLongPress)
+        return;
+#endif
+
     _dragInteraction = adoptNS([[UIDragInteraction alloc] initWithDelegate:self]);
     _dropInteraction = adoptNS([[UIDropInteraction alloc] initWithDelegate:self]);
     [_dragInteraction _setLiftDelay:self.dragLiftDelay];
@@ -9673,9 +9732,13 @@
     if (event->type() == WebKit::WebEvent::MouseUp && self.hasHiddenContentEditable && self._hasFocusedElement && !self.window.keyWindow)
         [self.window makeKeyWindow];
 
+    if (WKHoverPlatterDomain.rootSettings.enabled) {
+        [_hoverPlatter didReceiveMouseEvent:*event];
+        _page->handleMouseEvent([_hoverPlatter adjustedEventForEvent:*event]);
+        return;
+    }
+
     _page->handleMouseEvent(*event);
-    if (WKHoverPlatterDomain.rootSettings.platterEnabledForMouse)
-        [_hoverPlatter setHoverPoint:event->position()];
 }
 
 - (void)_configureMouseGestureRecognizer
@@ -9698,6 +9761,13 @@
     [self doAfterPositionInformationUpdate:completionHandler forRequest:request];
 }
 
+- (void)interactableRegionsForHoverPlatter:(WKHoverPlatter *)platter inRect:(WebCore::FloatRect)rect completionHandler:(void (^)(Vector<WebCore::FloatRect>))completionHandler
+{
+    _page->interactableRegionsInRootViewCoordinates(rect, [completionHandler = makeBlockPtr(completionHandler)] (Vector<WebCore::FloatRect> rects) {
+        completionHandler(rects);
+    });
+}
+
 #endif
 
 #if ENABLE(MEDIA_CONTROLS_CONTEXT_MENUS) && USE(UICONTEXTMENU)

Modified: trunk/Source/WebKit/UIProcess/ios/WKHoverPlatter.h (289462 => 289463)


--- trunk/Source/WebKit/UIProcess/ios/WKHoverPlatter.h	2022-02-09 09:15:58 UTC (rev 289462)
+++ trunk/Source/WebKit/UIProcess/ios/WKHoverPlatter.h	2022-02-09 09:30:46 UTC (rev 289463)
@@ -25,6 +25,8 @@
 
 #if HAVE(UIKIT_WITH_MOUSE_SUPPORT)
 
+#import "NativeWebMouseEvent.h"
+
 @class WKHoverPlatter;
 
 @protocol WKHoverPlatterDelegate
@@ -32,6 +34,8 @@
 @required
 - (void)positionInformationForHoverPlatter:(WKHoverPlatter *)hoverPlatter withRequest:(WebKit::InteractionInformationRequest&)request completionHandler:(void (^)(WebKit::InteractionInformationAtPosition))completionHandler;
 
+- (void)interactableRegionsForHoverPlatter:(WKHoverPlatter *)hoverPlatter inRect:(WebCore::FloatRect)rect completionHandler:(void (^)(Vector<WebCore::FloatRect>))completionHandler;
+
 @end
 
 @interface WKHoverPlatter : NSObject
@@ -38,6 +42,12 @@
 
 - (instancetype)initWithView:(UIView *)view delegate:(id <WKHoverPlatterDelegate>)delegate;
 
+- (void)didReceiveMouseEvent:(const WebKit::NativeWebMouseEvent&)event;
+- (void)didLongPressAtPoint:(WebCore::FloatPoint)point;
+
+- (WebCore::FloatPoint)adjustedPointForPoint:(WebCore::FloatPoint)point;
+- (WebKit::NativeWebMouseEvent)adjustedEventForEvent:(const WebKit::NativeWebMouseEvent&)event;
+
 - (void)dismissPlatterWithAnimation:(BOOL)withAnimation;
 
 - (void)invalidate;

Modified: trunk/Source/WebKit/UIProcess/ios/WKHoverPlatter.mm (289462 => 289463)


--- trunk/Source/WebKit/UIProcess/ios/WKHoverPlatter.mm	2022-02-09 09:15:58 UTC (rev 289462)
+++ trunk/Source/WebKit/UIProcess/ios/WKHoverPlatter.mm	2022-02-09 09:30:46 UTC (rev 289463)
@@ -63,37 +63,25 @@
     [layer addAnimation:animation.get() forKey:key];
 };
 
-#if USE(APPLE_INTERNAL_SDK)
-#import <WebKitAdditions/WKHoverPlatterAdditions.mm>
-#else
-static CGFloat setAdditionalPlatterLayerProperties(CALayer *, CALayer *) { return 0; }
-static void addAdditionalIncomingAnimations(CALayer *, CGFloat) { }
-static void addAdditionalDismissalAnimations(CALayer *) { }
-#endif
-
 @implementation WKHoverPlatter {
     __weak UIView *_view;
     __weak id <WKHoverPlatterDelegate> _delegate;
     WebCore::FloatPoint _hoverPoint;
 
-    BOOL _hasOutstandingPositionInformationRequest;
-    BOOL _hasDeferredPositionInformationRequest;
-
     BOOL _isSittingDown;
 
-    WebCore::FloatRect _lastHoverBounds;
+    RetainPtr<CALayer> _platterLayer;
+    RetainPtr<CAPortalLayer> _snapshotLayer;
 
-    RetainPtr<CAShapeLayer> _lastMaskLayer;
-    RetainPtr<CALayer> _lastShadowLayer;
-    RetainPtr<CALayer> _lastPlatterLayer;
-    RetainPtr<CALayer> _lastBackgroundLayer;
-    RetainPtr<CAPortalLayer> _lastSnapshotLayer;
+    RetainPtr<CALayer> _debugIndicatorLayer;
+    RetainPtr<CATextLayer> _linkCountLayer;
+    RetainPtr<CAShapeLayer> _linkHighlightLayer;
 }
 
 - (instancetype)initWithView:(UIView *)view delegate:(id <WKHoverPlatterDelegate>)delegate
 {
     auto parameters = WKHoverPlatterDomain.rootSettings;
-    if (!parameters.platterEnabledForMouse && !parameters.platterEnabledForHover) {
+    if (!parameters.platterEnabledForMouse && !parameters.platterEnabledForLongPress) {
         [self release];
         return nil;
     }
@@ -120,176 +108,140 @@
     return _hoverPoint;
 }
 
-- (void)setHoverPoint:(WebCore::FloatPoint)point
+- (void)didReceiveMouseEvent:(const WebKit::NativeWebMouseEvent&)event
 {
-    _hoverPoint = point;
+    auto point = event.position();
 
-    if (_hasOutstandingPositionInformationRequest) {
-        _hasDeferredPositionInformationRequest = YES;
+    if (WKHoverPlatterDomain.rootSettings.platterEnabledForMouse) {
+        _hoverPoint = point;
+        [self update];
         return;
     }
 
-    [self requestPositionInformationForCurrentHoverPoint];
+    auto boundingRect = self.platterBoundingRect;
+    if (!boundingRect.contains(point) && point != WebCore::FloatPoint { -1, -1 })
+        [self dismissPlatterWithAnimation:YES];
 }
 
-- (void)requestPositionInformationForCurrentHoverPoint
+- (void)didLongPressAtPoint:(WebCore::FloatPoint)point
 {
-    _hasDeferredPositionInformationRequest = NO;
-    _hasOutstandingPositionInformationRequest = YES;
-    WebKit::InteractionInformationRequest positionInformationRequest { WebCore::roundedIntPoint(_hoverPoint) };
-    // FIXME: This TextIndicator doesn't need a snapshot (and avoiding it would be a sizable performance win).
-    positionInformationRequest.includeLinkIndicator = YES;
-    [_delegate positionInformationForHoverPlatter:self withRequest:positionInformationRequest completionHandler:[weakSelf = WeakObjCPtr<WKHoverPlatter>(self)] (WebKit::InteractionInformationAtPosition information) {
-        [weakSelf didReceivePositionInformation:information];
-    }];
+    if (!WKHoverPlatterDomain.rootSettings.platterEnabledForLongPress)
+        return;
+
+    _hoverPoint = point;
+    [self update];
 }
 
-- (void)didReceivePositionInformation:(const WebKit::InteractionInformationAtPosition&)information
+- (WebCore::FloatRect)platterBoundingRect
 {
-    _hasOutstandingPositionInformationRequest = NO;
-    if (_hasDeferredPositionInformationRequest)
-        [self requestPositionInformationForCurrentHoverPoint];
+    auto radius = WKHoverPlatterDomain.rootSettings.platterRadius;
+    return { _hoverPoint - WebCore::FloatSize(radius, radius), WebCore::FloatSize(radius * 2, radius * 2) };
+}
 
-    auto preInflationBoundingRect = information.linkIndicator.textBoundingRectInRootViewCoordinates;
-    if (preInflationBoundingRect.isEmpty())
-        preInflationBoundingRect = information.bounds;
+- (WebCore::FloatRect)linkSearchRect
+{
+    auto radius = WKHoverPlatterDomain.rootSettings.linkSearchRadius;
+    return { _hoverPoint - WebCore::FloatSize(radius, radius), WebCore::FloatSize(radius * 2, radius * 2) };
+}
 
-    if (!information.isLink || preInflationBoundingRect.isEmpty()) {
-        _lastHoverBounds = { };
-        [self dismissPlatterWithAnimation:YES];
-        return;
-    }
-
-    if (_lastHoverBounds == preInflationBoundingRect && !_isSittingDown)
-        return;
-    _lastHoverBounds = preInflationBoundingRect;
-
+- (void)update
+{
     auto parameters = WKHoverPlatterDomain.rootSettings;
-    auto animateBetweenPlatters = parameters.animateBetweenPlatters;
-    if (!animateBetweenPlatters)
-        [self dismissPlatterWithAnimation:YES];
 
-    _isSittingDown = false;
+    if (parameters.showDebugOverlay)
+        [self updateDebugIndicator];
 
-    WebCore::FloatRect boundingRect;
-    Vector<WebCore::FloatRect> inflatedIndicatedRects;
-    auto indicatedRects = information.linkIndicator.textRectsInBoundingRectCoordinates;
-    auto platterPadding = parameters.platterPadding;
-    if (indicatedRects.isEmpty()) {
-        boundingRect = preInflationBoundingRect;
-        boundingRect.inflate(platterPadding);
-        inflatedIndicatedRects.append(preInflationBoundingRect);
-    } else {
-        for (auto rect : indicatedRects) {
-            rect.inflate(platterPadding);
-            inflatedIndicatedRects.append(rect);
-            boundingRect.unite(rect);
-        }
-        boundingRect.moveBy(preInflationBoundingRect.location());
-    }
-
-    RetainPtr<CGPathRef> inflatedPath = WebCore::PathUtilities::pathWithShrinkWrappedRects(inflatedIndicatedRects, parameters.platterCornerRadius).platformPath();
-    auto platterInflationSize = parameters.platterInflationSize;
-    CGFloat platterScale = CGFloatMin((boundingRect.width() + platterInflationSize) / boundingRect.width(), (boundingRect.height() + platterInflationSize) / boundingRect.height());
-
-    // FIXME: Consider using UIKit's in-process retargetable animations, because reading animation state from the presentation layer is racy.
-    bool hadOldLayers = !!_lastShadowLayer;
-    CGRect oldShadowBounds = [_lastShadowLayer presentationLayer].bounds;
-    CGPoint oldShadowPosition = [_lastShadowLayer presentationLayer].position;
-    CGFloat oldShadowOpacity = [_lastShadowLayer presentationLayer].shadowOpacity;
-    CGFloat oldShadowRadius = [_lastShadowLayer presentationLayer].shadowRadius;
-    CATransform3D oldShadowSublayerTransform = _lastShadowLayer ? [_lastShadowLayer presentationLayer].sublayerTransform : CATransform3DIdentity;
-    RetainPtr<CGPathRef> oldShadowPath = [_lastShadowLayer presentationLayer].shadowPath;
-    RetainPtr<CALayer> shadow = _lastShadowLayer ?: adoptNS([[CALayer alloc] init]);
-    auto shadowFrame = CGRectOffset(boundingRect, platterPadding, platterPadding);
-    [shadow setFrame:shadowFrame];
-    [shadow setShadowColor:UIColor.blackColor.CGColor];
-    [shadow setShadowRadius:parameters.platterShadowRadius];
-    [shadow setShadowOffset:CGSizeZero];
-    [shadow setShadowOpacity:parameters.platterShadowOpacity];
-    [shadow setSublayerTransform:CATransform3DMakeScale(platterScale, platterScale, 1)];
-    [shadow setShadowPath:inflatedPath.get()];
-    [shadow web_disableAllActions];
-    [[[_view superview] layer] addSublayer:shadow.get()];
-
-    CGRect oldPlatterBounds = [_lastPlatterLayer presentationLayer].bounds;
-    CGPoint oldPlatterPosition = [_lastPlatterLayer presentationLayer].position;
-    RetainPtr<CALayer> platter = _lastPlatterLayer ?: adoptNS([[CALayer alloc] init]);
+    auto boundingRect = self.platterBoundingRect;
+    RetainPtr<CALayer> platter = _platterLayer ?: adoptNS([[CALayer alloc] init]);
     [platter setBounds:CGRectMake(0, 0, boundingRect.width(), boundingRect.height())];
-    [platter setPosition:CGPointMake(shadowFrame.size.width / 2 - platterPadding, shadowFrame.size.height / 2 - platterPadding)];
-    auto oldPlatterAdditionalAnimationValue = setAdditionalPlatterLayerProperties(platter.get(), [_lastPlatterLayer presentationLayer]);
+    [platter setPosition:boundingRect.center()];
+    [platter setShadowColor:UIColor.blackColor.CGColor];
+    [platter setShadowOffset:CGSizeMake(0, 10)];
+    [platter setShadowOpacity:0.25];
+    [platter setShadowRadius:10];
     [platter web_disableAllActions];
-    [shadow addSublayer:platter.get()];
+    [[[_view superview] layer] addSublayer:platter.get()];
 
-    CGRect oldMaskBounds = [_lastMaskLayer presentationLayer].bounds;
-    CGPoint oldMaskPosition = [_lastMaskLayer presentationLayer].position;
-    RetainPtr<CGPathRef> oldMaskPath = [_lastMaskLayer presentationLayer].path;
-    RetainPtr<CAShapeLayer> mask = _lastMaskLayer ?: adoptNS([[CAShapeLayer alloc] init]);
-    [mask setFillColor:[UIColor blackColor].CGColor];
-    [mask setBounds:CGRectMake(0, 0, boundingRect.width(), boundingRect.height())];
-    [mask setPosition:CGPointMake(boundingRect.width() / 2 + platterPadding, boundingRect.height() / 2 + platterPadding)];
-    [mask setPath:inflatedPath.get()];
-    [mask web_disableAllActions];
-
-    CGRect oldBackgroundBounds = [_lastBackgroundLayer presentationLayer].bounds;
-    CGPoint oldBackgroundPosition = [_lastBackgroundLayer presentationLayer].position;
-    RetainPtr<CGColorRef> oldBackgroundColor = [_lastBackgroundLayer presentationLayer].backgroundColor;
-    RetainPtr<CALayer> background = "" ?: adoptNS([[CALayer alloc] init]);
-    [background setFrame:[platter bounds]];
-    [background setBackgroundColor:cachedCGColor(information.linkIndicator.estimatedBackgroundColor).get()];
-    [background setMask:mask.get()];
-    [background web_disableAllActions];
-    [platter addSublayer:background.get()];
-
-    CGRect oldSnapshotBounds = [_lastSnapshotLayer presentationLayer].bounds;
-    CGPoint oldSnapshotPosition = [_lastSnapshotLayer presentationLayer].position;
-    CATransform3D oldSnapshotSublayerTransform = _lastSnapshotLayer ? [_lastSnapshotLayer presentationLayer].sublayerTransform : CATransform3DIdentity;
-    RetainPtr<CAPortalLayer> snapshot = _lastSnapshotLayer ?: adoptNS([[CAPortalLayer alloc] init]);
+    RetainPtr<CAPortalLayer> snapshot = _snapshotLayer ?: adoptNS([[CAPortalLayer alloc] init]);
     [snapshot setSourceLayer:[_view layer]];
     [snapshot setMatchesPosition:YES];
     [snapshot setMatchesTransform:YES];
+    [snapshot setMasksToBounds:YES];
+    [snapshot setCornerRadius:parameters.platterRadius];
+    [snapshot setBackgroundColor:UIColor.blackColor.CGColor];
+    [snapshot setBorderColor:[UIColor colorWithWhite:0 alpha:0.2].CGColor];
+    [snapshot setBorderWidth:1];
     [snapshot setAnchorPoint:CGPointMake(0.5, 0.5)];
-    [snapshot setSublayerTransform:CATransform3DMakeScale(platterScale, platterScale, 1)];
+    [snapshot setSublayerTransform:CATransform3DMakeScale(parameters.platterScale, parameters.platterScale, 1)];
     [snapshot setMasksToBounds:YES];
     [snapshot setFrame:CGRectMake(0, 0, boundingRect.width(), boundingRect.height())];
     [snapshot web_disableAllActions];
-    [background addSublayer:snapshot.get()];
+    [platter addSublayer:snapshot.get()];
 
-    BOOL needsAnimateIn = !_lastPlatterLayer || _isSittingDown;
-    if (needsAnimateIn) {
-        addAnimation(shadow.get(), @"shadowOpacity", @(oldShadowOpacity), @([shadow shadowOpacity]));
-        addAnimation(shadow.get(), @"shadowRadius", @(oldShadowRadius), @([shadow shadowRadius]));
-        addAnimation(shadow.get(), @"sublayerTransform", [NSValue valueWithCATransform3D:oldShadowSublayerTransform], [NSValue valueWithCATransform3D:[shadow sublayerTransform]]);
+    if (_isSittingDown) {
+        if (parameters.animateScale) {
+            auto inverseScale = 1.f / parameters.platterScale;
+            addAnimation(platter.get(), @"transform", [NSValue valueWithCATransform3D:CATransform3DMakeScale(inverseScale, inverseScale, 1)], [NSValue valueWithCATransform3D:CATransform3DIdentity]);
+            addAnimation(snapshot.get(), @"sublayerTransform", [NSValue valueWithCATransform3D:CATransform3DIdentity], [NSValue valueWithCATransform3D:[snapshot sublayerTransform]]);
+            addAnimation(platter.get(), @"shadowOpacity", @0, @([platter shadowOpacity]));
+            addAnimation(snapshot.get(), @"borderColor", (id)UIColor.clearColor.CGColor, (id)[snapshot borderColor]);
+        } else
+            addAnimation(platter.get(), @"opacity", @0, @1);
+    }
 
-        addAnimation(snapshot.get(), @"sublayerTransform", [NSValue valueWithCATransform3D:oldSnapshotSublayerTransform], [NSValue valueWithCATransform3D:[snapshot sublayerTransform]]);
+    _platterLayer = platter;
+    _snapshotLayer = snapshot;
 
-        addAdditionalIncomingAnimations(platter.get(), oldPlatterAdditionalAnimationValue);
-    }
+    _isSittingDown = false;
+}
 
-    if (animateBetweenPlatters && hadOldLayers) {
-        addAnimation(mask.get(), @"bounds", [NSValue valueWithCGRect:oldMaskBounds], [NSValue valueWithCGRect:[mask bounds]]);
-        addAnimation(mask.get(), @"position", [NSValue valueWithCGPoint:oldMaskPosition], [NSValue valueWithCGPoint:[mask position]]);
-        addAnimation(mask.get(), @"path", (id)oldMaskPath.get(), (id)[mask path]);
+- (void)updateDebugIndicator
+{
+    auto searchBoundingRect = self.linkSearchRect;
 
-        addAnimation(shadow.get(), @"bounds", [NSValue valueWithCGRect:oldShadowBounds], [NSValue valueWithCGRect:[shadow bounds]]);
-        addAnimation(shadow.get(), @"position", [NSValue valueWithCGPoint:oldShadowPosition], [NSValue valueWithCGPoint:[shadow position]]);
-        addAnimation(shadow.get(), @"shadowPath", (id)oldShadowPath.get(), (id)[shadow shadowPath]);
+    RetainPtr<CALayer> debugIndicator = _debugIndicatorLayer ?: adoptNS([[CALayer alloc] init]);
+    [debugIndicator setBounds:CGRectMake(0, 0, searchBoundingRect.width(), searchBoundingRect.height())];
+    [debugIndicator setPosition:searchBoundingRect.center()];
+    [debugIndicator setBorderColor:[UIColor colorWithRed:1 green:0 blue:0 alpha:1].CGColor];
+    [debugIndicator setBorderWidth:1];
+    [debugIndicator web_disableAllActions];
+    [[_view layer] addSublayer:debugIndicator.get()];
 
-        addAnimation(platter.get(), @"bounds", [NSValue valueWithCGRect:oldPlatterBounds], [NSValue valueWithCGRect:[platter bounds]]);
-        addAnimation(platter.get(), @"position", [NSValue valueWithCGPoint:oldPlatterPosition], [NSValue valueWithCGPoint:[platter position]]);
+    RetainPtr<CATextLayer> linkCountLayer = _linkCountLayer ?: adoptNS([[CATextLayer alloc] init]);
+    [linkCountLayer setBounds:CGRectMake(0, 0, 50, 16)];
+    [linkCountLayer setPosition:CGPointMake(-10, (searchBoundingRect.height() / 2) - 8)];
+    [linkCountLayer setForegroundColor:UIColor.blackColor.CGColor];
+    [linkCountLayer setShadowColor:UIColor.whiteColor.CGColor];
+    [linkCountLayer setShadowOffset:CGSizeMake(0, 0)];
+    [linkCountLayer setShadowOpacity:1];
+    [linkCountLayer setShadowRadius:2];
+    [linkCountLayer setFontSize:16];
+    [linkCountLayer setContentsScale:4];
+    [linkCountLayer setAlignmentMode:kCAAlignmentCenter];
+    [linkCountLayer web_disableAllActions];
+    [debugIndicator addSublayer:linkCountLayer.get()];
 
-        addAnimation(background.get(), @"bounds", [NSValue valueWithCGRect:oldBackgroundBounds], [NSValue valueWithCGRect:[background bounds]]);
-        addAnimation(background.get(), @"position", [NSValue valueWithCGPoint:oldBackgroundPosition], [NSValue valueWithCGPoint:[background position]]);
+    RetainPtr<CAShapeLayer> linkHighlightLayer = _linkHighlightLayer ?: adoptNS([[CAShapeLayer alloc] init]);
+    [linkHighlightLayer setFillColor:UIColor.clearColor.CGColor];
+    [linkHighlightLayer setStrokeColor:[UIColor.blueColor colorWithAlphaComponent:0.3].CGColor];
+    [linkHighlightLayer web_disableAllActions];
+    [[_view layer] addSublayer:linkHighlightLayer.get()];
 
-        addAnimation(snapshot.get(), @"bounds", [NSValue valueWithCGRect:oldSnapshotBounds], [NSValue valueWithCGRect:[snapshot bounds]]);
-        addAnimation(snapshot.get(), @"position", [NSValue valueWithCGPoint:oldSnapshotPosition], [NSValue valueWithCGPoint:[snapshot position]]);
-    }
+    [_delegate interactableRegionsForHoverPlatter:self inRect:searchBoundingRect completionHandler:makeBlockPtr([self, strongSelf = retainPtr(self)] (Vector<WebCore::FloatRect> rects) {
+        if (!_linkCountLayer && !_linkHighlightLayer)
+            return;
 
-    _lastMaskLayer = mask;
-    _lastShadowLayer = shadow;
-    _lastPlatterLayer = platter;
-    _lastBackgroundLayer = background;
-    _lastSnapshotLayer = snapshot;
+        [_linkCountLayer setString:[NSString stringWithFormat:@"%zu", rects.size()]];
+
+        WebCore::Path path;
+        for (const auto& rect : rects)
+            path.addRect(rect);
+        [_linkHighlightLayer setPath:path.platformPath()];
+    }).get()];
+
+    _debugIndicatorLayer = debugIndicator;
+    _linkCountLayer = linkCountLayer;
+    _linkHighlightLayer = linkHighlightLayer;
 }
 
 - (void)dismissPlatterWithAnimation:(BOOL)withAnimation
@@ -299,48 +251,64 @@
     _isSittingDown = true;
 
     if (!withAnimation) {
-        [_lastShadowLayer removeFromSuperlayer];
+        [_debugIndicatorLayer removeFromSuperlayer];
+        [_platterLayer removeFromSuperlayer];
+        [_linkCountLayer removeFromSuperlayer];
+        [_linkHighlightLayer removeFromSuperlayer];
         [self clearLayers];
         return;
     }
 
     [CATransaction begin];
-    [CATransaction setCompletionBlock:[protectedSelf = retainPtr(self), shadowLayer = _lastShadowLayer] {
-        [protectedSelf didFinishAnimationForShadow:shadowLayer.get()];
+    [CATransaction setCompletionBlock:[protectedSelf = retainPtr(self), platterLayer = _platterLayer] {
+        [protectedSelf didFinishDismissalAnimation:platterLayer.get()];
     }];
 
     auto parameters = WKHoverPlatterDomain.rootSettings;
-    addAnimation(_lastShadowLayer.get(), @"shadowOpacity", @([_lastShadowLayer shadowOpacity]), @0);
-    addAnimation(_lastShadowLayer.get(), @"shadowRadius", @([_lastShadowLayer shadowRadius]), @0);
-    addAnimation(_lastShadowLayer.get(), @"sublayerTransform", [NSValue valueWithCATransform3D:[_lastShadowLayer sublayerTransform]], [NSValue valueWithCATransform3D:CATransform3DIdentity]);
-    addAnimation(_lastSnapshotLayer.get(), @"sublayerTransform", [NSValue valueWithCATransform3D:[_lastSnapshotLayer sublayerTransform]], [NSValue valueWithCATransform3D:CATransform3DIdentity]);
-    addAdditionalDismissalAnimations(_lastPlatterLayer.get());
+    if (parameters.animateScale) {
+        auto inverseScale = 1.f / parameters.platterScale;
+        addAnimation(_platterLayer.get(), @"transform", [NSValue valueWithCATransform3D:CATransform3DIdentity], [NSValue valueWithCATransform3D:CATransform3DMakeScale(inverseScale, inverseScale, 1)]);
+        addAnimation(_snapshotLayer.get(), @"sublayerTransform", [NSValue valueWithCATransform3D:[_snapshotLayer sublayerTransform]], [NSValue valueWithCATransform3D:CATransform3DIdentity]);
+        addAnimation(_platterLayer.get(), @"shadowOpacity", @([_platterLayer shadowOpacity]), @0);
+        addAnimation(_snapshotLayer.get(), @"borderColor", (id)[_snapshotLayer borderColor], (id)UIColor.clearColor.CGColor);
+    } else
+        addAnimation(_platterLayer.get(), @"opacity", @1, @0);
 
     [CATransaction commit];
+}
 
-    if (!parameters.animateBetweenPlatters)
-        [self clearLayers];
+- (void)didFinishDismissalAnimation:(CALayer *)platterLayer
+{
+    [platterLayer removeFromSuperlayer];
 }
 
-- (void)didFinishAnimationForShadow:(CALayer *)shadowLayer
+- (void)clearLayers
 {
-    auto parameters = WKHoverPlatterDomain.rootSettings;
-    if (!parameters.animateBetweenPlatters)
-        [shadowLayer removeFromSuperlayer];
+    _debugIndicatorLayer = nil;
+    _platterLayer = nil;
+    _snapshotLayer = nil;
+    _linkCountLayer = nil;
+    _linkHighlightLayer = nil;
+}
 
-    if (_isSittingDown && parameters.animateBetweenPlatters && shadowLayer == _lastShadowLayer) {
-        [shadowLayer removeFromSuperlayer];
-        [self clearLayers];
-    }
+- (WebCore::FloatPoint)adjustedPointForPoint:(WebCore::FloatPoint)point
+{
+    if (_isSittingDown)
+        return point;
+
+    auto delta = point - _hoverPoint;
+    delta.scale(1.f / WKHoverPlatterDomain.rootSettings.platterScale);
+    return _hoverPoint + delta;
 }
 
-- (void)clearLayers
+- (WebKit::NativeWebMouseEvent)adjustedEventForEvent:(const WebKit::NativeWebMouseEvent&)event
 {
-    _lastMaskLayer = nil;
-    _lastShadowLayer = nil;
-    _lastPlatterLayer = nil;
-    _lastBackgroundLayer = nil;
-    _lastSnapshotLayer = nil;
+    if (_isSittingDown)
+        return event;
+
+    auto inverseScale = 1.f / WKHoverPlatterDomain.rootSettings.platterScale;
+    auto adjustedPoint = roundedIntPoint([self adjustedPointForPoint:event.position()]);
+    return WebKit::NativeWebMouseEvent(event, adjustedPoint, adjustedPoint, event.deltaX() * inverseScale, event.deltaY() * inverseScale, event.deltaZ() * inverseScale);
 }
 
 @end

Modified: trunk/Source/WebKit/UIProcess/ios/WKHoverPlatterParameters.h (289462 => 289463)


--- trunk/Source/WebKit/UIProcess/ios/WKHoverPlatterParameters.h	2022-02-09 09:15:58 UTC (rev 289462)
+++ trunk/Source/WebKit/UIProcess/ios/WKHoverPlatterParameters.h	2022-02-09 09:30:46 UTC (rev 289463)
@@ -30,20 +30,23 @@
 @interface WKHoverPlatterParameters : PTSettings
 
 @property (nonatomic) BOOL platterEnabledForMouse;
-@property (nonatomic) BOOL platterEnabledForHover;
+@property (nonatomic) BOOL platterEnabledForLongPress;
 
-@property (nonatomic) CGFloat platterCornerRadius;
-@property (nonatomic) CGFloat platterPadding;
-@property (nonatomic) CGFloat platterShadowOpacity;
-@property (nonatomic) CGFloat platterShadowRadius;
-@property (nonatomic) unsigned platterInflationSize;
+@property (nonatomic, readonly) BOOL enabled;
 
-@property (nonatomic) BOOL animateBetweenPlatters;
+@property (nonatomic) BOOL showDebugOverlay;
+
+@property (nonatomic) CGFloat platterRadius;
+@property (nonatomic) CGFloat platterScale;
+
+@property (nonatomic) CGFloat linkSearchRadius;
+
 @property (nonatomic) CGFloat springMass;
 @property (nonatomic) CGFloat springStiffness;
 @property (nonatomic) CGFloat springDamping;
 @property (nonatomic) NSTimeInterval duration;
-@property (nonatomic) CGFloat useSpring;
+@property (nonatomic) BOOL useSpring;
+@property (nonatomic) BOOL animateScale;
 
 #if USE(APPLE_INTERNAL_SDK)
 #import <WebKitAdditions/WKHoverPlatterParametersAdditions.h>

Modified: trunk/Source/WebKit/UIProcess/ios/WKHoverPlatterParameters.mm (289462 => 289463)


--- trunk/Source/WebKit/UIProcess/ios/WKHoverPlatterParameters.mm	2022-02-09 09:15:58 UTC (rev 289462)
+++ trunk/Source/WebKit/UIProcess/ios/WKHoverPlatterParameters.mm	2022-02-09 09:30:46 UTC (rev 289463)
@@ -49,13 +49,6 @@
 
 @end
 
-#if USE(APPLE_INTERNAL_SDK)
-#import <WebKitAdditions/WKHoverPlatterParametersAdditions.mm>
-#else
-static void addAdditionalPlatterLayoutParameters(NSMutableArray *) { }
-static void setDefaultValuesForAdditionalPlatterLayoutParameters(WKHoverPlatterParameters *) { }
-#endif
-
 @implementation WKHoverPlatterParameters
 
 - (void)setDefaultValues
@@ -63,22 +56,26 @@
     [super setDefaultValues];
 
     _platterEnabledForMouse = NO;
-    _platterEnabledForHover = NO;
+    _platterEnabledForLongPress = NO;
 
-    _platterCornerRadius = 6;
-    _platterPadding = 5;
-    _platterShadowOpacity = 0.6;
-    _platterShadowRadius = 10;
-    _platterInflationSize = 8;
+    _showDebugOverlay = NO;
 
-    _animateBetweenPlatters = YES;
+    _platterRadius = 200;
+    _platterScale = 2;
+
+    _linkSearchRadius = 40;
+
     _springMass = 2;
-    _springStiffness = 100;
-    _springDamping = 50;
+    _springStiffness = 200;
+    _springDamping = 200;
     _duration = 0.3;
     _useSpring = YES;
+    _animateScale = YES;
+}
 
-    setDefaultValuesForAdditionalPlatterLayoutParameters(self);
+- (BOOL)enabled
+{
+    return _platterEnabledForMouse || _platterEnabledForLongPress;
 }
 
 + (PTModule *)settingsControllerModule
@@ -85,11 +82,15 @@
 {
     PTSection *enablementSection = [PTModule sectionWithRows:@[
         [PTSwitchRow rowWithTitle:@"Enable Platter For Mouse" valueKeyPath:@"platterEnabledForMouse"],
-        [PTSwitchRow rowWithTitle:@"Enable Platter For Hover" valueKeyPath:@"platterEnabledForHover"],
+        [PTSwitchRow rowWithTitle:@"Enable Platter For Long Press" valueKeyPath:@"platterEnabledForLongPress"],
     ] title:@"Platter"];
 
+    PTSection *debugSection = [PTModule sectionWithRows:@[
+        [PTSwitchRow rowWithTitle:@"Show Debug Overlay" valueKeyPath:@"showDebugOverlay"],
+    ] title:@"Debug"];
+
     PTSection *animationSection = [PTModule sectionWithRows:@[
-        [PTSwitchRow rowWithTitle:@"Animate Between Platters" valueKeyPath:@"animateBetweenPlatters"],
+        [PTSwitchRow rowWithTitle:@"Animate Scale" valueKeyPath:@"animateScale"],
         [PTSwitchRow rowWithTitle:@"Use Spring" valueKeyPath:@"useSpring"],
         [[[PTSliderRow rowWithTitle:@"Duration" valueKeyPath:@"duration"] minValue:0 maxValue:1] condition:[NSPredicate predicateWithFormat:@"useSpring == FALSE"]],
         [[PTEditFloatRow rowWithTitle:@"Spring Mass" valueKeyPath:@"springMass"] condition:[NSPredicate predicateWithFormat:@"useSpring == TRUE"]],
@@ -97,22 +98,20 @@
         [[PTEditFloatRow rowWithTitle:@"Spring Damping" valueKeyPath:@"springDamping"] condition:[NSPredicate predicateWithFormat:@"useSpring == TRUE"]],
     ] title:@"Animation"];
 
-    RetainPtr<NSMutableArray> platterLayoutRows = adoptNS([@[
-        [[PTSliderRow rowWithTitle:@"Corner Radius" valueKeyPath:@"platterCornerRadius"] integerMinValue:0 maxValue:20],
-        [[PTSliderRow rowWithTitle:@"Padding" valueKeyPath:@"platterPadding"] integerMinValue:0 maxValue:20],
-        [[PTSliderRow rowWithTitle:@"Shadow Opacity" valueKeyPath:@"platterShadowOpacity"] minValue:0 maxValue:1],
-        [[PTSliderRow rowWithTitle:@"Shadow Radius" valueKeyPath:@"platterShadowRadius"] integerMinValue:0 maxValue:20],
-        [[PTSliderRow rowWithTitle:@"Inflation Size" valueKeyPath:@"platterInflationSize"] integerMinValue:0 maxValue:30]
-    ] mutableCopy]);
-    addAdditionalPlatterLayoutParameters(platterLayoutRows.get());
+    PTSection *platterSection = [PTModule sectionWithRows:@[
+        [[PTSliderRow rowWithTitle:@"Radius" valueKeyPath:@"platterRadius"] integerMinValue:0 maxValue:400],
+        [[PTSliderRow rowWithTitle:@"Scale" valueKeyPath:@"platterScale"] minValue:1 maxValue:4],
+    ] title:@"Platter"];
 
-    PTSection *platterLayoutSection = [PTModule sectionWithRows:platterLayoutRows.get() title:@"Platter Layout"];
+    PTSection *linkSearchingSection = [PTModule sectionWithRows:@[
+        [[PTSliderRow rowWithTitle:@"Radius" valueKeyPath:@"linkSearchRadius"] integerMinValue:0 maxValue:200],
+    ] title:@"Link Searching"];
 
     PTSection *restoreDefaultsSection = [PTModule sectionWithRows:@[
         [PTButtonRow rowWithTitle:@"Restore Defaults" action:[PTRestoreDefaultSettingsRowAction action]]
     ]];
 
-    return [PTModule moduleWithTitle:nil contents:@[ enablementSection, animationSection, platterLayoutSection, restoreDefaultsSection ]];
+    return [PTModule moduleWithTitle:nil contents:@[ enablementSection, debugSection, animationSection, platterSection, linkSearchingSection, restoreDefaultsSection ]];
 }
 
 @end

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (289462 => 289463)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2022-02-09 09:15:58 UTC (rev 289462)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2022-02-09 09:30:46 UTC (rev 289463)
@@ -6265,6 +6265,43 @@
     sendEditorStateUpdate();
 }
 
+void WebPage::interactableRegionsInRootViewCoordinates(FloatRect rect, CompletionHandler<void(Vector<FloatRect>)>&& completionHandler)
+{
+    Ref frame(m_page->mainFrame());
+
+    if (RefPtr frameView = frame->view())
+        frameView->updateLayoutAndStyleIfNeededRecursive();
+
+    auto result = HitTestResult { LayoutRect(rect) };
+    RefPtr document = frame->document();
+    if (!document) {
+        completionHandler({ });
+        return;
+    }
+
+    HitTestRequest request({
+        HitTestRequest::Type::ReadOnly,
+        HitTestRequest::Type::AllowVisibleChildFrameContentOnly,
+        HitTestRequest::Type::CollectMultipleElements
+    });
+    document->hitTest(request, result);
+
+    Vector<FloatRect> rects;
+
+    for (const auto& node : result.listBasedTestResult()) {
+        if (!is<Element>(node.get()))
+            continue;
+        auto& element = downcast<Element>(node.get());
+
+        if (!node->willRespondToMouseClickEvents())
+            continue;
+
+        rects.append(element.boundingBoxInRootViewCoordinates());
+    }
+
+    completionHandler(rects);
+}
+
 void WebPage::setAlwaysShowsHorizontalScroller(bool alwaysShowsHorizontalScroller)
 {
     if (alwaysShowsHorizontalScroller == m_alwaysShowsHorizontalScroller)

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (289462 => 289463)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2022-02-09 09:15:58 UTC (rev 289462)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2022-02-09 09:30:46 UTC (rev 289463)
@@ -931,6 +931,8 @@
     void didUpdateComposition();
     void didEndUserTriggeredSelectionChanges();
 
+    void interactableRegionsInRootViewCoordinates(WebCore::FloatRect, CompletionHandler<void(Vector<WebCore::FloatRect>)>&&);
+
 #if PLATFORM(COCOA)
     void platformInitializeAccessibility();
     void registerUIProcessAccessibilityTokens(const IPC::DataReference& elemenToken, const IPC::DataReference& windowToken);

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (289462 => 289463)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in	2022-02-09 09:15:58 UTC (rev 289462)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in	2022-02-09 09:30:46 UTC (rev 289463)
@@ -657,4 +657,6 @@
 #endif
 
     ScrollToRect(WebCore::FloatRect targetRect, WebCore::FloatPoint origin)
+
+    InteractableRegionsInRootViewCoordinates(WebCore::FloatRect rect) -> (Vector<WebCore::FloatRect> rects) Async
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to