Title: [181660] trunk/Source
Revision
181660
Author
[email protected]
Date
2015-03-17 13:20:48 -0700 (Tue, 17 Mar 2015)

Log Message

DOM mouse events have weird timing for force clickable elements in Safari 8.0.3 on 
10.10.2
https://bugs.webkit.org/show_bug.cgi?id=142700
-and corresponding-
rdar://problem/20165168

Reviewed by Tim Horton.

Source/WebCore:

This patch adds a new enum and member variable so that EventHandler can keep track 
of the current immediate action state.
* page/EventHandler.cpp:
(WebCore::EventHandler::EventHandler):

A new mouse press even is starting. We can re-set m_immediateActionStage to none 
unless a Hit Test has already been performed.
(WebCore::EventHandler::handleMousePressEvent):

If an immediate action was completed, then send mouse to the DOM and return early. 
This will prevent us from doing our own normal mouseup behaviors such as 
navigating to a link that was clicked — we only want to do that if the click was 
not used to perform an immediate action.
(WebCore::EventHandler::handleMouseReleaseEvent):
* page/EventHandler.h:
(WebCore::EventHandler::setImmediateActionStage):

Source/WebKit2:

No need to tell the WKImmediateActionController about mouse down any more since we 
are expecting it at the beginning of an immediate action interaction.
* UIProcess/API/mac/WKView.mm:
(-[WKView mouseDown:]):

Set the delaysPrimaryMouseButtonEvents to NO for the 
_immediateActionGestureRecognizer. This will cause AppKit to send up the mouse 
events at the expected time.
(-[WKView initWithFrame:processPool:configuration:webView:]):

WebCore::EventHandler now needs to know if an immediate action cancelled or 
completed. This plumbs that information down.
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::immediateActionDidCancel):
(WebKit::WebPageProxy::immediateActionDidComplete):
* UIProcess/WebPageProxy.h:
* UIProcess/mac/WKImmediateActionController.h:
* UIProcess/mac/WKImmediateActionController.mm:
(-[WKImmediateActionController immediateActionRecognizerDidCancelAnimation:]):
(-[WKImmediateActionController immediateActionRecognizerDidCompleteAnimation:]):
(-[WKImmediateActionController wkView:willHandleMouseDown:]): Deleted.
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:

Call EventHandler::setImmediateActionStage() with the appropriate stage.
* WebProcess/WebPage/mac/WebPageMac.mm:
(WebKit::WebPage::performActionMenuHitTestAtLocation):
(WebKit::WebPage::immediateActionDidCancel):
(WebKit::WebPage::immediateActionDidComplete):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (181659 => 181660)


--- trunk/Source/WebCore/ChangeLog	2015-03-17 20:11:53 UTC (rev 181659)
+++ trunk/Source/WebCore/ChangeLog	2015-03-17 20:20:48 UTC (rev 181660)
@@ -1,3 +1,30 @@
+2015-03-17  Beth Dakin  <[email protected]>
+
+        DOM mouse events have weird timing for force clickable elements in Safari 8.0.3 on 
+        10.10.2
+        https://bugs.webkit.org/show_bug.cgi?id=142700
+        -and corresponding-
+        rdar://problem/20165168
+
+        Reviewed by Tim Horton.
+
+        This patch adds a new enum and member variable so that EventHandler can keep track 
+        of the current immediate action state.
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::EventHandler):
+
+        A new mouse press even is starting. We can re-set m_immediateActionStage to none 
+        unless a Hit Test has already been performed.
+        (WebCore::EventHandler::handleMousePressEvent):
+
+        If an immediate action was completed, then send mouse to the DOM and return early. 
+        This will prevent us from doing our own normal mouseup behaviors such as 
+        navigating to a link that was clicked — we only want to do that if the click was 
+        not used to perform an immediate action.
+        (WebCore::EventHandler::handleMouseReleaseEvent):
+        * page/EventHandler.h:
+        (WebCore::EventHandler::setImmediateActionStage):
+
 2015-03-17  Joseph Pecoraro  <[email protected]>
 
         Use a better parameter name for Document.getElementsByClassName

Modified: trunk/Source/WebCore/page/EventHandler.cpp (181659 => 181660)


--- trunk/Source/WebCore/page/EventHandler.cpp	2015-03-17 20:11:53 UTC (rev 181659)
+++ trunk/Source/WebCore/page/EventHandler.cpp	2015-03-17 20:20:48 UTC (rev 181660)
@@ -423,6 +423,7 @@
 #if ENABLE(CURSOR_VISIBILITY)
     , m_autoHideCursorTimer(*this, &EventHandler::autoHideCursorTimerFired)
 #endif
