New force-related DOM events should fire in WK1 views
authorbdakin@apple.com <bdakin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 May 2015 22:32:07 +0000 (22:32 +0000)
committerbdakin@apple.com <bdakin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 May 2015 22:32:07 +0000 (22:32 +0000)
https://bugs.webkit.org/show_bug.cgi?id=144663
-and corresponding-
rdar://problem/20281886

Reviewed by Sam Weinig.

Source/WebCore:

All of the WK1 mouse events need to take the correspondingPressureEvent.
* page/EventHandler.h:

Make correspondingPressureEvent a part of CurrentEventScope. This is needed to
have accurate pressure information for all of the mouse events in subframes.
* page/mac/EventHandlerMac.mm:
(WebCore::correspondingPressureEventSlot):
(WebCore::EventHandler::correspondingPressureEvent):
(WebCore::CurrentEventScope::CurrentEventScope):
(WebCore::CurrentEventScope::~CurrentEventScope):

These events don’t have an associated pressure, so send nil for the
correspondingPressureEvent.
(WebCore::EventHandler::wheelEvent):
(WebCore::EventHandler::keyEvent):

Pipe through correspondingPressureEvent.
(WebCore::EventHandler::mouseDown):
(WebCore::EventHandler::mouseDragged):
(WebCore::EventHandler::mouseUp):
(WebCore::EventHandler::mouseMoved):

New function to handle pressure change events.
(WebCore::EventHandler::pressureChange):

Pipe through correspondingPressureEvent.
(WebCore::EventHandler::passMouseMovedEventToScrollbars):
(WebCore::EventHandler::currentPlatformMouseEvent):

Take the correspondingPressureEvent in order to build a PlatformMouseEvent with
the correct pressure information.
* platform/mac/PlatformEventFactoryMac.h:
* platform/mac/PlatformEventFactoryMac.mm:
(WebCore::globalPointForEvent):
(WebCore::pointForEvent):
(WebCore::mouseButtonForEvent):
(WebCore::PlatformMouseEventBuilder::PlatformMouseEventBuilder):
(WebCore::PlatformEventFactory::createPlatformMouseEvent):

Source/WebKit:

Pass the lastPressureEvent to WebCore.
* WebView/WebHTMLView.mm:
(-[WebHTMLView _updateMouseoverWithEvent:]):
(-[WebHTMLView rightMouseUp:]):
(-[WebHTMLView menuForEvent:]):
(-[WebHTMLView acceptsFirstMouse:]):
(-[WebHTMLView shouldDelayWindowOrderingForEvent:]):
(-[WebHTMLView mouseDown:mouseDown:]):
(-[WebHTMLView mouseDragged:]):
(-[WebHTMLView mouseUp:mouseUp:]):

New NSRespnder method for pressure changes.
(-[WebHTMLView pressureChangeWithEvent:]):

New BOOL _contentPreventsDefault tracks whether the HitTestResult prevented the
default action. Get rid of willHandleMouseDown; now that the gesture recognizer
sets delaysPrimaryMouseButtonEvents to NO, we don’t need this.
* WebView/WebImmediateActionController.h:
* WebView/WebImmediateActionController.mm:
(-[WebImmediateActionController _clearImmediateActionState]):

Set all of the immediateActionStages on EventHandler. This is critical to keep
link navigation happening at the right time now that
delaysPrimaryMouseButtonEvents is set to NO.
(-[WebImmediateActionController performHitTestAtPoint:]):
(-[WebImmediateActionController immediateActionRecognizerDidUpdateAnimation:]):
(-[WebImmediateActionController immediateActionRecognizerDidCancelAnimation:]):
(-[WebImmediateActionController immediateActionRecognizerDidCompleteAnimation:]):

Use a dummy animation controller if the content prevents default.
(-[WebImmediateActionController _defaultAnimationController]):
(-[WebImmediateActionController _updateImmediateActionItem]):
(-[WebImmediateActionController webView:willHandleMouseDown:]): Deleted.

Set delaysPrimaryMouseButtonEvents to NO so that we get existing mouse events when
we expect to.
* WebView/WebView.mm:
(-[WebView _commonInitializationWithFrameName:groupName:]):

Cache the most recent pressure event so that we can send it to WebCore for all of
the mouse events.
(-[WebView _pressureEvent]):
(-[WebView _setPressureEvent:]):
* WebView/WebViewData.h:
* WebView/WebViewData.mm:
(-[WebViewPrivate dealloc]):
* WebView/WebViewInternal.h:

Source/WebKit/mac:

Pass the lastPressureEvent to WebCore.
* WebView/WebHTMLView.mm:
(-[WebHTMLView _updateMouseoverWithEvent:]):
(-[WebHTMLView rightMouseUp:]):
(-[WebHTMLView menuForEvent:]):
(-[WebHTMLView acceptsFirstMouse:]):
(-[WebHTMLView shouldDelayWindowOrderingForEvent:]):
(-[WebHTMLView mouseDown:mouseDown:]):
(-[WebHTMLView mouseDragged:]):
(-[WebHTMLView mouseUp:mouseUp:]):

New NSRespnder method for pressure changes.
(-[WebHTMLView pressureChangeWithEvent:]):

New BOOL _contentPreventsDefault tracks whether the HitTestResult prevented the
default action. Get rid of willHandleMouseDown; now that the gesture recognizer
sets delaysPrimaryMouseButtonEvents to NO, we don’t need this.
* WebView/WebImmediateActionController.h:
* WebView/WebImmediateActionController.mm:
(-[WebImmediateActionController _clearImmediateActionState]):

Set all of the immediateActionStages on EventHandler. This is critical to keep
link navigation happening at the right time now that
delaysPrimaryMouseButtonEvents is set to NO.
(-[WebImmediateActionController performHitTestAtPoint:]):
(-[WebImmediateActionController immediateActionRecognizerDidUpdateAnimation:]):
(-[WebImmediateActionController immediateActionRecognizerDidCancelAnimation:]):
(-[WebImmediateActionController immediateActionRecognizerDidCompleteAnimation:]):

