[ContentChangeObserver] Always dispatch the synthetic click asynchronously
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 27 Mar 2019 19:41:22 +0000 (19:41 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 27 Mar 2019 19:41:22 +0000 (19:41 +0000)
https://bugs.webkit.org/show_bug.cgi?id=196278
<rdar://problem/49299968>

Reviewed by Simon Fraser.

This patch ensures that all completeSyntheticClick() calls happen in an asynchronous manner (unless the feature is turned off).

* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::dispatchSyntheticMouseMove):
(WebKit::WebPage::handleSyntheticClick):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@243557 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit/ChangeLog
Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm

index 3eb7157..a1f9c57 100644 (file)
@@ -1,3 +1,17 @@
+2019-03-27  Zalan Bujtas  <zalan@apple.com>
+
+        [ContentChangeObserver] Always dispatch the synthetic click asynchronously
+        https://bugs.webkit.org/show_bug.cgi?id=196278
+        <rdar://problem/49299968>
+
+        Reviewed by Simon Fraser.
+
+        This patch ensures that all completeSyntheticClick() calls happen in an asynchronous manner (unless the feature is turned off).
+
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::dispatchSyntheticMouseMove):
+        (WebKit::WebPage::handleSyntheticClick):
+
 2019-03-27  Tim Horton  <timothy_horton@apple.com>
 
         Fix some more deprecation warnings in WKDrawingView
index 0dd509d..df8ddc9 100644 (file)
@@ -561,17 +561,22 @@ static void dispatchSyntheticMouseMove(Frame& mainFrame, const WebCore::FloatPoi
     auto altKey = modifiers.contains(WebEvent::Modifier::AltKey);
     auto metaKey = modifiers.contains(WebEvent::Modifier::MetaKey);
     auto mouseEvent = PlatformMouseEvent(roundedAdjustedPoint, roundedAdjustedPoint, NoButton, PlatformEvent::MouseMoved, 0, shiftKey, ctrlKey, altKey, metaKey, WallTime::now(), WebCore::ForceAtClick, WebCore::NoTap);
+    // FIXME: Pass caps lock state.
     mainFrame.eventHandler().dispatchSyntheticMouseMove(mouseEvent);
 }
 
 void WebPage::handleSyntheticClick(Node& nodeRespondingToClick, const WebCore::FloatPoint& location, OptionSet<WebEvent::Modifier> modifiers)
 {
+    if (!nodeRespondingToClick.document().settings().contentChangeObserverEnabled()) {
+        completeSyntheticClick(nodeRespondingToClick, location, modifiers, WebCore::OneFingerTap);
+        return;
+    }
+
     auto& respondingDocument = nodeRespondingToClick.document();
-    auto& mainFrame = m_page->mainFrame();
-    // FIXME: Pass caps lock state.
     {
         LOG_WITH_STREAM(ContentObservation, stream << "handleSyntheticClick: node(" << &nodeRespondingToClick << ") " << location);
         ContentChangeObserver::MouseMovedScope observingScope(respondingDocument);
+        auto& mainFrame = m_page->mainFrame();
         dispatchSyntheticMouseMove(mainFrame, location, modifiers);
         mainFrame.document()->updateStyleIfNeeded();
     }
@@ -579,32 +584,34 @@ void WebPage::handleSyntheticClick(Node& nodeRespondingToClick, const WebCore::F
     if (m_isClosed)
         return;
 
-    if (is<HTMLFormControlElement>(nodeRespondingToClick)) {
-        LOG(ContentObservation, "handleSyntheticClick: Target node is a form control -> click.");
-        completeSyntheticClick(nodeRespondingToClick, location, modifiers, WebCore::OneFingerTap);
-        return;
-    }
     auto& contentChangeObserver = respondingDocument.contentChangeObserver();
     auto observedContentChange = contentChangeObserver.observedContentChange();
-    if (observedContentChange == WKContentVisibilityChange) {
-        // The move event caused new contents to appear. Don't send the click event, but just ensure that the mouse is on the most recent content.
-        dispatchSyntheticMouseMove(mainFrame, location, modifiers);
-        LOG(ContentObservation, "handleSyntheticClick: Observed meaningful visible change -> hover.");
-        return;
-    }
-    const Seconds observationDuration = 32_ms;
-    contentChangeObserver.startContentObservationForDuration(observationDuration);
-    if (contentChangeObserver.observedContentChange() == WKContentNoChange) {
-        ASSERT(!respondingDocument.settings().contentChangeObserverEnabled());
-        completeSyntheticClick(nodeRespondingToClick, location, modifiers, WebCore::OneFingerTap);
+
+    auto continueContentObservation = !(observedContentChange == WKContentVisibilityChange || is<HTMLFormControlElement>(nodeRespondingToClick));
+    if (continueContentObservation) {
+        // Wait for callback to completePendingSyntheticClickForContentChangeObserver() to decide whether to send the click event.
+        const Seconds observationDuration = 32_ms;
+        contentChangeObserver.startContentObservationForDuration(observationDuration);
+        LOG(ContentObservation, "handleSyntheticClick: Can't decide it yet -> wait.");
+        m_pendingSyntheticClickNode = &nodeRespondingToClick;
+        m_pendingSyntheticClickLocation = location;
+        m_pendingSyntheticClickModifiers = modifiers;
         return;
     }
 
-    LOG(ContentObservation, "handleSyntheticClick: Can't decide it yet -> wait.");
-    // Wait for callback to completePendingSyntheticClickForContentChangeObserver() to decide whether to send the click event.
-    m_pendingSyntheticClickNode = &nodeRespondingToClick;
-    m_pendingSyntheticClickLocation = location;
-    m_pendingSyntheticClickModifiers = modifiers;
+    callOnMainThread([protectedThis = makeRefPtr(this), targetNode = Ref<Node>(nodeRespondingToClick), location, modifiers, observedContentChange] {
+        if (protectedThis->m_isClosed || !protectedThis->corePage())
+            return;
+
+        if (observedContentChange == WKContentVisibilityChange) {
+            // The move event caused new contents to appear. Don't send synthetic click event, but just ensure that the mouse is on the most recent content.
+            dispatchSyntheticMouseMove(protectedThis->corePage()->mainFrame(), location, modifiers);
+            LOG(ContentObservation, "handleSyntheticClick: Observed meaningful visible change -> hover.");
+            return;
+        }
+        LOG(ContentObservation, "handleSyntheticClick: calling completeSyntheticClick -> click.");
+        protectedThis->completeSyntheticClick(targetNode, location, modifiers, WebCore::OneFingerTap);
+    });
 }
 
 void WebPage::completePendingSyntheticClickForContentChangeObserver()