+    , m_immediateActionStage(ImmediateActionStage::None)
 {
 }
 
@@ -764,6 +765,9 @@
 
     m_mouseDown = event.event();
 
+    if (m_immediateActionStage != ImmediateActionStage::PerformedHitTest)
+        m_immediateActionStage = ImmediateActionStage::None;
+
     if (event.isOverWidget() && passWidgetMouseDownEventToWidget(event))
         return true;
 
@@ -2057,6 +2061,14 @@
     if (m_frameSetBeingResized)
         return !dispatchMouseEvent(eventNames().mouseupEvent, m_frameSetBeingResized.get(), true, m_clickCount, platformMouseEvent, false);
 
+    // If an immediate action was completed using this series of mouse events, then we should send mouseup to
+    // the DOM and return now so that we don't perform our own default behaviors.
+    if (m_immediateActionStage == ImmediateActionStage::ActionCompleted) {
+        m_immediateActionStage = ImmediateActionStage::None;
+        return !dispatchMouseEvent(eventNames().mouseupEvent, m_lastElementUnderMouse.get(), true, m_clickCount, platformMouseEvent, false);
+    }
+    m_immediateActionStage = ImmediateActionStage::None;
+
     if (m_lastScrollbarUnderMouse) {
         invalidateClick();
         m_lastScrollbarUnderMouse->mouseUp(platformMouseEvent);

Modified: trunk/Source/WebCore/page/EventHandler.h (181659 => 181660)


--- trunk/Source/WebCore/page/EventHandler.h	2015-03-17 20:11:53 UTC (rev 181659)
+++ trunk/Source/WebCore/page/EventHandler.h	2015-03-17 20:20:48 UTC (rev 181660)
@@ -117,6 +117,13 @@
 enum AppendTrailingWhitespace { ShouldAppendTrailingWhitespace, DontAppendTrailingWhitespace };
 enum CheckDragHysteresis { ShouldCheckDragHysteresis, DontCheckDragHysteresis };
 
+enum class ImmediateActionStage {
+    None,
+    PerformedHitTest,
+    ActionCancelled,
+    ActionCompleted
+};
+
 class EventHandler {
     WTF_MAKE_NONCOPYABLE(EventHandler);
     WTF_MAKE_FAST_ALLOCATED;
@@ -305,6 +312,8 @@
 
     bool isHandlingWheelEvent() const { return m_isHandlingWheelEvent; }
 
+    WEBCORE_EXPORT void setImmediateActionStage(ImmediateActionStage stage) { m_immediateActionStage = stage; }
+
 private:
 #if ENABLE(DRAG_SUPPORT)
     static DragState& dragState();
@@ -564,6 +573,8 @@
 #if ENABLE(CURSOR_VISIBILITY)
     Timer m_autoHideCursorTimer;
 #endif
+
+    ImmediateActionStage m_immediateActionStage;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebKit2/ChangeLog (181659 => 181660)


--- trunk/Source/WebKit2/ChangeLog	2015-03-17 20:11:53 UTC (rev 181659)
+++ trunk/Source/WebKit2/ChangeLog	2015-03-17 20:20:48 UTC (rev 181660)
@@ -1,3 +1,43 @@
+2015-03-17  Beth Dakin  <[email protected]>
+
+        DOM mouse events have weird timing for force clickable elements in Safari 8.0.3 on 
+        10.10.2
+        https://bugs.webkit.org/show_bug.cgi?id=142700
+        -and corresponding-
+        rdar://problem/20165168
+
+        Reviewed by Tim Horton.
+
+        No need to tell the WKImmediateActionController about mouse down any more since we 
+        are expecting it at the beginning of an immediate action interaction.
+        * UIProcess/API/mac/WKView.mm:
+        (-[WKView mouseDown:]):
+
+        Set the delaysPrimaryMouseButtonEvents to NO for the 
+        _immediateActionGestureRecognizer. This will cause AppKit to send up the mouse 
+        events at the expected time.
+        (-[WKView initWithFrame:processPool:configuration:webView:]):
+
+        WebCore::EventHandler now needs to know if an immediate action cancelled or 
+        completed. This plumbs that information down.
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::immediateActionDidCancel):
+        (WebKit::WebPageProxy::immediateActionDidComplete):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/mac/WKImmediateActionController.h:
+        * UIProcess/mac/WKImmediateActionController.mm:
+        (-[WKImmediateActionController immediateActionRecognizerDidCancelAnimation:]):
+        (-[WKImmediateActionController immediateActionRecognizerDidCompleteAnimation:]):
+        (-[WKImmediateActionController wkView:willHandleMouseDown:]): Deleted.
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+
+        Call EventHandler::setImmediateActionStage() with the appropriate stage.
+        * WebProcess/WebPage/mac/WebPageMac.mm:
+        (WebKit::WebPage::performActionMenuHitTestAtLocation):
+        (WebKit::WebPage::immediateActionDidCancel):
+        (WebKit::WebPage::immediateActionDidComplete):
+
 2015-03-17  Timothy Horton  <[email protected]>
 
         Reproducible null deref under ScriptedAnimationController::createDisplayRefreshMonitor

Modified: trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm (181659 => 181660)


--- trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm	2015-03-17 20:11:53 UTC (rev 181659)
+++ trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm	2015-03-17 20:20:48 UTC (rev 181660)
@@ -1274,7 +1274,6 @@
     [self _dismissContentRelativeChildWindows];
 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
     [_data->_actionMenuController wkView:self willHandleMouseDown:event];
-    [_data->_immediateActionController wkView:self willHandleMouseDown:event];
 #endif
     [self mouseDownInternal:event];
 }