Use a dummy animation controller if the content prevents default.
(-[WebImmediateActionController _defaultAnimationController]):
(-[WebImmediateActionController _updateImmediateActionItem]):
(-[WebImmediateActionController webView:willHandleMouseDown:]): Deleted.

Set delaysPrimaryMouseButtonEvents to NO so that we get existing mouse events when
we expect to.
* WebView/WebView.mm:
(-[WebView _commonInitializationWithFrameName:groupName:]):

Cache the most recent pressure event so that we can send it to WebCore for all of
the mouse events.
(-[WebView _pressureEvent]):
(-[WebView _setPressureEvent:]):
* WebView/WebViewData.h:
* WebView/WebViewData.mm:
(-[WebViewPrivate dealloc]):
* WebView/WebViewInternal.h:

Tools:

PlatformEventFactory::createPlatformMouseEvent() takes the last pressure event
now. Just send nil.
* TestWebKitAPI/Tests/mac/MenuTypesForMouseEvents.mm:
(TestWebKitAPI::buildAndPerformTest):

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

15 files changed:
Source/WebCore/ChangeLog
Source/WebCore/page/EventHandler.h
Source/WebCore/page/mac/EventHandlerMac.mm
Source/WebCore/platform/mac/PlatformEventFactoryMac.h
Source/WebCore/platform/mac/PlatformEventFactoryMac.mm
Source/WebKit/ChangeLog
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebView/WebHTMLView.mm
Source/WebKit/mac/WebView/WebImmediateActionController.h
Source/WebKit/mac/WebView/WebImmediateActionController.mm
Source/WebKit/mac/WebView/WebView.mm
Source/WebKit/mac/WebView/WebViewData.h
Source/WebKit/mac/WebView/WebViewInternal.h
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/mac/MenuTypesForMouseEvents.mm

index 24bad4b43b1f95971a6e917db324c6094045e0a6..2b95090394fd1afc588b3cab55a5498543e9abd8 100644 (file)
@@ -1,3 +1,51 @@
+2015-05-07  Beth Dakin  <bdakin@apple.com>
+
+        New force-related DOM events should fire in WK1 views
+        https://bugs.webkit.org/show_bug.cgi?id=144663
+        -and corresponding-
+        rdar://problem/20281886
+
+        Reviewed by Sam Weinig.
+
+        All of the WK1 mouse events need to take the correspondingPressureEvent.
+        * page/EventHandler.h:
+
+        Make correspondingPressureEvent a part of CurrentEventScope. This is needed to 
+        have accurate pressure information for all of the mouse events in subframes.
+        * page/mac/EventHandlerMac.mm:
+        (WebCore::correspondingPressureEventSlot):
+        (WebCore::EventHandler::correspondingPressureEvent):
+        (WebCore::CurrentEventScope::CurrentEventScope):
+        (WebCore::CurrentEventScope::~CurrentEventScope):
+
+        These events don’t have an associated pressure, so send nil for the 
+        correspondingPressureEvent.
+        (WebCore::EventHandler::wheelEvent):
+        (WebCore::EventHandler::keyEvent):
+
+        Pipe through correspondingPressureEvent.
+        (WebCore::EventHandler::mouseDown):
+        (WebCore::EventHandler::mouseDragged):
+        (WebCore::EventHandler::mouseUp):
+        (WebCore::EventHandler::mouseMoved):
+
+        New function to handle pressure change events.
+        (WebCore::EventHandler::pressureChange):
+
+        Pipe through correspondingPressureEvent.
+        (WebCore::EventHandler::passMouseMovedEventToScrollbars):
+        (WebCore::EventHandler::currentPlatformMouseEvent):
+
+        Take the correspondingPressureEvent in order to build a PlatformMouseEvent with 
+        the correct pressure information.
+        * platform/mac/PlatformEventFactoryMac.h:
+        * platform/mac/PlatformEventFactoryMac.mm:
+        (WebCore::globalPointForEvent):
+        (WebCore::pointForEvent):
+        (WebCore::mouseButtonForEvent):
+        (WebCore::PlatformMouseEventBuilder::PlatformMouseEventBuilder):
+        (WebCore::PlatformEventFactory::createPlatformMouseEvent):
+
 2015-05-06  Roger Fong  <roger_fong@apple.com>
 
         Media Controls: Scrubber should be independent of actual video time, causes scrubber to be jumpy.
index d9cfd15a91e4aec1d4d1782d2e079a67f4b0d4aa..866199cd97e730541dd4a709fb5cb7ebf6eaa31a 100644 (file)
@@ -266,10 +266,11 @@ public:
 
 #if PLATFORM(COCOA) && defined(__OBJC__)
 #if !PLATFORM(IOS)
-    WEBCORE_EXPORT void mouseDown(NSEvent *);
-    WEBCORE_EXPORT void mouseDragged(NSEvent *);
-    WEBCORE_EXPORT void mouseUp(NSEvent *);
-    WEBCORE_EXPORT void mouseMoved(NSEvent *);
+    WEBCORE_EXPORT void mouseDown(NSEvent *, NSEvent *correspondingPressureEvent);
+    WEBCORE_EXPORT void mouseDragged(NSEvent *, NSEvent *correspondingPressureEvent);
+    WEBCORE_EXPORT void mouseUp(NSEvent *, NSEvent *correspondingPressureEvent);
+    WEBCORE_EXPORT void mouseMoved(NSEvent *, NSEvent *correspondingPressureEvent);
+    WEBCORE_EXPORT void pressureChange(NSEvent *, NSEvent* correspondingPressureEvent);
     WEBCORE_EXPORT bool keyEvent(NSEvent *);
     WEBCORE_EXPORT bool wheelEvent(NSEvent *);
 #else
@@ -285,7 +286,7 @@ public:
 #endif
 
 #if !PLATFORM(IOS)
-    WEBCORE_EXPORT void passMouseMovedEventToScrollbars(NSEvent *);
+    WEBCORE_EXPORT void passMouseMovedEventToScrollbars(NSEvent *, NSEvent* correspondingPressureEvent);
 
     WEBCORE_EXPORT void sendFakeEventsAfterWidgetTracking(NSEvent *initiatingEvent);
 #endif
