Pointer lock events should be delivered directly to the target element
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 26 Jan 2017 23:47:53 +0000 (23:47 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 26 Jan 2017 23:47:53 +0000 (23:47 +0000)
https://bugs.webkit.org/show_bug.cgi?id=167134

Patch by Jeremy Jones <jeremyj@apple.com> on 2017-01-26
Reviewed by Jon Lee.

Source/WebCore:

pointer-lock/mouse-event-delivery.html: Enabled for mac, added wheel event tests.

When pointer is locked on an element, route mouse events directly to the target element, instead of
doing the normal event disptach.

* page/EventHandler.cpp:
(WebCore::EventHandler::handleMousePressEvent):
(WebCore::EventHandler::handleMouseDoubleClickEvent):
(WebCore::EventHandler::handleMouseMoveEvent):
(WebCore::EventHandler::handleMouseReleaseEvent):
(WebCore::EventHandler::handleMouseForceEvent):
(WebCore::EventHandler::handleWheelEvent):
* page/PointerLockController.cpp:
(WebCore::PointerLockController::isLocked): Added.
(WebCore::PointerLockController::dispatchLockedWheelEvent): Added.
* page/PointerLockController.h:

LayoutTests:

The pointer-lock/mouse-event-delivery.html test is modified to explicitly move the mouse pointer to a valid
location before sending mouse actions. Without this, the test infrastructure doesn't know that the pointer
is over the web view and doesn't deliver events.

Added code to test for wheel events.

* platform/mac/TestExpectations: enabled test.
* pointer-lock/mouse-event-delivery.html:
* pointer-lock/mouse-event-delivery-expected.txt:

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

LayoutTests/ChangeLog
LayoutTests/platform/mac/TestExpectations
LayoutTests/pointer-lock/mouse-event-delivery-expected.txt
LayoutTests/pointer-lock/mouse-event-delivery.html
Source/WebCore/ChangeLog
Source/WebCore/page/EventHandler.cpp
Source/WebCore/page/PointerLockController.cpp
Source/WebCore/page/PointerLockController.h

index 22317d7..a7c0c89 100644 (file)
@@ -1,5 +1,22 @@
 2017-01-26  Jeremy Jones  <jeremyj@apple.com>
 
+        Pointer lock events should be delivered directly to the target element
+        https://bugs.webkit.org/show_bug.cgi?id=167134
+
+        Reviewed by Jon Lee.
+
+        The pointer-lock/mouse-event-delivery.html test is modified to explicitly move the mouse pointer to a valid
+        location before sending mouse actions. Without this, the test infrastructure doesn't know that the pointer
+        is over the web view and doesn't deliver events.
+
+        Added code to test for wheel events.
+
+        * platform/mac/TestExpectations: enabled test.
+        * pointer-lock/mouse-event-delivery.html:
+        * pointer-lock/mouse-event-delivery-expected.txt:
+
+2017-01-26  Jeremy Jones  <jeremyj@apple.com>
+
         Request pointer unlock on navigation and re-enable pointer-lock tests for WK2.
         https://bugs.webkit.org/show_bug.cgi?id=166765
 
index bb24d31..a7053d0 100644 (file)
@@ -281,7 +281,6 @@ fast/events/platform-wheelevent-paging-y-in-scrolling-page.html
 pointer-lock/bug90391-move-then-window-open-crash.html
 pointer-lock/locked-element-iframe-removed-from-dom.html
 pointer-lock/locked-element-removed-from-dom.html
-pointer-lock/mouse-event-delivery.html
 pointer-lock/pointerlockchange-event-on-lock-lost.html
 pointer-lock/pointerlockchange-pointerlockerror-events.html
 pointer-lock/pointerlockelement-null-when-pending.html
index 7565e9f..7f5459c 100644 (file)
@@ -5,11 +5,17 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 
 PASS document.onpointerlockchange event received.
 PASS document.pointerLockElement is targetdiv1
+     With a lock in place send a wheel event.
+PASS event type: wheel, target: target1, received on: target1
+PASS event type: wheel, target: target1, received on: body
      With a lock in place send a click.
 PASS event type: mousedown, target: target1, received on: target1
 PASS event type: mousedown, target: target1, received on: body
 PASS document.onpointerlockchange event received.
 PASS document.pointerLockElement is targetdiv2
+     With a lock in place send a wheel event.
+PASS event type: wheel, target: target2, received on: target2
+PASS event type: wheel, target: target2, received on: body
      With a lock in place send a click.
 PASS event type: mousedown, target: target2, received on: target2
 PASS event type: mousedown, target: target2, received on: body
index e5b9c49..4d0799b 100644 (file)
             // doNextStep() called by onpointerlockchange handler.
         },
         function () {
+            debug("     With a lock in place send a wheel event.")
+            targetdiv1.onwheel = eventExpected;
+            targetdiv2.onwheel = eventNotExpected;
+            document.body.onwheel = eventExpected;
+            if (window.eventSender) {
+                window.eventSender.mouseMoveTo(20,20);
+                window.eventSender.leapForward(1000);
+                window.eventSender.mouseScrollBy(0,10);
+            }
+            doNextStep();
+        },
+        function () {
             debug("     With a lock in place send a click.")
             targetdiv1.onmousedown = eventExpected;
             targetdiv2.onmousedown = eventNotExpected;
             // doNextStep() called by onpointerlockchange handler.
         },
         function () {
+            debug("     With a lock in place send a wheel event.")
+            targetdiv1.onwheel = eventNotExpected;
+            targetdiv2.onwheel = eventExpected;
+            document.body.onwheel = eventExpected;
+            if (window.eventSender) {
+                window.eventSender.leapForward(1000);
+                window.eventSender.mouseScrollBy(0,10);
+            }
+            doNextStep();
+        },
+        function () {
             debug("     With a lock in place send a click.")
             targetdiv1.onmousedown = eventNotExpected;
             targetdiv2.onmousedown = eventExpected;
index 868113c..4fa1de4 100644 (file)
@@ -1,3 +1,27 @@
+2017-01-26  Jeremy Jones  <jeremyj@apple.com>
+
+        Pointer lock events should be delivered directly to the target element
+        https://bugs.webkit.org/show_bug.cgi?id=167134
+
+        Reviewed by Jon Lee.
+
+        pointer-lock/mouse-event-delivery.html: Enabled for mac, added wheel event tests.
+
+        When pointer is locked on an element, route mouse events directly to the target element, instead of 
+        doing the normal event disptach.
+
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::handleMousePressEvent):
+        (WebCore::EventHandler::handleMouseDoubleClickEvent):
+        (WebCore::EventHandler::handleMouseMoveEvent):
+        (WebCore::EventHandler::handleMouseReleaseEvent):
+        (WebCore::EventHandler::handleMouseForceEvent):
+        (WebCore::EventHandler::handleWheelEvent):
+        * page/PointerLockController.cpp:
+        (WebCore::PointerLockController::isLocked): Added.
+        (WebCore::PointerLockController::dispatchLockedWheelEvent): Added.
+        * page/PointerLockController.h:
+
 2017-01-26  Chris Dumez  <cdumez@apple.com>
 
         Fix CPU / Memory diagnostic logging in PerformanceMonitor