@@ -3666,6 +3665,7 @@
         _data->_immediateActionGestureRecognizer = adoptNS([(NSImmediateActionGestureRecognizer *)[gestureClass alloc] initWithTarget:nil action:NULL]);
         _data->_immediateActionController = adoptNS([[WKImmediateActionController alloc] initWithPage:*_data->_page view:self recognizer:_data->_immediateActionGestureRecognizer.get()]);
         [_data->_immediateActionGestureRecognizer setDelegate:_data->_immediateActionController.get()];
+        [_data->_immediateActionGestureRecognizer setDelaysPrimaryMouseButtonEvents:NO];
     }
 #endif
 

Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (181659 => 181660)


--- trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp	2015-03-17 20:11:53 UTC (rev 181659)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp	2015-03-17 20:20:48 UTC (rev 181660)
@@ -5565,6 +5565,16 @@
     m_process->send(Messages::WebPage::FocusAndSelectLastActionMenuHitTestResult(), m_pageID);
 }
 
+void WebPageProxy::immediateActionDidCancel()
+{
+    m_process->send(Messages::WebPage::ImmediateActionDidCancel(), m_pageID);
+}
+
+void WebPageProxy::immediateActionDidComplete()
+{
+    m_process->send(Messages::WebPage::ImmediateActionDidComplete(), m_pageID);
+}
+
 void WebPageProxy::didPerformActionMenuHitTest(const ActionMenuHitTestResult& result, bool forImmediateAction, const UserData& userData)
 {
     m_pageClient.didPerformActionMenuHitTest(result, forImmediateAction, m_process->transformHandlesToObjects(userData.object()).get());

Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (181659 => 181660)


--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h	2015-03-17 20:11:53 UTC (rev 181659)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h	2015-03-17 20:20:48 UTC (rev 181660)
@@ -985,6 +985,9 @@
     void selectLastActionMenuRange();
     void focusAndSelectLastActionMenuHitTestResult();
 
+    void immediateActionDidCancel();
+    void immediateActionDidComplete();
+
     void installViewStateChangeCompletionHandler(void(^completionHandler)());
 #endif
 

Modified: trunk/Source/WebKit2/UIProcess/mac/WKImmediateActionController.h (181659 => 181660)


--- trunk/Source/WebKit2/UIProcess/mac/WKImmediateActionController.h	2015-03-17 20:11:53 UTC (rev 181659)
+++ trunk/Source/WebKit2/UIProcess/mac/WKImmediateActionController.h	2015-03-17 20:20:48 UTC (rev 181660)
@@ -69,7 +69,6 @@
 - (instancetype)initWithPage:(WebKit::WebPageProxy&)page view:(WKView *)wkView recognizer:(NSImmediateActionGestureRecognizer *)immediateActionRecognizer;
 - (void)willDestroyView:(WKView *)view;
 - (void)didPerformActionMenuHitTest:(const WebKit::ActionMenuHitTestResult&)hitTestResult userData:(API::Object*)userData;
-- (void)wkView:(WKView *)wkView willHandleMouseDown:(NSEvent *)event;
 - (void)dismissContentRelativeChildWindows;
 - (BOOL)hasActiveImmediateAction;
 

Modified: trunk/Source/WebKit2/UIProcess/mac/WKImmediateActionController.mm (181659 => 181660)


--- trunk/Source/WebKit2/UIProcess/mac/WKImmediateActionController.mm	2015-03-17 20:11:53 UTC (rev 181659)
+++ trunk/Source/WebKit2/UIProcess/mac/WKImmediateActionController.mm	2015-03-17 20:20:48 UTC (rev 181660)
@@ -88,11 +88,6 @@
     _hasActiveImmediateAction = NO;
 }
 