@@ -294,6 +295,7 @@ public:
     void setActivationEventNumber(int num) { m_activationEventNumber = num; }
 
     WEBCORE_EXPORT static NSEvent *currentNSEvent();
+    static NSEvent *correspondingPressureEvent();
 #else
     static WebEvent *currentEvent();
 #endif // !PLATFORM(IOS)
index b1aea269a0cd5a7815b7d6761e476eccad6fe723..7e71dcf784c175a35e92286496d9de9da6074ac8 100644 (file)
@@ -81,10 +81,21 @@ NSEvent *EventHandler::currentNSEvent()
     return currentNSEventSlot().get();
 }
 
+static RetainPtr<NSEvent>& correspondingPressureEventSlot()
+{
+    static NeverDestroyed<RetainPtr<NSEvent>> event;
+    return event;
+}
+
+NSEvent *EventHandler::correspondingPressureEvent()
+{
+    return correspondingPressureEventSlot().get();
+}
+
 class CurrentEventScope {
      WTF_MAKE_NONCOPYABLE(CurrentEventScope);
 public:
-    CurrentEventScope(NSEvent *);
+    CurrentEventScope(NSEvent *, NSEvent *correspondingPressureEvent);
     ~CurrentEventScope();
 
 private:
@@ -92,21 +103,27 @@ private:
 #ifndef NDEBUG
     RetainPtr<NSEvent> m_event;
 #endif
+    RetainPtr<NSEvent> m_savedPressureEvent;
+    RetainPtr<NSEvent> m_correspondingPressureEvent;
 };
 
-inline CurrentEventScope::CurrentEventScope(NSEvent *event)
+inline CurrentEventScope::CurrentEventScope(NSEvent *event, NSEvent *correspondingPressureEvent)
     : m_savedCurrentEvent(currentNSEventSlot())
 #ifndef NDEBUG
     , m_event(event)
 #endif
+    , m_savedPressureEvent(correspondingPressureEventSlot())
+    , m_correspondingPressureEvent(correspondingPressureEvent)
 {
     currentNSEventSlot() = event;
+    correspondingPressureEventSlot() = correspondingPressureEvent;
 }
 
 inline CurrentEventScope::~CurrentEventScope()
 {
     ASSERT(currentNSEventSlot() == m_event);
     currentNSEventSlot() = m_savedCurrentEvent;
+    correspondingPressureEventSlot() = m_savedPressureEvent;
 }
 
 bool EventHandler::wheelEvent(NSEvent *event)
@@ -115,7 +132,7 @@ bool EventHandler::wheelEvent(NSEvent *event)
     if (!page)
         return false;
 
-    CurrentEventScope scope(event);
+    CurrentEventScope scope(event, nil);
     return handleWheelEvent(PlatformEventFactory::createPlatformWheelEvent(event, page->chrome().platformPageClient()));
 }
 
@@ -125,7 +142,7 @@ bool EventHandler::keyEvent(NSEvent *event)
 
     ASSERT([event type] == NSKeyDown || [event type] == NSKeyUp);
 
-    CurrentEventScope scope(event);
+    CurrentEventScope scope(event, nil);
     return keyEvent(PlatformEventFactory::createPlatformKeyboardEvent(event));
 
     END_BLOCK_OBJC_EXCEPTIONS;
@@ -469,7 +486,7 @@ bool EventHandler::passWheelEventToWidget(const PlatformWheelEvent& wheelEvent,
     return false;
 }
 
-void EventHandler::mouseDown(NSEvent *event)
+void EventHandler::mouseDown(NSEvent *event, NSEvent *correspondingPressureEvent)
 {
     FrameView* v = m_frame.view();
     if (!v || m_sendingEventToSubview)
@@ -479,14 +496,14 @@ void EventHandler::mouseDown(NSEvent *event)
     
     m_mouseDownView = nil;
     
-    CurrentEventScope scope(event);
+    CurrentEventScope scope(event, correspondingPressureEvent);
 
     handleMousePressEvent(currentPlatformMouseEvent());
 
     END_BLOCK_OBJC_EXCEPTIONS;
 }
 
-void EventHandler::mouseDragged(NSEvent *event)
+void EventHandler::mouseDragged(NSEvent *event, NSEvent *correspondingPressureEvent)
 {
     FrameView* v = m_frame.view();
     if (!v || m_sendingEventToSubview)
@@ -494,13 +511,13 @@ void EventHandler::mouseDragged(NSEvent *event)
 
     BEGIN_BLOCK_OBJC_EXCEPTIONS;
 
-    CurrentEventScope scope(event);
+    CurrentEventScope scope(event, correspondingPressureEvent);
     handleMouseMoveEvent(currentPlatformMouseEvent());
 
     END_BLOCK_OBJC_EXCEPTIONS;
 }
 
-void EventHandler::mouseUp(NSEvent *event)
+void EventHandler::mouseUp(NSEvent *event, NSEvent *correspondingPressureEvent)
 {
     FrameView* v = m_frame.view();
     if (!v || m_sendingEventToSubview)
@@ -508,7 +525,7 @@ void EventHandler::mouseUp(NSEvent *event)
 
     BEGIN_BLOCK_OBJC_EXCEPTIONS;
 
-    CurrentEventScope scope(event);
+    CurrentEventScope scope(event, correspondingPressureEvent);
 
     // Our behavior here is a little different that Qt. Qt always sends
     // a mouse release event, even for a double click. To correct problems
@@ -595,7 +612,7 @@ void EventHandler::sendFakeEventsAfterWidgetTracking(NSEvent *initiatingEvent)
     END_BLOCK_OBJC_EXCEPTIONS;
 }
 
-void EventHandler::mouseMoved(NSEvent *event)
+void EventHandler::mouseMoved(NSEvent *event, NSEvent* correspondingPressureEvent)
 {
     // Reject a mouse moved if the button is down - screws up tracking during autoscroll
     // These happen because WebKit sometimes has to fake up moved events.
@@ -603,12 +620,23 @@ void EventHandler::mouseMoved(NSEvent *event)
         return;
 
     BEGIN_BLOCK_OBJC_EXCEPTIONS;
-    CurrentEventScope scope(event);
+    CurrentEventScope scope(event, correspondingPressureEvent);
     mouseMoved(currentPlatformMouseEvent());
     END_BLOCK_OBJC_EXCEPTIONS;
 }
 