index ee4e772..5041c55 100644 (file)
@@ -1622,6 +1622,13 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& platformMouse
         return true;
     }
 
+#if ENABLE(POINTER_LOCK)
+    if (m_frame.page()->pointerLockController().isLocked()) {
+        m_frame.page()->pointerLockController().dispatchLockedMouseEvent(platformMouseEvent, eventNames().mousedownEvent);
+        return true;
+    }
+#endif
+
     if (m_frame.mainFrame().pageOverlayController().handleMouseEvent(platformMouseEvent))
         return true;
 
@@ -1762,6 +1769,13 @@ bool EventHandler::handleMouseDoubleClickEvent(const PlatformMouseEvent& platfor
 
     UserGestureIndicator gestureIndicator(ProcessingUserGesture, m_frame.document());
 
+#if ENABLE(POINTER_LOCK)
+    if (m_frame.page()->pointerLockController().isLocked()) {
+        m_frame.page()->pointerLockController().dispatchLockedMouseEvent(platformMouseEvent, eventNames().mouseupEvent);
+        return true;
+    }
+#endif
+
     // We get this instead of a second mouse-up 
     m_mousePressed = false;
     setLastKnownMousePosition(platformMouseEvent);
@@ -1856,7 +1870,14 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& platformMouseE
 
     Ref<Frame> protectedFrame(m_frame);
     RefPtr<FrameView> protector(m_frame.view());
-    
+
+#if ENABLE(POINTER_LOCK)
+    if (m_frame.page()->pointerLockController().isLocked()) {
+        m_frame.page()->pointerLockController().dispatchLockedMouseEvent(platformMouseEvent, eventNames().mousemoveEvent);
+        return true;
+    }
+#endif
+
     setLastKnownMousePosition(platformMouseEvent);
 
     if (m_hoverTimer.isActive())
@@ -1990,6 +2011,13 @@ bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& platformMou
 
     m_frame.selection().setCaretBlinkingSuspended(false);
 
+#if ENABLE(POINTER_LOCK)
+    if (m_frame.page()->pointerLockController().isLocked()) {
+        m_frame.page()->pointerLockController().dispatchLockedMouseEvent(platformMouseEvent, eventNames().mouseupEvent);
+        return true;
+    }
+#endif
+
     if (m_frame.mainFrame().pageOverlayController().handleMouseEvent(platformMouseEvent))
         return true;
 
@@ -2068,6 +2096,17 @@ bool EventHandler::handleMouseForceEvent(const PlatformMouseEvent& event)
     Ref<Frame> protectedFrame(m_frame);
     RefPtr<FrameView> protector(m_frame.view());
 
+#if ENABLE(POINTER_LOCK)
+    if (m_frame.page()->pointerLockController().isLocked()) {
+        m_frame.page()->pointerLockController().dispatchLockedMouseEvent(event, eventNames().webkitmouseforcechangedEvent);
+        if (event.type() == PlatformEvent::MouseForceDown)
+            m_frame.page()->pointerLockController().dispatchLockedMouseEvent(event, eventNames().webkitmouseforcedownEvent);
+        if (event.type() == PlatformEvent::MouseForceUp)
+            m_frame.page()->pointerLockController().dispatchLockedMouseEvent(event, eventNames().webkitmouseforceupEvent);
+        return true;
+    }
+#endif
+
     setLastKnownMousePosition(event);
 
     HitTestRequest::HitTestRequestType hitType = HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::Active;
@@ -2673,6 +2712,13 @@ bool EventHandler::handleWheelEvent(const PlatformWheelEvent& event)
     if (!view)
         return false;
 
+#if ENABLE(POINTER_LOCK)
+    if (m_frame.page()->pointerLockController().isLocked()) {
+        m_frame.page()->pointerLockController().dispatchLockedWheelEvent(event);
+        return true;
+    }
+#endif
+
     m_isHandlingWheelEvent = true;
     setFrameWasScrolledByUser();
 
index 843fc6c..24b23c7 100644 (file)
@@ -120,6 +120,11 @@ void PointerLockController::documentDetached(Document& document)
     }
 }
 