-- (void)wkView:(WKView *)wkView willHandleMouseDown:(NSEvent *)event
-{
-    [self _clearImmediateActionState];
-}
-
 - (void)_cancelImmediateAction
 {
     // Reset the recognizer by turning it off and on again.
@@ -218,6 +213,8 @@
     if (immediateActionRecognizer != _immediateActionRecognizer)
         return;
 
+    _page->immediateActionDidCancel();
+
     [_wkView _cancelImmediateActionAnimation];
 
     _page->setTextIndicatorAnimationProgress(0);
@@ -230,6 +227,8 @@
     if (immediateActionRecognizer != _immediateActionRecognizer)
         return;
 
+    _page->immediateActionDidComplete();
+
     [_wkView _completeImmediateActionAnimation];
 
     _page->setTextIndicatorAnimationProgress(1);

Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h (181659 => 181660)


--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h	2015-03-17 20:11:53 UTC (rev 181659)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h	2015-03-17 20:20:48 UTC (rev 181660)
@@ -1084,6 +1084,8 @@
     PassRefPtr<WebCore::Range> lookupTextAtLocation(WebCore::FloatPoint, NSDictionary **options);
     void selectLastActionMenuRange();
     void focusAndSelectLastActionMenuHitTestResult();
+    void immediateActionDidCancel();
+    void immediateActionDidComplete();
     void setFont(const String& fontFamily, double fontSize, uint64_t fontTraits);
 
     void dataDetectorsDidPresentUI(WebCore::PageOverlay::PageOverlayID);

Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in (181659 => 181660)


--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in	2015-03-17 20:11:53 UTC (rev 181659)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in	2015-03-17 20:20:48 UTC (rev 181660)
@@ -405,6 +405,8 @@
     PerformActionMenuHitTestAtLocation(WebCore::FloatPoint location, bool forImmediateAction)
     SelectLastActionMenuRange()
     FocusAndSelectLastActionMenuHitTestResult()
+    ImmediateActionDidCancel()
+    ImmediateActionDidComplete()
     DataDetectorsDidPresentUI(WebCore::PageOverlay::PageOverlayID pageOverlay)
     DataDetectorsDidChangeUI(WebCore::PageOverlay::PageOverlayID pageOverlay)
     DataDetectorsDidHideUI(WebCore::PageOverlay::PageOverlayID pageOverlay)

Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm (181659 => 181660)


--- trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm	2015-03-17 20:11:53 UTC (rev 181659)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm	2015-03-17 20:20:48 UTC (rev 181660)
@@ -1024,6 +1024,9 @@
     IntPoint locationInContentCoordinates = mainFrame.view()->rootViewToContents(roundedIntPoint(locationInViewCooordinates));
     HitTestResult hitTestResult = mainFrame.eventHandler().hitTestResultAtPoint(locationInContentCoordinates);
 
+    if (forImmediateAction)
+        mainFrame.eventHandler().setImmediateActionStage(ImmediateActionStage::PerformedHitTest);
+
     ActionMenuHitTestResult actionMenuResult;
     actionMenuResult.hitTestLocationInViewCooordinates = locationInViewCooordinates;
     actionMenuResult.hitTestResult = WebHitTestResult::Data(hitTestResult);
@@ -1145,6 +1148,16 @@
     frame->selection().setSelection(position);
 }
 
+void WebPage::immediateActionDidCancel()
+{
+    m_page->mainFrame().eventHandler().setImmediateActionStage(ImmediateActionStage::ActionCancelled);
+}
+
+void WebPage::immediateActionDidComplete()
+{
+    m_page->mainFrame().eventHandler().setImmediateActionStage(ImmediateActionStage::ActionCompleted);
+}
+
 void WebPage::dataDetectorsDidPresentUI(PageOverlay::PageOverlayID overlayID)
 {
     MainFrame& mainFrame = corePage()->mainFrame();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to