-void EventHandler::passMouseMovedEventToScrollbars(NSEvent *event)
+void EventHandler::pressureChange(NSEvent *event, NSEvent* correspondingPressureEvent)
+{
+    if (!m_frame.view() || m_sendingEventToSubview)
+        return;
+
+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
+    CurrentEventScope scope(event, correspondingPressureEvent);
+    handleMouseForceEvent(currentPlatformMouseEvent());
+    END_BLOCK_OBJC_EXCEPTIONS;
+}
+
+void EventHandler::passMouseMovedEventToScrollbars(NSEvent *event, NSEvent* correspondingPressureEvent)
 {
     // Reject a mouse moved if the button is down - screws up tracking during autoscroll
     // These happen because WebKit sometimes has to fake up moved events.
@@ -616,7 +644,7 @@ void EventHandler::passMouseMovedEventToScrollbars(NSEvent *event)
         return;
 
     BEGIN_BLOCK_OBJC_EXCEPTIONS;
-    CurrentEventScope scope(event);
+    CurrentEventScope scope(event, correspondingPressureEvent);
     passMouseMovedEventToScrollbars(currentPlatformMouseEvent());
     END_BLOCK_OBJC_EXCEPTIONS;
 }
@@ -674,7 +702,7 @@ PlatformMouseEvent EventHandler::currentPlatformMouseEvent() const
     NSView *windowView = nil;
     if (Page* page = m_frame.page())
         windowView = page->chrome().platformPageClient();
-    return PlatformEventFactory::createPlatformMouseEvent(currentNSEvent(), windowView);
+    return PlatformEventFactory::createPlatformMouseEvent(currentNSEvent(), correspondingPressureEvent(), windowView);
 }
 
 bool EventHandler::eventActivatedView(const PlatformMouseEvent& event) const
