Title: [246074] trunk
Revision
246074
Author
[email protected]
Date
2019-06-04 12:00:12 -0700 (Tue, 04 Jun 2019)

Log Message

[Pointer Events] Only allow pointer capture if the pointer is in the active buttons state
https://bugs.webkit.org/show_bug.cgi?id=198479

Patch by Antoine Quint <[email protected]> on 2019-06-04
Reviewed by Dean Jackson.

LayoutTests/imported/w3c:

Mark WPT progression.

* web-platform-tests/pointerevents/pointerevent_setpointercapture_inactive_button_mouse-expected.txt:

Source/WebCore:

The Pointer Events specification says that pointer capture can only be engaged provided the pointer is
in the active buttons state, which means that it has dispatched a "pointerdown" event more recently than
it has a "pointerup" event.

This is tested by web-platform-tests/pointerevents/pointerevent_setpointercapture_inactive_button_mouse.html.

That test showed a few issues that this patch addresses. First, we would update the pointerIsPressed state to
"true" only after a "pointerdown" event had been dispatched. This is incorrect since setPointerCapture() can,
and is likely to, be called during handling of a "pointerdown" event. So we now call pointerEventWillBeDispatched()
prior to dispatching a PointerEvent with a mouse type, which we only did previously for a PointerEvent with a
touch or pen type. If the event is "pointerdown", we set "pointerIsPressed" to true on the CapturingData object
matching the given pointer, and to false if the event is "pointerup".

Finally, we must also ensure that "pointerIsPressed" is set to true when creating CapturingData for a PointerEvent
with a touch or pen type since these types of pointer events implictly set capture.

* page/PointerCaptureController.cpp:
(WebCore::PointerCaptureController::setPointerCapture):
(WebCore::PointerCaptureController::dispatchEvent):
(WebCore::PointerCaptureController::pointerEventWillBeDispatched):
(WebCore::PointerCaptureController::pointerEventWasDispatched):

Modified Paths

Diff

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (246073 => 246074)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2019-06-04 18:27:59 UTC (rev 246073)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2019-06-04 19:00:12 UTC (rev 246074)
@@ -1,3 +1,14 @@
+2019-06-04  Antoine Quint  <[email protected]>
+
+        [Pointer Events] Only allow pointer capture if the pointer is in the active buttons state
+        https://bugs.webkit.org/show_bug.cgi?id=198479
+
+        Reviewed by Dean Jackson.
+
+        Mark WPT progression.
+
+        * web-platform-tests/pointerevents/pointerevent_setpointercapture_inactive_button_mouse-expected.txt:
+
 2019-06-03  Rob Buis  <[email protected]>
 
         Implement imagesrcset and imagesizes attributes on link rel=preload

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_setpointercapture_inactive_button_mouse-expected.txt (246073 => 246074)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_setpointercapture_inactive_button_mouse-expected.txt	2019-06-04 18:27:59 UTC (rev 246073)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_setpointercapture_inactive_button_mouse-expected.txt	2019-06-04 19:00:12 UTC (rev 246074)
@@ -9,5 +9,5 @@
 The following pointer types were detected: mouse.
 
 
-FAIL pointer capture is not set while button state is inactive assert_false: pointer capture is not set while button state is inactive expected false got true
+PASS pointer capture is not set while button state is inactive 
 

Modified: trunk/Source/WebCore/ChangeLog (246073 => 246074)


--- trunk/Source/WebCore/ChangeLog	2019-06-04 18:27:59 UTC (rev 246073)
+++ trunk/Source/WebCore/ChangeLog	2019-06-04 19:00:12 UTC (rev 246074)
@@ -1,3 +1,32 @@
+2019-06-04  Antoine Quint  <[email protected]>
+
+        [Pointer Events] Only allow pointer capture if the pointer is in the active buttons state
+        https://bugs.webkit.org/show_bug.cgi?id=198479
+
+        Reviewed by Dean Jackson.
+
+        The Pointer Events specification says that pointer capture can only be engaged provided the pointer is
+        in the active buttons state, which means that it has dispatched a "pointerdown" event more recently than
+        it has a "pointerup" event.
+
+        This is tested by web-platform-tests/pointerevents/pointerevent_setpointercapture_inactive_button_mouse.html.
+
+        That test showed a few issues that this patch addresses. First, we would update the pointerIsPressed state to
+        "true" only after a "pointerdown" event had been dispatched. This is incorrect since setPointerCapture() can,
+        and is likely to, be called during handling of a "pointerdown" event. So we now call pointerEventWillBeDispatched()
+        prior to dispatching a PointerEvent with a mouse type, which we only did previously for a PointerEvent with a
+        touch or pen type. If the event is "pointerdown", we set "pointerIsPressed" to true on the CapturingData object
+        matching the given pointer, and to false if the event is "pointerup".
+
+        Finally, we must also ensure that "pointerIsPressed" is set to true when creating CapturingData for a PointerEvent
+        with a touch or pen type since these types of pointer events implictly set capture.
+
+        * page/PointerCaptureController.cpp:
+        (WebCore::PointerCaptureController::setPointerCapture):
+        (WebCore::PointerCaptureController::dispatchEvent):
+        (WebCore::PointerCaptureController::pointerEventWillBeDispatched):
+        (WebCore::PointerCaptureController::pointerEventWasDispatched):
+
 2019-06-04  Keith Rollin  <[email protected]>
 
         Fix 32-bit/64-bit mismatch in PointerCaptureController::elementWasRemoved