+bool PointerLockController::isLocked() const
+{
+    return m_element && !m_lockPending;
+}
+
 bool PointerLockController::lockPending() const
 {
     return m_lockPending;
@@ -165,6 +170,14 @@ void PointerLockController::dispatchLockedMouseEvent(const PlatformMouseEvent& e
         m_element->dispatchMouseEvent(event, eventNames().clickEvent, event.clickCount());
 }
 
+void PointerLockController::dispatchLockedWheelEvent(const PlatformWheelEvent& event)
+{
+    if (!m_element || !m_element->document().frame())
+        return;
+
+    m_element->dispatchWheelEvent(event);
+}
+
 void PointerLockController::clearElement()
 {
     m_lockPending = false;
index cb6b0f9..de70b4f 100644 (file)
@@ -35,6 +35,7 @@ class Element;
 class Document;
 class Page;
 class PlatformMouseEvent;
+class PlatformWheelEvent;
 class VoidCallback;
 
 class PointerLockController {
@@ -48,6 +49,7 @@ public:
     void requestPointerUnlockAndForceCursorVisible();
     void elementRemoved(Element&);
     void documentDetached(Document&);
+    bool isLocked() const;
     WEBCORE_EXPORT bool lockPending() const;
     WEBCORE_EXPORT Element* element() const;
 
@@ -55,6 +57,7 @@ public:
     WEBCORE_EXPORT void didNotAcquirePointerLock();
     WEBCORE_EXPORT void didLosePointerLock();
     void dispatchLockedMouseEvent(const PlatformMouseEvent&, const AtomicString& eventType);
+    void dispatchLockedWheelEvent(const PlatformWheelEvent&);
 
 private:
     void clearElement();