index d7e1553ec53db36b7afdd36a827766a7a01ad5ac..8a0e9bc0eef195548647cdbd8123d3f801d41bc7 100644 (file)
@@ -34,7 +34,7 @@ namespace WebCore {
 
 class PlatformEventFactory {
 public:
-    WEBCORE_EXPORT static PlatformMouseEvent createPlatformMouseEvent(NSEvent *, NSView *windowView);
+    WEBCORE_EXPORT static PlatformMouseEvent createPlatformMouseEvent(NSEvent *, NSEvent *correspondingPressureEvent, NSView *windowView);
     static PlatformWheelEvent createPlatformWheelEvent(NSEvent *, NSView *windowView);
     WEBCORE_EXPORT static PlatformKeyboardEvent createPlatformKeyboardEvent(NSEvent *);
 };
index f32d6404e46777078cfd5f5c02fa3f61450387f3..05bb81c686489c22d7b2b1356cd5fd8d67874f47 100644 (file)
@@ -49,6 +49,9 @@ IntPoint globalPoint(const NSPoint& windowPoint, NSWindow *window)
 static IntPoint globalPointForEvent(NSEvent *event)
 {
     switch ([event type]) {
+#if defined(__LP64__) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101003
+        case NSEventTypePressure:
+#endif
         case NSLeftMouseDown:
         case NSLeftMouseDragged:
         case NSLeftMouseUp:
@@ -71,6 +74,9 @@ static IntPoint globalPointForEvent(NSEvent *event)
 static IntPoint pointForEvent(NSEvent *event, NSView *windowView)
 {
     switch ([event type]) {
+#if defined(__LP64__) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101003
+        case NSEventTypePressure:
+#endif
         case NSLeftMouseDown:
         case NSLeftMouseDragged:
         case NSLeftMouseUp:
@@ -99,6 +105,9 @@ static IntPoint pointForEvent(NSEvent *event, NSView *windowView)
 static MouseButton mouseButtonForEvent(NSEvent *event)
 {
     switch ([event type]) {
+#if defined(__LP64__) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101003
+        case NSEventTypePressure:
+#endif
         case NSLeftMouseDown:
         case NSLeftMouseUp:
         case NSLeftMouseDragged:
@@ -411,29 +420,53 @@ static int typeForEvent(NSEvent *event)
     
 class PlatformMouseEventBuilder : public PlatformMouseEvent {
 public:
-    PlatformMouseEventBuilder(NSEvent *event, NSView *windowView)
+    PlatformMouseEventBuilder(NSEvent *event, NSEvent *correspondingPressureEvent, NSView *windowView)
     {
         // PlatformEvent
-        m_type                              = mouseEventTypeForEvent(event);
-        m_modifiers                         = modifiersForEvent(event);
-        m_timestamp                         = eventTimeStampSince1970(event);
+        m_type = mouseEventTypeForEvent(event);
+
+#if defined(__LP64__) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101003
+        BOOL eventIsPressureEvent = [event type] == NSEventTypePressure;
+        if (eventIsPressureEvent) {
+            // Since AppKit doesn't send mouse events for force down or force up, we have to use the current pressure
+            // event and correspondingPressureEvent to detect if this is MouseForceDown, MouseForceUp, or just MouseForceChanged.
+            if (correspondingPressureEvent.stage == 1 && event.stage == 2)
+                m_type = PlatformEvent::MouseForceDown;
+            else if (correspondingPressureEvent.stage == 2 && event.stage == 1)
+                m_type = PlatformEvent::MouseForceUp;
+            else
+                m_type = PlatformEvent::MouseForceChanged;
+        }
+#else
+        UNUSED_PARAM(correspondingPressureEvent);
+#endif
+
+        m_modifiers = modifiersForEvent(event);
+        m_timestamp = eventTimeStampSince1970(event);
 
         // PlatformMouseEvent
-        m_position                          = pointForEvent(event, windowView);
-        m_globalPosition                    = globalPointForEvent(event);
-        m_button                            = mouseButtonForEvent(event);
-        m_clickCount                        = clickCountForEvent(event);
-        
+        m_position = pointForEvent(event, windowView);
+        m_globalPosition = globalPointForEvent(event);
+        m_button = mouseButtonForEvent(event);
+        m_clickCount = clickCountForEvent(event);
+
+        m_force = 0;
+#if defined(__LP64__) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101003
+        int stage = eventIsPressureEvent ? event.stage : correspondingPressureEvent.stage;
+        double pressure = eventIsPressureEvent ? event.pressure : correspondingPressureEvent.pressure;
+        m_force = stage < 1 ? pressure : pressure + stage - 1;
+#endif
+
         // Mac specific
-        m_modifierFlags                     = [event modifierFlags];
-        m_eventNumber                       = [event eventNumber];
-        m_menuTypeForEvent                  = typeForEvent(event);
+        m_modifierFlags = [event modifierFlags];
+        m_eventNumber = [event eventNumber];
+        m_menuTypeForEvent = typeForEvent(event);
     }
 };
 
-PlatformMouseEvent PlatformEventFactory::createPlatformMouseEvent(NSEvent *event, NSView *windowView)
+PlatformMouseEvent PlatformEventFactory::createPlatformMouseEvent(NSEvent *event, NSEvent *correspondingPressureEvent, NSView *windowView)
 {
-    return PlatformMouseEventBuilder(event, windowView);
+    return PlatformMouseEventBuilder(event, correspondingPressureEvent, windowView);
 }
 
 
index da030e6aa8433f14c63c7fdd1a50ad5de04f333c..bcf028234c17a0914dd28a23af0f81368a2b826b 100644 (file)
@@ -1,3 +1,60 @@
+2015-05-07  Beth Dakin  <bdakin@apple.com>
+
+        New force-related DOM events should fire in WK1 views
+        https://bugs.webkit.org/show_bug.cgi?id=144663
+        -and corresponding-
+        rdar://problem/20281886
+
+        Reviewed by Sam Weinig.
+
+        Pass the lastPressureEvent to WebCore.
+        * WebView/WebHTMLView.mm:
+        (-[WebHTMLView _updateMouseoverWithEvent:]):
+        (-[WebHTMLView rightMouseUp:]):
+        (-[WebHTMLView menuForEvent:]):
+        (-[WebHTMLView acceptsFirstMouse:]):
+        (-[WebHTMLView shouldDelayWindowOrderingForEvent:]):
+        (-[WebHTMLView mouseDown:mouseDown:]):
+        (-[WebHTMLView mouseDragged:]):
+        (-[WebHTMLView mouseUp:mouseUp:]):
+
+        New NSRespnder method for pressure changes.
+        (-[WebHTMLView pressureChangeWithEvent:]):
+
+        New BOOL _contentPreventsDefault tracks whether the HitTestResult prevented the 
+        default action. Get rid of willHandleMouseDown; now that the gesture recognizer 
+        sets delaysPrimaryMouseButtonEvents to NO, we don’t need this.
+        * WebView/WebImmediateActionController.h:
+        * WebView/WebImmediateActionController.mm:
+        (-[WebImmediateActionController _clearImmediateActionState]):
+
+        Set all of the immediateActionStages on EventHandler. This is critical to keep 
+        link navigation happening at the right time now that 
+        delaysPrimaryMouseButtonEvents is set to NO.
+        (-[WebImmediateActionController performHitTestAtPoint:]):
+        (-[WebImmediateActionController immediateActionRecognizerDidUpdateAnimation:]):
+        (-[WebImmediateActionController immediateActionRecognizerDidCancelAnimation:]):
+        (-[WebImmediateActionController immediateActionRecognizerDidCompleteAnimation:]):
+
+        Use a dummy animation controller if the content prevents default.
+        (-[WebImmediateActionController _defaultAnimationController]):
+        (-[WebImmediateActionController _updateImmediateActionItem]):
+        (-[WebImmediateActionController webView:willHandleMouseDown:]): Deleted.
+
+        Set delaysPrimaryMouseButtonEvents to NO so that we get existing mouse events when 
+        we expect to.
+        * WebView/WebView.mm:
+        (-[WebView _commonInitializationWithFrameName:groupName:]):
+
+        Cache the most recent pressure event so that we can send it to WebCore for all of 
+        the mouse events.
+        (-[WebView _pressureEvent]):
+        (-[WebView _setPressureEvent:]):
+        * WebView/WebViewData.h:
+        * WebView/WebViewData.mm:
+        (-[WebViewPrivate dealloc]):
+        * WebView/WebViewInternal.h:
+
 2015-04-27  Brent Fulgham  <bfulgham@apple.com>
 
         [Win] Deactivate WebGL until Windows tests work properly
index 9b422b3e055d3891ba598015cee67ab466b33ddb..a3da3af9bd6826d853f36a073f78b913bd13c81d 100644 (file)
@@ -1,3 +1,60 @@
+2015-05-07  Beth Dakin  <bdakin@apple.com>
+
+        New force-related DOM events should fire in WK1 views
+        https://bugs.webkit.org/show_bug.cgi?id=144663
+        -and corresponding-
+        rdar://problem/20281886
+
+        Reviewed by Sam Weinig.
+
+        Pass the lastPressureEvent to WebCore.
+        * WebView/WebHTMLView.mm:
+        (-[WebHTMLView _updateMouseoverWithEvent:]):
+        (-[WebHTMLView rightMouseUp:]):
+        (-[WebHTMLView menuForEvent:]):
+        (-[WebHTMLView acceptsFirstMouse:]):
+        (-[WebHTMLView shouldDelayWindowOrderingForEvent:]):
+        (-[WebHTMLView mouseDown:mouseDown:]):
+        (-[WebHTMLView mouseDragged:]):
+        (-[WebHTMLView mouseUp:mouseUp:]):
+
+        New NSRespnder method for pressure changes.
+        (-[WebHTMLView pressureChangeWithEvent:]):
+
+        New BOOL _contentPreventsDefault tracks whether the HitTestResult prevented the 
+        default action. Get rid of willHandleMouseDown; now that the gesture recognizer 
+        sets delaysPrimaryMouseButtonEvents to NO, we don’t need this.
+        * WebView/WebImmediateActionController.h:
+        * WebView/WebImmediateActionController.mm:
+        (-[WebImmediateActionController _clearImmediateActionState]):
+
+        Set all of the immediateActionStages on EventHandler. This is critical to keep 
+        link navigation happening at the right time now that 
+        delaysPrimaryMouseButtonEvents is set to NO.
+        (-[WebImmediateActionController performHitTestAtPoint:]):
+        (-[WebImmediateActionController immediateActionRecognizerDidUpdateAnimation:]):
+        (-[WebImmediateActionController immediateActionRecognizerDidCancelAnimation:]):
+        (-[WebImmediateActionController immediateActionRecognizerDidCompleteAnimation:]):
+
+        Use a dummy animation controller if the content prevents default.
+        (-[WebImmediateActionController _defaultAnimationController]):
+        (-[WebImmediateActionController _updateImmediateActionItem]):
+        (-[WebImmediateActionController webView:willHandleMouseDown:]): Deleted.
+
+        Set delaysPrimaryMouseButtonEvents to NO so that we get existing mouse events when 
+        we expect to.
+        * WebView/WebView.mm:
+        (-[WebView _commonInitializationWithFrameName:groupName:]):
+
+        Cache the most recent pressure event so that we can send it to WebCore for all of 
+        the mouse events.
+        (-[WebView _pressureEvent]):
+        (-[WebView _setPressureEvent:]):
+        * WebView/WebViewData.h:
+        * WebView/WebViewData.mm:
+        (-[WebViewPrivate dealloc]):
+        * WebView/WebViewInternal.h:
+
 2015-05-05  Myles C. Maxfield  <mmaxfield@apple.com>
 
         Revert "Introducing the Platform Abstraction Layer (PAL)"
index 2ebe7c60bb8f79899a0269f785d1add52f50dacd..d35fad54fba959a49603608a1b6c7b958ca1793d 100644 (file)
@@ -1768,7 +1768,7 @@ static bool mouseEventIsPartOfClickOrDrag(NSEvent *event)
             context:[[NSApp currentEvent] context]
             eventNumber:0 clickCount:0 pressure:0];
         if (Frame* lastHitCoreFrame = core([lastHitView _frame]))
-            lastHitCoreFrame->eventHandler().mouseMoved(event);
+            lastHitCoreFrame->eventHandler().mouseMoved(event, [[self _webView] _pressureEvent]);
     }
 
     lastHitView = view;
@@ -1787,9 +1787,9 @@ static bool mouseEventIsPartOfClickOrDrag(NSEvent *event)
                 || [[self _webView] _dashboardBehavior:WebDashboardBehaviorAlwaysSendMouseEventsToAllWindows]
 #endif
                 ) {
-                coreFrame->eventHandler().mouseMoved(event);
+                coreFrame->eventHandler().mouseMoved(event, [[self _webView] _pressureEvent]);
             } else
-                coreFrame->eventHandler().passMouseMovedEventToScrollbars(event);
+                coreFrame->eventHandler().passMouseMovedEventToScrollbars(event, [[self _webView] _pressureEvent]);
         }
 
         [view release];
@@ -3303,7 +3303,7 @@ WEBCORE_COMMAND(toggleUnderline)
     [super rightMouseUp:event];
 
     if (Frame* coreframe = core([self _frame]))
-        coreframe->eventHandler().mouseUp(event);
+        coreframe->eventHandler().mouseUp(event, [[self _webView] _pressureEvent]);
 }
 
 static void setMenuItemTarget(NSMenuItem* menuItem)
@@ -3348,8 +3348,8 @@ static void setMenuTargets(NSMenu* menu)
     // Match behavior of other browsers by sending a mousedown event for right clicks.
     _private->handlingMouseDownEvent = YES;
     page->contextMenuController().clearContextMenu();
-    coreFrame->eventHandler().mouseDown(event);
-    BOOL handledEvent = coreFrame->eventHandler().sendContextMenuEvent(PlatformEventFactory::createPlatformMouseEvent(event, page->chrome().platformPageClient()));
+    coreFrame->eventHandler().mouseDown(event, [[self _webView] _pressureEvent]);
+    BOOL handledEvent = coreFrame->eventHandler().sendContextMenuEvent(PlatformEventFactory::createPlatformMouseEvent(event, [[self _webView] _pressureEvent], page->chrome().platformPageClient()));
     _private->handlingMouseDownEvent = NO;
 
     if (!handledEvent)
@@ -3777,7 +3777,7 @@ static void setMenuTargets(NSMenu* menu)
             if ([hitHTMLView _isSelectionEvent:event]) {
 #if ENABLE(DRAG_SUPPORT)
                 if (Page* page = coreFrame->page())
-                    result = coreFrame->eventHandler().eventMayStartDrag(PlatformEventFactory::createPlatformMouseEvent(event, page->chrome().platformPageClient()));
+                    result = coreFrame->eventHandler().eventMayStartDrag(PlatformEventFactory::createPlatformMouseEvent(event, [[self _webView] _pressureEvent], page->chrome().platformPageClient()));
 #endif
             } else if ([hitHTMLView _isScrollBarEvent:event])
                 result = true;
@@ -3804,7 +3804,7 @@ static void setMenuTargets(NSMenu* menu)
 #if ENABLE(DRAG_SUPPORT)
             if (Frame* coreFrame = core([hitHTMLView _frame])) {
                 if (Page* page = coreFrame->page())
-                    result = coreFrame->eventHandler().eventMayStartDrag(PlatformEventFactory::createPlatformMouseEvent(event, page->chrome().platformPageClient()));
+                    result = coreFrame->eventHandler().eventMayStartDrag(PlatformEventFactory::createPlatformMouseEvent(event, [[self _webView] _pressureEvent], page->chrome().platformPageClient()));
             }
 #endif
             [hitHTMLView _setMouseDownEvent:nil];
@@ -3841,7 +3841,6 @@ static void setMenuTargets(NSMenu* menu)
 
 #if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
     [[[self _webView] _actionMenuController] webView:[self _webView] willHandleMouseDown:event];
-    [[[self _webView] _immediateActionController] webView:[self _webView] willHandleMouseDown:event];
 #endif
 
 #if PLATFORM(IOS)
@@ -3872,7 +3871,7 @@ static void setMenuTargets(NSMenu* menu)
             // Let WebCore get a chance to deal with the event. This will call back to us
             // to start the autoscroll timer if appropriate.
             if (Frame* coreframe = core([self _frame]))
-                coreframe->eventHandler().mouseDown(event);
+                coreframe->eventHandler().mouseDown(event, [[self _webView] _pressureEvent]);
         }
     }
 #pragma clang diagnostic pop