Modified: trunk/Source/WebCore/page/PointerCaptureController.cpp (246073 => 246074)


--- trunk/Source/WebCore/page/PointerCaptureController.cpp	2019-06-04 18:27:59 UTC (rev 246073)
+++ trunk/Source/WebCore/page/PointerCaptureController.cpp	2019-06-04 19:00:12 UTC (rev 246074)
@@ -70,10 +70,10 @@
 #endif
 
     // 4. If the pointer is not in the active buttons state, then terminate these steps.
-    // FIXME: implement when we support mouse events.
-
     // 5. For the specified pointerId, set the pending pointer capture target override to the Element on which this method was invoked.
-    iterator->value.pendingTargetOverride = capturingTarget;
+    auto& capturingData = iterator->value;
+    if (capturingData.pointerIsPressed)
+        capturingData.pendingTargetOverride = capturingTarget;
 
     return { };
 }
@@ -237,17 +237,39 @@
     if (iterator != m_activePointerIdsToCapturingData.end()) {
         auto& capturingData = iterator->value;
         if (capturingData.pendingTargetOverride && capturingData.targetOverride)
-            capturingData.targetOverride->dispatchEvent(event);
+            target = capturingData.targetOverride.get();
     }
 
-    if (target && !event.target())
-        target->dispatchEvent(event);
+    if (!target || event.target())
+        return;
 
+    pointerEventWillBeDispatched(event, target);
+    target->dispatchEvent(event);
     pointerEventWasDispatched(event);
 }
 
 void PointerCaptureController::pointerEventWillBeDispatched(const PointerEvent& event, EventTarget* target)
 {
+    if (!is<Element>(target))
+        return;
+
+    bool isPointerdown = event.type() == eventNames().pointerdownEvent;
+    bool isPointerup = event.type() == eventNames().pointerupEvent;
+    if (!isPointerdown && !isPointerup)
+        return;
+
+    auto pointerId = event.pointerId();
+
+    if (event.pointerType() == PointerEvent::mousePointerType()) {
+        auto iterator = m_activePointerIdsToCapturingData.find(pointerId);
+        if (iterator != m_activePointerIdsToCapturingData.end())
+            iterator->value.pointerIsPressed = isPointerdown;
+        return;
+    }
+
+    if (!isPointerdown)
+        return;
+
     // https://w3c.github.io/pointerevents/#implicit-pointer-capture
 
     // Some input devices (such as touchscreens) implement a "direct manipulation" metaphor where a pointer is intended to act primarily on the UI
@@ -260,12 +282,9 @@
     // releasePointerCapture is not called for the pointer before the next pointer event is fired, then a gotpointercapture event will be dispatched
     // to the target (as normal) indicating that capture is active.
 
-    if (!is<Element>(target) || event.type() != eventNames().pointerdownEvent)
-        return;
-
-    auto pointerId = event.pointerId();
     CapturingData capturingData;
     capturingData.pointerType = event.pointerType();
+    capturingData.pointerIsPressed = true;
     m_activePointerIdsToCapturingData.set(pointerId, capturingData);
     setPointerCapture(downcast<Element>(target), pointerId);
 }
@@ -281,10 +300,8 @@
         // override for the pointerId of the pointerup or pointercancel event that was just dispatched, and then run Process Pending
         // Pointer Capture steps to fire lostpointercapture if necessary.
         // https://w3c.github.io/pointerevents/#implicit-release-of-pointer-capture
-        if (event.type() == eventNames().pointerupEvent) {
+        if (event.type() == eventNames().pointerupEvent)
             capturingData.pendingTargetOverride = nullptr;
-            capturingData.pointerIsPressed = false;
-        }
 
         // If a mouse pointer has moved while it isn't pressed, make sure we reset the preventsCompatibilityMouseEvents flag since
         // we could otherwise prevent compatibility mouse events while those are only supposed to be prevented while the pointer is pressed.
@@ -293,10 +310,8 @@
 
         // If the pointer event dispatched was pointerdown and the event was canceled, then set the PREVENT MOUSE EVENT flag for this pointerType.
         // https://www.w3.org/TR/pointerevents/#mapping-for-devices-that-support-hover
-        if (event.type() == eventNames().pointerdownEvent) {
+        if (event.type() == eventNames().pointerdownEvent)
             capturingData.preventsCompatibilityMouseEvents = event.defaultPrevented();
-            capturingData.pointerIsPressed = true;
-        }
     }
 
     processPendingPointerCapture(event);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to