@@ -3925,7 +3924,7 @@ static void setMenuTargets(NSMenu* menu)
     if (!_private->ignoringMouseDraggedEvents) {
         if (Frame* frame = core([self _frame])) {
             if (Page* page = frame->page())
-                page->mainFrame().eventHandler().mouseDragged(event);
+                page->mainFrame().eventHandler().mouseDragged(event, [[self _webView] _pressureEvent]);
         }
     }
 
@@ -4064,8 +4063,13 @@ static bool matchesExtensionOrEquivalent(NSString *filename, NSString *extension
 
     [self _stopAutoscrollTimer];
     if (Frame* frame = core([self _frame])) {
-        if (Page* page = frame->page())
+        if (Page* page = frame->page()) {
+#if PLATFORM(IOS)
             page->mainFrame().eventHandler().mouseUp(event);
+#else
+            page->mainFrame().eventHandler().mouseUp(event, [[self _webView] _pressureEvent]);
+#endif
+        }
     }
 #if !PLATFORM(IOS)
     [self _updateMouseoverWithFakeEvent];
@@ -4081,6 +4085,22 @@ static bool matchesExtensionOrEquivalent(NSString *filename, NSString *extension
 }
 #endif
 
+- (void)pressureChangeWithEvent:(NSEvent *)event
+{
+#if defined(__LP64__) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101003
+    NSEvent *lastPressureEvent = [[self _webView] _pressureEvent];
+    if (event.phase != NSEventPhaseChanged && event.phase != NSEventPhaseBegan && event.phase != NSEventPhaseEnded)
+        return;
+
+    RefPtr<Frame> coreFrame = core([self _frame]);
+    if (!coreFrame)
+        return;
+
+    coreFrame->eventHandler().pressureChange(event, lastPressureEvent);
+    [[self _webView] _setPressureEvent:event];
+#endif
+}
+
 #if !PLATFORM(IOS)
 // returning YES from this method is the way we tell AppKit that it is ok for this view
 // to be in the key loop even when "tab to all controls" is not on.
index 6262720f8e45034eb052d8f3a5f45cc8bd577bdf..febbd955af9f63eccf77ebf346e2c623b92a9543 100644 (file)
     RetainPtr<DDActionContext> _currentActionContext;
     BOOL _isShowingTextIndicator;
     BOOL _hasActivatedActionContext;
+    BOOL _contentPreventsDefault;
 }
 
 - (instancetype)initWithWebView:(WebView *)webView recognizer:(NSImmediateActionGestureRecognizer *)immediateActionRecognizer;
 - (void)webViewClosed;
 
-- (void)webView:(WebView *)webView willHandleMouseDown:(NSEvent *)event;
 - (void)webView:(WebView *)webView didHandleScrollWheel:(NSEvent *)event;
 
 - (NSImmediateActionGestureRecognizer *)immediateActionRecognizer;
index b94d99e26b7cf12cc326436d3bea7b83c4588b60..31aa4bc03b68d3a0e1cf09b672ae5d78bf82a152 100644 (file)
@@ -64,6 +64,13 @@ SOFT_LINK_CLASS(QuickLookUI, QLPreviewMenuItem)
 @interface WebImmediateActionController () <QLPreviewMenuItemDelegate>
 @end
 
+@interface WebAnimationController : NSObject <NSImmediateActionAnimationController> {
+}
+@end
+
+@implementation WebAnimationController
+@end
+
 using namespace WebCore;
 
 @implementation WebImmediateActionController
@@ -94,12 +101,6 @@ using namespace WebCore;
     _currentActionContext = nil;
 }
 
-- (void)webView:(WebView *)webView willHandleMouseDown:(NSEvent *)event
-{
-    [self _clearImmediateActionState];
-    [_webView _clearTextIndicatorWithAnimation:TextIndicatorDismissalAnimation::FadeOut];
-}
-
 - (void)webView:(WebView *)webView didHandleScrollWheel:(NSEvent *)event
 {
     [_currentQLPreviewMenuItem close];
@@ -136,6 +137,7 @@ using namespace WebCore;
     _type = WebImmediateActionNone;
     _currentActionContext = nil;
     _currentQLPreviewMenuItem = nil;
+    _contentPreventsDefault = NO;
 }
 
 - (void)performHitTestAtPoint:(NSPoint)viewPoint
@@ -144,6 +146,10 @@ using namespace WebCore;
     if (!coreFrame)
         return;
     _hitTestResult = coreFrame->eventHandler().hitTestResultAtPoint(IntPoint(viewPoint));
+    coreFrame->eventHandler().setImmediateActionStage(ImmediateActionStage::PerformedHitTest);
+
+    if (Element* element = _hitTestResult.innerElement())
+        _contentPreventsDefault = element->dispatchMouseForceWillBegin();
 }
 
 #pragma mark NSImmediateActionGestureRecognizerDelegate
@@ -188,6 +194,13 @@ using namespace WebCore;
     if (immediateActionRecognizer != _immediateActionRecognizer)
         return;
 
+    Frame* coreFrame = core([[[[_webView _selectedOrMainFrame] frameView] documentView] _frame]);
+    if (!coreFrame)
+        return;
+    coreFrame->eventHandler().setImmediateActionStage(ImmediateActionStage::ActionUpdated);
+    if (_contentPreventsDefault)
+        return;
+
     [_webView _setTextIndicatorAnimationProgress:[immediateActionRecognizer animationProgress]];
 }
 
@@ -196,6 +209,10 @@ using namespace WebCore;
     if (immediateActionRecognizer != _immediateActionRecognizer)
         return;
 
+    Frame* coreFrame = core([[[[_webView _selectedOrMainFrame] frameView] documentView] _frame]);
+    if (coreFrame)
+        coreFrame->eventHandler().setImmediateActionStage(ImmediateActionStage::ActionCancelled);
+
     [_webView _setTextIndicatorAnimationProgress:0];
     [self _clearImmediateActionState];
     [_webView _clearTextIndicatorWithAnimation:TextIndicatorDismissalAnimation::None];
@@ -207,6 +224,11 @@ using namespace WebCore;
     if (immediateActionRecognizer != _immediateActionRecognizer)
         return;
 
+    Frame* coreFrame = core([[[[_webView _selectedOrMainFrame] frameView] documentView] _frame]);
+    if (!coreFrame)
+        return;
+    coreFrame->eventHandler().setImmediateActionStage(ImmediateActionStage::ActionCompleted);
+
     [_webView _setTextIndicatorAnimationProgress:1];
     [_webView _setMaintainsInactiveSelection:NO];
 }
@@ -215,6 +237,11 @@ using namespace WebCore;
 
 - (id <NSImmediateActionAnimationController>)_defaultAnimationController
 {
+    if (_contentPreventsDefault) {
+        RetainPtr<WebAnimationController> dummyController = [[WebAnimationController alloc] init];
+        return dummyController.get();
+    }
+
     NSURL *url = _hitTestResult.absoluteLinkURL();
     NSString *absoluteURLString = [url absoluteString];
     if (url && _hitTestResult.URLElement()) {
@@ -265,6 +292,11 @@ using namespace WebCore;
 
     id <NSImmediateActionAnimationController> defaultAnimationController = [self _defaultAnimationController];
 
+    if (_contentPreventsDefault) {
+        [_immediateActionRecognizer setAnimationController:defaultAnimationController];
+        return;
+    }
+
     // Allow clients the opportunity to override the default immediate action.
     id customClientAnimationController = nil;
     if ([[_webView UIDelegate] respondsToSelector:@selector(_webView:immediateActionAnimationControllerForHitTestResult:withType:)]) {
index faa02556fd79871832078407e36a681addadc0f0..1deeee25db1e20b344e9d6e61656d52fea3069f2 100644 (file)
@@ -910,6 +910,7 @@ static void WebKitInitializeGamepadProviderIfNecessary()
         RetainPtr<NSImmediateActionGestureRecognizer> recognizer = adoptNS([(NSImmediateActionGestureRecognizer *)[gestureClass alloc] initWithTarget:nil action:NULL]);
         _private->immediateActionController = [[WebImmediateActionController alloc] initWithWebView:self recognizer:recognizer.get()];
         [recognizer setDelegate:_private->immediateActionController];
+        [recognizer setDelaysPrimaryMouseButtonEvents:NO];
     }
 #endif
 
@@ -8601,6 +8602,16 @@ bool LayerFlushController::flushLayers()
 }
 #endif // __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
 
+- (NSEvent *)_pressureEvent
+{
+    return _private->pressureEvent.get();
+}
+
+- (void)_setPressureEvent:(NSEvent *)event
+{
+    _private->pressureEvent = event;
+}
+
 - (void)_setTextIndicator:(TextIndicator&)textIndicator
 {
     [self _setTextIndicator:textIndicator withLifetime:TextIndicatorLifetime::Permanent];
index 9f1d1ab114af07bc1ea491fdbc6ee45ff14c5e5b..43d10ec447a58d2729a1f336947551527acd69db 100644 (file)
@@ -175,6 +175,7 @@ private:
     std::unique_ptr<WebCore::TextIndicatorWindow> textIndicatorWindow;
     BOOL hasInitializedLookupObserver;
     RetainPtr<WebWindowVisibilityObserver> windowVisibilityObserver;
+    RetainPtr<NSEvent> pressureEvent;
 #endif // PLATFORM(MAC)
 
     BOOL shouldMaintainInactiveSelection;
index 980b0bd38422eb57ec02e02a711b91e928c3f18e..ea8a8305278625138257ad4480f77f86240935d8 100644 (file)
@@ -269,6 +269,8 @@ OBJC_CLASS NSTextAlternatives;
 - (WebActionMenuController *)_actionMenuController;
 - (WebImmediateActionController *)_immediateActionController;
 #endif
+- (NSEvent *)_pressureEvent;
+- (void)_setPressureEvent:(NSEvent *)event;
 #endif
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS) && defined(__cplusplus)
index 42348a3dd966142bd05a3bd628c5bb372a454ee3..8ce0fe1fb354144620a80e39172f8ddc9c98847a 100644 (file)
@@ -1,3 +1,17 @@
+2015-05-07  Beth Dakin  <bdakin@apple.com>
+
+        New force-related DOM events should fire in WK1 views
+        https://bugs.webkit.org/show_bug.cgi?id=144663
+        -and corresponding-
+        rdar://problem/20281886
+
+        Reviewed by Sam Weinig.
+
+        PlatformEventFactory::createPlatformMouseEvent() takes the last pressure event 
+        now. Just send nil. 
+        * TestWebKitAPI/Tests/mac/MenuTypesForMouseEvents.mm:
+        (TestWebKitAPI::buildAndPerformTest):
+
 2015-05-07  Michael Catanzaro  <mcatanzaro@igalia.com>
 
         [GTK] Checks for DEVELOPMENT_BUILD are all wrong
index 03f0f74b324490a650625c10c62c2ecbfde3d8cf..8e4b4f791a9af0a7fe2b76fee6e903b810c1f0b6 100644 (file)
@@ -52,7 +52,7 @@ static void buildAndPerformTest(NSEventType buttonEvent, NSEventModifierFlags mo
                                       clickCount:0
                                         pressure:0];
     
-    auto pme = WebCore::PlatformEventFactory::createPlatformMouseEvent(event, webView.get());
+    auto pme = WebCore::PlatformEventFactory::createPlatformMouseEvent(event, nil, webView.get());
     
     EXPECT_EQ(expectedButton, pme.button());
     EXPECT_TRUE(!modifierFlags || pme.modifierFlags() & modifierFlags);