Title: [246103] trunk
Revision
246103
Author
[email protected]
Date
2019-06-05 01:41:30 -0700 (Wed, 05 Jun 2019)

Log Message

[Pointer Events] Add support for chorded button interactions
https://bugs.webkit.org/show_bug.cgi?id=198462

Reviewed by Dean Jackson.

LayoutTests/imported/w3c:

Mark the progression for web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover.html which
proves the correct implementation of the chorded button interactions section of the Pointer Events spec. To do that,
we also had to make use of the "button" parameter used in WPT tests action sequences, which allows the test to indicate
which mouse button is pressed. Finally, there is now a change in the pointerevent_pointermove_on_chorded_mouse_button.html
results, another source change is required to get this test to fully pass.

* web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt:
* web-platform-tests/pointerevents/pointerevent_pointermove_on_chorded_mouse_button-expected.txt:
* web-platform-tests/resources/testdriver-vendor.js:
(dispatchMouseActions):

Source/WebCore:

Pointer events differ from mouse events in that pressing a button on a mouse and then pressing a second button
would yield two "mousedown" events but a single "pointerdown" event, for the first time we're transitioning from
a state where no button is pressed at all, and then a "pointermove" event to indicate an additional button has been
pressed. This is what the Pointer Events specification calls "chorded button interactions".
See https://w3c.github.io/pointerevents/#chorded-button-interactions for the full details.

To implement this, we no longer directly call PointerEvent::create() from Element::dispatchMouseEvent() but instead
call the new PointerCaptureController::pointerEventForMouseEvent() which implements the required logic to determine
for "mousedown" and "mouseup" mouse events, if we're transitioning from or to a state where no button is pressed at
all.

While that basic change is pretty small, a wider change was required to report the correct value for a PointerEvents'
"button" property which should return "-1" when there is no change in pressed button state compared to any previous
pointer event.

Up until now, MouseEvent.button was an "unsigned short", as specified up to and including DOM Level 2 Events. But the
UI Events spec says that property is a "short", and PointerEvent is the only interface where a "-1" value is used. This
required some changes throughout our codebase since we used a "-1" value to specify that no button was pressed when dealing
with NSEvent input and going through PlatformMouseEvent and eventually MouseEvent. So now we change the various NoButton
enum values to be "-2" and use that value, which is not going to be used for any mouse button, as the value reflected as
"0" through MouseEvent.button, as specified by UI Events.

Furthermore, we identified another issue: MouseEvent.buttons would always return 0 in DRT and WKTR. We rely upon that
value in PointerCaptureController::pointerEventForMouseEvent() and so we had to make that work for the relevant WPT test,
web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover.html, to pass and show a correct implementation
of chorded button interactions. The details of the work required for this is in Tools/ChangeLog.

* dom/Element.cpp:
(WebCore::Element::dispatchMouseEvent):
* dom/MouseEvent.cpp:
(WebCore::MouseEvent::create):
(WebCore::MouseEvent::MouseEvent):
(WebCore::MouseEvent::initMouseEvent):
(WebCore::MouseEvent::initMouseEventQuirk):
* dom/MouseEvent.h:
(WebCore::MouseEvent::button const):
* dom/MouseEvent.idl:
* dom/MouseEventInit.h:
* dom/MouseEventInit.idl:
* dom/PointerEvent.cpp:
(WebCore::PointerEvent::create):
(WebCore::PointerEvent::PointerEvent):
* dom/PointerEvent.h:
* loader/NavigationAction.h:
* page/PointerCaptureController.cpp:
(WebCore::PointerCaptureController::pointerEventForMouseEvent):
* page/PointerCaptureController.h:
* platform/PlatformMouseEvent.h:

Source/WebKit:

Update to use -2 instead of -1 for NoButton.

* Shared/API/c/WKEvent.h:
* Shared/WebEvent.h:

Source/WebKitLegacy/mac:

Update -[DOMMouseEvent button] to be a "short" and update the noButton value from -1 to -2.

* DOM/DOMMouseEvent.h:
* DOM/DOMMouseEvent.mm:
(-[DOMMouseEvent button]):
* WebView/WebPDFView.mm:
(-[WebPDFView PDFViewWillClickOnLink:withURL:]):

Tools:

Until now, MouseEvent.buttons would always return 0 when used within DRT and WKTR as [NSEvent pressedMouseButtons], used
by PlatformMouseEventBuilder to set the m_buttons value eventually used to set MouseEvent.buttons, not account for the
NSEvent created through the eventSender JS object in tests. To fix this, we now track the pressed mouse buttons within
DRT and WKTR as mouseDown() and mouseUp() are called, and swizzle [NSEvent pressedMouseButtons] to return that value.

In the case of DRT, one test would fail when swizzling this method in the case where the target view for the event would
be the DRTMockScroller, a subclass of NSScroller. So we only swizzle when the target view is *not* an NSScroller or a
subclass.

Finally, we change the NoMouseButton enum value from -1 to -2 to adjust to MouseEvent.button now being a "short".

* DumpRenderTree/mac/EventSendingController.mm:
(swizzledEventPressedMouseButtons):
(-[EventSendingController mouseDown:withModifiers:]):
(-[EventSendingController mouseUp:withModifiers:]):
(-[EventSendingController mouseMoveToX:Y:]):
* TestWebKitAPI/Tests/mac/IsNavigationActionTrusted.mm:
* WebKitTestRunner/EventSenderProxy.h:
(WTR::EventSenderProxy::mouseButtonsCurrentlyDown const):
* WebKitTestRunner/mac/EventSenderProxy.mm:
(WTR::swizzledEventPressedMouseButtons):
(WTR::EventSenderProxy::mouseDown):
(WTR::EventSenderProxy::mouseUp):
(WTR::EventSenderProxy::mouseMoveTo):

LayoutTests:

Update some tests and their expectations due to MouseEvent.buttons now returning the correct value in DRT and WKTR
and MouseEvent.button now being a "short" instead of an "unsigned short".

* fast/events/constructors/mouse-event-constructor-expected.txt:
* fast/events/constructors/mouse-event-constructor.html: Update the test to test the boundary values for "short" instead
of "unsigned short" as well as the new "magic" value of -2 for no button, which ends up being reported as 0.
* fast/events/constructors/wheel-event-constructor-expected.txt:
* fast/events/constructors/wheel-event-constructor.html: Update the test to test the boundary values for "short" instead
of "unsigned short" as well as the new "magic" value of -2 for no button, which ends up being reported as 0.
* fast/events/fire-mousedown-while-pressing-mouse-button.html: Rewrite this test to always use MouseEvent.buttons and
adjust the bitmask expectations which were way off.
* platform/mac-wk1/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt:
* platform/mac-highsierra/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt:
* platform/mac-highsierra-wk1/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt:
This test fails differently in WK1 and WK2 and will be addressed in a future patch.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (246102 => 246103)


--- trunk/LayoutTests/ChangeLog	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/LayoutTests/ChangeLog	2019-06-05 08:41:30 UTC (rev 246103)
@@ -1,3 +1,26 @@
+2019-06-01  Antoine Quint  <[email protected]>
+
+        [Pointer Events] Add support for chorded button interactions
+        https://bugs.webkit.org/show_bug.cgi?id=198462
+
+        Reviewed by Dean Jackson.
+
+        Update some tests and their expectations due to MouseEvent.buttons now returning the correct value in DRT and WKTR
+        and MouseEvent.button now being a "short" instead of an "unsigned short".
+
+        * fast/events/constructors/mouse-event-constructor-expected.txt:
+        * fast/events/constructors/mouse-event-constructor.html: Update the test to test the boundary values for "short" instead
+        of "unsigned short" as well as the new "magic" value of -2 for no button, which ends up being reported as 0.
+        * fast/events/constructors/wheel-event-constructor-expected.txt:
+        * fast/events/constructors/wheel-event-constructor.html: Update the test to test the boundary values for "short" instead
+        of "unsigned short" as well as the new "magic" value of -2 for no button, which ends up being reported as 0.
+        * fast/events/fire-mousedown-while-pressing-mouse-button.html: Rewrite this test to always use MouseEvent.buttons and
+        adjust the bitmask expectations which were way off.
+        * platform/mac-wk1/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt:
+        * platform/mac-highsierra/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt:
+        * platform/mac-highsierra-wk1/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt:
+        This test fails differently in WK1 and WK2 and will be addressed in a future patch.
+
 2019-06-04  Zalan Bujtas  <[email protected]>
 
         [ContentChangeObserver] Gmail text editing controls require two taps

Modified: trunk/LayoutTests/fast/events/constructors/mouse-event-constructor-expected.txt (246102 => 246103)


--- trunk/LayoutTests/fast/events/constructors/mouse-event-constructor-expected.txt	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/LayoutTests/fast/events/constructors/mouse-event-constructor-expected.txt	2019-06-05 08:41:30 UTC (rev 246103)
@@ -151,11 +151,13 @@
 PASS new MouseEvent('eventType', { metaKey: false }).metaKey is false
 PASS new MouseEvent('eventType', { metaKey: true }).metaKey is true
 PASS new MouseEvent('eventType', { button: 0 }).button is 0
+PASS new MouseEvent('eventType', { button: -1 }).button is -1
+PASS new MouseEvent('eventType', { button: -2 }).button is 0
 PASS new MouseEvent('eventType', { button: 1 }).button is 1
-PASS new MouseEvent('eventType', { button: 65534 }).button is 65534
-PASS new MouseEvent('eventType', { button: 65535 }).button is 0
-PASS new MouseEvent('eventType', { button: 9007199254740991 }).button is 0
-PASS new MouseEvent('eventType', { button: -1 }).button is 0
+PASS new MouseEvent('eventType', { button: -32768 }).button is -32768
+PASS new MouseEvent('eventType', { button: 32767 }).button is 32767
+PASS new MouseEvent('eventType', { button: 32768 }).button is -32768
+PASS new MouseEvent('eventType', { button: -32769 }).button is 32767
 PASS new MouseEvent('eventType', { button: 18446744073709551615 }).button is 0
 PASS new MouseEvent('eventType', { button: 12345678901234567890 }).button is 2048
 PASS new MouseEvent('eventType', { button: 123.45 }).button is 123

Modified: trunk/LayoutTests/fast/events/constructors/mouse-event-constructor.html (246102 => 246103)


--- trunk/LayoutTests/fast/events/constructors/mouse-event-constructor.html	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/LayoutTests/fast/events/constructors/mouse-event-constructor.html	2019-06-05 08:41:30 UTC (rev 246103)
@@ -100,16 +100,16 @@
 });
 
 // button is passed.
-// Numbers within the unsigned short range.
+// Numbers within the short range.
 shouldBe("new MouseEvent('eventType', { button: 0 }).button", "0");
+shouldBe("new MouseEvent('eventType', { button: -1 }).button", "-1");
+shouldBe("new MouseEvent('eventType', { button: -2 }).button", "0");
 shouldBe("new MouseEvent('eventType', { button: 1 }).button", "1");
-shouldBe("new MouseEvent('eventType', { button: 65534 }).button", "65534");
+shouldBe("new MouseEvent('eventType', { button: -32768 }).button", "-32768");
+shouldBe("new MouseEvent('eventType', { button: 32767 }).button", "32767");
+shouldBe("new MouseEvent('eventType', { button: 32768 }).button", "-32768");
+shouldBe("new MouseEvent('eventType', { button: -32769 }).button", "32767");
 
-// Numbers that are equal to ((unsigned short)-1) should be treated as 0.
-shouldBe("new MouseEvent('eventType', { button: 65535 }).button", "0");
-shouldBe("new MouseEvent('eventType', { button: 9007199254740991 }).button", "0");
-shouldBe("new MouseEvent('eventType', { button: -1 }).button", "0");
-
 // Numbers out of the unsigned short range.
 // 2^{64}-1
 shouldBe("new MouseEvent('eventType', { button: 18446744073709551615 }).button", "0");

Modified: trunk/LayoutTests/fast/events/constructors/wheel-event-constructor-expected.txt (246102 => 246103)


--- trunk/LayoutTests/fast/events/constructors/wheel-event-constructor-expected.txt	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/LayoutTests/fast/events/constructors/wheel-event-constructor-expected.txt	2019-06-05 08:41:30 UTC (rev 246103)
@@ -221,11 +221,13 @@
 PASS new WheelEvent('eventType', { metaKey: false }).metaKey is false
 PASS new WheelEvent('eventType', { metaKey: true }).metaKey is true
 PASS new WheelEvent('eventType', { button: 0 }).button is 0
+PASS new WheelEvent('eventType', { button: -1 }).button is -1
+PASS new WheelEvent('eventType', { button: -2 }).button is 0
 PASS new WheelEvent('eventType', { button: 1 }).button is 1
-PASS new WheelEvent('eventType', { button: 65534 }).button is 65534
-PASS new WheelEvent('eventType', { button: 65535 }).button is 0
-PASS new WheelEvent('eventType', { button: 9007199254740991 }).button is 0
-PASS new WheelEvent('eventType', { button: -1 }).button is 0
+PASS new WheelEvent('eventType', { button: -32768 }).button is -32768
+PASS new WheelEvent('eventType', { button: 32767 }).button is 32767
+PASS new WheelEvent('eventType', { button: 32768 }).button is -32768
+PASS new WheelEvent('eventType', { button: -32769 }).button is 32767
 PASS new WheelEvent('eventType', { button: 18446744073709551615 }).button is 0
 PASS new WheelEvent('eventType', { button: 12345678901234567890 }).button is 2048
 PASS new WheelEvent('eventType', { button: 123.45 }).button is 123

Modified: trunk/LayoutTests/fast/events/constructors/wheel-event-constructor.html (246102 => 246103)


--- trunk/LayoutTests/fast/events/constructors/wheel-event-constructor.html	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/LayoutTests/fast/events/constructors/wheel-event-constructor.html	2019-06-05 08:41:30 UTC (rev 246103)
@@ -137,16 +137,16 @@
 });
 
 // button is passed.
-// Numbers within the unsigned short range.
+// Numbers within the short range.
 shouldBe("new WheelEvent('eventType', { button: 0 }).button", "0");
+shouldBe("new WheelEvent('eventType', { button: -1 }).button", "-1");
+shouldBe("new WheelEvent('eventType', { button: -2 }).button", "0");
 shouldBe("new WheelEvent('eventType', { button: 1 }).button", "1");
-shouldBe("new WheelEvent('eventType', { button: 65534 }).button", "65534");
+shouldBe("new WheelEvent('eventType', { button: -32768 }).button", "-32768");
+shouldBe("new WheelEvent('eventType', { button: 32767 }).button", "32767");
+shouldBe("new WheelEvent('eventType', { button: 32768 }).button", "-32768");
+shouldBe("new WheelEvent('eventType', { button: -32769 }).button", "32767");
 
-// Numbers that are equal to ((unsigned short)-1) should be treated as 0.
-shouldBe("new WheelEvent('eventType', { button: 65535 }).button", "0");
-shouldBe("new WheelEvent('eventType', { button: 9007199254740991 }).button", "0");
-shouldBe("new WheelEvent('eventType', { button: -1 }).button", "0");
-
 // Numbers out of the unsigned short range.
 // 2^{64}-1
 shouldBe("new WheelEvent('eventType', { button: 18446744073709551615 }).button", "0");

Modified: trunk/LayoutTests/fast/events/fire-mousedown-while-pressing-mouse-button.html (246102 => 246103)


--- trunk/LayoutTests/fast/events/fire-mousedown-while-pressing-mouse-button.html	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/LayoutTests/fast/events/fire-mousedown-while-pressing-mouse-button.html	2019-06-05 08:41:30 UTC (rev 246103)
@@ -47,15 +47,15 @@
     runTest();
 }
 
-function toIEMouseButton(w3cButton)
+function toBitmaskMouseButton(w3cButton)
 {
     switch (w3cButton) {
     case LeftMouseButton:
-        return 1;
+        return 1 << 0;
     case MiddleMouseButton:
-        return 4;
+        return 1 << 1;
     case RightMouseButton:
-        return 2;
+        return 1 << 2;
     }
     return; // We shouldn't get here.
 }
@@ -91,24 +91,13 @@
 
 function checkIfDoneOnMouseDown(event)
 {
-    var pressedButtons; // A bitmask that represents the combination of buttons that are currently being pressed.
-    if (event && event.buttons)
-        pressedButtons = event.buttons; // DOM Level 3 Events (Working Draft 07 September 2010).
-    else if (event) {
-        // For browsers than don't support event.buttons (or IE's window.event.button) we convert event.button to
-        // the corresponding bitmask to simplify the logic below.
-        pressedButtons = toIEMouseButton(event.button);
-    } else {
-        // Assume this script is running within Internet Explorer.
-        pressedButtons = window.event.button;
-    }
-
+    var pressedButtons = event.buttons; // A bitmask that represents the combination of buttons that are currently being pressed.
     var chosenFirstMouseButton = firstMouseButtonElem.selectedIndex;
     var chosenSecondMouseButton = secondMouseButtonElem.selectedIndex;
-    if (!didFireMousedownForFirstMouseButton && (pressedButtons & toIEMouseButton(chosenFirstMouseButton)) == toIEMouseButton(chosenFirstMouseButton)) {
+    if (!didFireMousedownForFirstMouseButton && (pressedButtons & toBitmaskMouseButton(chosenFirstMouseButton)) == toBitmaskMouseButton(chosenFirstMouseButton)) {
         didFireMousedownForFirstMouseButton = true;
         square.innerHTML = "Now, " + shortMouseButtonName(chosenSecondMouseButton) + " click";
-    } else if (didFireMousedownForFirstMouseButton && (pressedButtons & toIEMouseButton(chosenSecondMouseButton)) == toIEMouseButton(chosenSecondMouseButton))
+    } else if (didFireMousedownForFirstMouseButton && (pressedButtons & toBitmaskMouseButton(chosenSecondMouseButton)) == toBitmaskMouseButton(chosenSecondMouseButton))
         didFireMousedownForSecondMouseButton = true;
     if (didFireMousedownForFirstMouseButton && didFireMousedownForSecondMouseButton) {
         testPassed("received mousedown for the " + mouseButtonName(chosenSecondMouseButton) + " while pressing the " + mouseButtonName(chosenFirstMouseButton) + ".");

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (246102 => 246103)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2019-06-05 08:41:30 UTC (rev 246103)
@@ -1,3 +1,21 @@
+2019-06-01  Antoine Quint  <[email protected]>
+
+        [Pointer Events] Add support for chorded button interactions
+        https://bugs.webkit.org/show_bug.cgi?id=198462
+
+        Reviewed by Dean Jackson.
+
+        Mark the progression for web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover.html which
+        proves the correct implementation of the chorded button interactions section of the Pointer Events spec. To do that,
+        we also had to make use of the "button" parameter used in WPT tests action sequences, which allows the test to indicate
+        which mouse button is pressed. Finally, there is now a change in the pointerevent_pointermove_on_chorded_mouse_button.html
+        results, another source change is required to get this test to fully pass.
+
+        * web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt:
+        * web-platform-tests/pointerevents/pointerevent_pointermove_on_chorded_mouse_button-expected.txt:
+        * web-platform-tests/resources/testdriver-vendor.js:
+        (dispatchMouseActions):
+
 2019-06-04  Antoine Quint  <[email protected]>
 
         [Pointer Events] Only allow pointer capture if the pointer is in the active buttons state

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt (246102 => 246103)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt	2019-06-05 08:41:30 UTC (rev 246103)
@@ -1,5 +1,5 @@
 
 FAIL Mouse down and capture to green. assert_array_equals: Received events: green received pointerover,green received pointerenter,green received pointermove,green received pointerdown,green received gotpointercapture,green received pointermove,green received pointerout,green received pointerleave,green received pointerover,green received pointerenter,green received pointermove lengths differ, expected 7 got 11
-FAIL Mouse down at green and capture to blue. assert_array_equals: Received events: green received pointerout,green received pointerover,green received pointerenter,green received pointermove,green received pointerdown,green received lostpointercapture,blue received gotpointercapture,blue received pointermove,blue received pointermove lengths differ, expected 11 got 9
-FAIL Mouse down and capture to green, move to blue and release capture assert_array_equals: Received events: blue received pointerout,blue received pointerover,blue received pointerenter,blue received pointermove,blue received pointerdown,blue received pointerout,blue received pointerleave,blue received pointerover,blue received pointerenter,blue received pointermove,blue received pointermove lengths differ, expected 12 got 11
+FAIL Mouse down at green and capture to blue. assert_array_equals: Received events: green received pointerout,green received pointerover,green received pointerenter,green received pointermove,green received pointermove,green received pointermove lengths differ, expected 11 got 6
+FAIL Mouse down and capture to green, move to blue and release capture assert_array_equals: Received events: green received pointerout,green received pointerover,green received pointerenter,green received pointermove,green received lostpointercapture,green received pointerout,green received pointerleave,blue received pointerover,blue received pointerenter,blue received pointermove,blue received pointermove lengths differ, expected 12 got 11
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_pointermove_on_chorded_mouse_button-expected.txt (246102 => 246103)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_pointermove_on_chorded_mouse_button-expected.txt	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_pointermove_on_chorded_mouse_button-expected.txt	2019-06-05 08:41:30 UTC (rev 246103)
@@ -14,5 +14,5 @@
 Refresh the page to run the tests again.
 
 
-FAIL pointermove events received for button state changes assert_true: There must not be more than one pointer down event. expected true got false
+PASS pointermove events received for button state changes 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver-vendor.js (246102 => 246103)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver-vendor.js	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver-vendor.js	2019-06-05 08:41:30 UTC (rev 246103)
@@ -28,14 +28,12 @@
                     eventSender.mouseMoveTo(action.x + origin.x, action.y + origin.y);
                     break;
                 case "pointerDown":
-                    // FIXME: what to do with "button"?
                     logDebug(() => `eventSender.mouseDown()`);
-                    eventSender.mouseDown();
+                    eventSender.mouseDown(action.button);
                     break;
                 case "pointerUp":
-                    // FIXME: what to do with "button"?
                     logDebug(() => `eventSender.mouseUp()`);
-                    eventSender.mouseUp();
+                    eventSender.mouseUp(action.button);
                     break;
                 default:
                     return Promise.reject(new Error(`Unknown action type "${action.type}".`));

Copied: trunk/LayoutTests/platform/mac-highsierra/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt (from rev 246102, trunk/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt) (0 => 246103)


--- trunk/LayoutTests/platform/mac-highsierra/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-highsierra/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt	2019-06-05 08:41:30 UTC (rev 246103)
@@ -0,0 +1,5 @@
+
+FAIL Mouse down and capture to green. assert_array_equals: Received events: green received pointerover,green received pointerenter,green received pointermove,green received pointerdown,green received gotpointercapture,green received pointermove,green received pointerout,green received pointerleave,green received pointerover,green received pointerenter,green received pointermove lengths differ, expected 7 got 11
+FAIL Mouse down at green and capture to blue. assert_array_equals: Received events: green received pointerout,green received pointerover,green received pointerenter,green received pointermove,green received pointermove,green received pointermove,green received pointermove lengths differ, expected 11 got 7
+FAIL Mouse down and capture to green, move to blue and release capture assert_array_equals: Received events: green received pointerout,green received pointerover,green received pointerenter,green received pointermove,green received lostpointercapture,green received pointermove,green received pointerout,green received pointerleave,blue received pointerover,blue received pointerenter,blue received pointermove,blue received pointermove property 0, expected "green received pointerover" but got "green received pointerout"
+

Copied: trunk/LayoutTests/platform/mac-highsierra-wk1/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt (from rev 246102, trunk/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt) (0 => 246103)


--- trunk/LayoutTests/platform/mac-highsierra-wk1/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-highsierra-wk1/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt	2019-06-05 08:41:30 UTC (rev 246103)
@@ -0,0 +1,5 @@
+
+FAIL Mouse down and capture to green. assert_array_equals: Received events: green received pointerover,green received pointerenter,green received pointermove,green received pointerdown,green received gotpointercapture lengths differ, expected 7 got 5
+FAIL Mouse down at green and capture to blue. assert_array_equals: Received events: green received pointermove lengths differ, expected 11 got 1
+FAIL Mouse down and capture to green, move to blue and release capture assert_array_equals: Received events: green received pointermove,green received lostpointercapture lengths differ, expected 12 got 2
+

Modified: trunk/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt (246102 => 246103)


--- trunk/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt	2019-06-05 08:41:30 UTC (rev 246103)
@@ -1,5 +1,5 @@
 
 FAIL Mouse down and capture to green. assert_array_equals: Received events: green received pointerover,green received pointerenter,green received pointermove,green received pointerdown,green received gotpointercapture lengths differ, expected 7 got 5
-FAIL Mouse down at green and capture to blue. assert_array_equals: Received events: green received pointerdown,green received lostpointercapture,blue received gotpointercapture lengths differ, expected 11 got 3
-FAIL Mouse down and capture to green, move to blue and release capture assert_array_equals: Received events: blue received pointerdown lengths differ, expected 12 got 1
+FAIL Mouse down at green and capture to blue. assert_array_equals: Received events:  lengths differ, expected 11 got 0
+FAIL Mouse down and capture to green, move to blue and release capture assert_array_equals: Received events:  lengths differ, expected 12 got 0
 

Modified: trunk/Source/WebCore/ChangeLog (246102 => 246103)


--- trunk/Source/WebCore/ChangeLog	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/Source/WebCore/ChangeLog	2019-06-05 08:41:30 UTC (rev 246103)
@@ -1,3 +1,59 @@
+2019-06-01  Antoine Quint  <[email protected]>
+
+        [Pointer Events] Add support for chorded button interactions
+        https://bugs.webkit.org/show_bug.cgi?id=198462
+
+        Reviewed by Dean Jackson.
+
+        Pointer events differ from mouse events in that pressing a button on a mouse and then pressing a second button
+        would yield two "mousedown" events but a single "pointerdown" event, for the first time we're transitioning from
+        a state where no button is pressed at all, and then a "pointermove" event to indicate an additional button has been
+        pressed. This is what the Pointer Events specification calls "chorded button interactions".
+        See https://w3c.github.io/pointerevents/#chorded-button-interactions for the full details.
+
+        To implement this, we no longer directly call PointerEvent::create() from Element::dispatchMouseEvent() but instead
+        call the new PointerCaptureController::pointerEventForMouseEvent() which implements the required logic to determine
+        for "mousedown" and "mouseup" mouse events, if we're transitioning from or to a state where no button is pressed at
+        all.
+
+        While that basic change is pretty small, a wider change was required to report the correct value for a PointerEvents'
+        "button" property which should return "-1" when there is no change in pressed button state compared to any previous
+        pointer event.
+
+        Up until now, MouseEvent.button was an "unsigned short", as specified up to and including DOM Level 2 Events. But the
+        UI Events spec says that property is a "short", and PointerEvent is the only interface where a "-1" value is used. This
+        required some changes throughout our codebase since we used a "-1" value to specify that no button was pressed when dealing
+        with NSEvent input and going through PlatformMouseEvent and eventually MouseEvent. So now we change the various NoButton
+        enum values to be "-2" and use that value, which is not going to be used for any mouse button, as the value reflected as
+        "0" through MouseEvent.button, as specified by UI Events.
+
+        Furthermore, we identified another issue: MouseEvent.buttons would always return 0 in DRT and WKTR. We rely upon that
+        value in PointerCaptureController::pointerEventForMouseEvent() and so we had to make that work for the relevant WPT test,
+        web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover.html, to pass and show a correct implementation
+        of chorded button interactions. The details of the work required for this is in Tools/ChangeLog.
+
+        * dom/Element.cpp:
+        (WebCore::Element::dispatchMouseEvent):
+        * dom/MouseEvent.cpp:
+        (WebCore::MouseEvent::create):
+        (WebCore::MouseEvent::MouseEvent):
+        (WebCore::MouseEvent::initMouseEvent):
+        (WebCore::MouseEvent::initMouseEventQuirk):
+        * dom/MouseEvent.h:
+        (WebCore::MouseEvent::button const):
+        * dom/MouseEvent.idl:
+        * dom/MouseEventInit.h:
+        * dom/MouseEventInit.idl:
+        * dom/PointerEvent.cpp:
+        (WebCore::PointerEvent::create):
+        (WebCore::PointerEvent::PointerEvent):
+        * dom/PointerEvent.h:
+        * loader/NavigationAction.h:
+        * page/PointerCaptureController.cpp:
+        (WebCore::PointerCaptureController::pointerEventForMouseEvent):
+        * page/PointerCaptureController.h:
+        * platform/PlatformMouseEvent.h:
+
 2019-06-05  Michael Catanzaro  <[email protected]>
 
         REGRESSION(r245796): [WPE][GTK] Web process crash on startup

Modified: trunk/Source/WebCore/dom/Element.cpp (246102 => 246103)


--- trunk/Source/WebCore/dom/Element.cpp	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/Source/WebCore/dom/Element.cpp	2019-06-05 08:41:30 UTC (rev 246103)
@@ -314,25 +314,24 @@
 
 #if ENABLE(POINTER_EVENTS)
     if (RuntimeEnabledFeatures::sharedFeatures().pointerEventsEnabled()) {
+        if (auto* page = document().page()) {
+            auto& pointerCaptureController = page->pointerCaptureController();
 #if ENABLE(TOUCH_EVENTS)
-        if (auto* page = document().page()) {
-            if (mouseEvent->type() != eventNames().clickEvent && page->pointerCaptureController().preventsCompatibilityMouseEventsForIdentifier(platformEvent.pointerId()))
+            if (mouseEvent->type() != eventNames().clickEvent && pointerCaptureController.preventsCompatibilityMouseEventsForIdentifier(platformEvent.pointerId()))
                 return false;
-        }
 #else
-        if (auto pointerEvent = PointerEvent::create(mouseEvent)) {
-            if (auto* page = document().page()) {
-                page->pointerCaptureController().dispatchEvent(*pointerEvent, this);
-                if (isCompatibilityMouseEvent(mouseEvent) && page->pointerCaptureController().preventsCompatibilityMouseEventsForIdentifier(pointerEvent->pointerId()))
+            if (auto pointerEvent = pointerCaptureController.pointerEventForMouseEvent(mouseEvent)) {
+                pointerCaptureController.dispatchEvent(*pointerEvent, this);
+                if (isCompatibilityMouseEvent(mouseEvent) && pointerCaptureController.preventsCompatibilityMouseEventsForIdentifier(pointerEvent->pointerId()))
                     return false;
+                if (pointerEvent->defaultPrevented() || pointerEvent->defaultHandled()) {
+                    didNotSwallowEvent = false;
+                    if (pointerEvent->type() == eventNames().pointerdownEvent)
+                        return false;
+                }
             }
-            if (pointerEvent->defaultPrevented() || pointerEvent->defaultHandled()) {
-                didNotSwallowEvent = false;
-                if (pointerEvent->type() == eventNames().pointerdownEvent)
-                    return false;
-            }
+#endif
         }
-#endif
     }
 #endif
 

Modified: trunk/Source/WebCore/dom/MouseEvent.cpp (246102 => 246103)


--- trunk/Source/WebCore/dom/MouseEvent.cpp	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/Source/WebCore/dom/MouseEvent.cpp	2019-06-05 08:41:30 UTC (rev 246103)
@@ -62,7 +62,7 @@
 }
 
 Ref<MouseEvent> MouseEvent::create(const AtomicString& type, CanBubble canBubble, IsCancelable isCancelable, IsComposed isComposed, MonotonicTime timestamp, RefPtr<WindowProxy>&& view, int detail,
-    const IntPoint& screenLocation, const IntPoint& windowLocation, const IntPoint& movementDelta, OptionSet<Modifier> modifiers, unsigned short button, unsigned short buttons,
+    const IntPoint& screenLocation, const IntPoint& windowLocation, const IntPoint& movementDelta, OptionSet<Modifier> modifiers, short button, unsigned short buttons,
     EventTarget* relatedTarget, double force, unsigned short syntheticClickType, DataTransfer* dataTransfer, IsSimulated isSimulated, IsTrusted isTrusted)
 {
     return adoptRef(*new MouseEvent(type, canBubble, isCancelable, isComposed, timestamp, WTFMove(view), detail,
@@ -70,7 +70,7 @@
 }
 
 Ref<MouseEvent> MouseEvent::create(const AtomicString& eventType, CanBubble canBubble, IsCancelable isCancelable, IsComposed isComposed, RefPtr<WindowProxy>&& view, int detail,
-    int screenX, int screenY, int clientX, int clientY, OptionSet<Modifier> modifiers, unsigned short button, unsigned short buttons,
+    int screenX, int screenY, int clientX, int clientY, OptionSet<Modifier> modifiers, short button, unsigned short buttons,
     unsigned short syntheticClickType, EventTarget* relatedTarget)
 {
     return adoptRef(*new MouseEvent(eventType, canBubble, isCancelable, isComposed, WTFMove(view), detail, { screenX, screenY }, { clientX, clientY }, modifiers, button, buttons, syntheticClickType, relatedTarget));
@@ -80,13 +80,13 @@
 
 MouseEvent::MouseEvent(const AtomicString& eventType, CanBubble canBubble, IsCancelable isCancelable, IsComposed isComposed,
     MonotonicTime timestamp, RefPtr<WindowProxy>&& view, int detail,
-    const IntPoint& screenLocation, const IntPoint& windowLocation, const IntPoint& movementDelta, OptionSet<Modifier> modifiers, unsigned short button, unsigned short buttons,
+    const IntPoint& screenLocation, const IntPoint& windowLocation, const IntPoint& movementDelta, OptionSet<Modifier> modifiers, short button, unsigned short buttons,
     EventTarget* relatedTarget, double force, unsigned short syntheticClickType, DataTransfer* dataTransfer, IsSimulated isSimulated, IsTrusted isTrusted)
     : MouseRelatedEvent(eventType, canBubble, isCancelable, isComposed, timestamp, WTFMove(view), detail, screenLocation, windowLocation, movementDelta, modifiers, isSimulated, isTrusted)
-    , m_button(button == (unsigned short)-1 ? 0 : button)
+    , m_button(button == -2 ? 0 : button)
     , m_buttons(buttons)
-    , m_syntheticClickType(button == (unsigned short)-1 ? 0 : syntheticClickType)
-    , m_buttonDown(button != (unsigned short)-1)
+    , m_syntheticClickType(button == -2 ? 0 : syntheticClickType)
+    , m_buttonDown(button != -2)
     , m_relatedTarget(relatedTarget)
     , m_force(force)
     , m_dataTransfer(dataTransfer)
@@ -95,12 +95,12 @@
 
 MouseEvent::MouseEvent(const AtomicString& eventType, CanBubble canBubble, IsCancelable isCancelable, IsComposed isComposed,
     RefPtr<WindowProxy>&& view, int detail, const IntPoint& screenLocation, const IntPoint& clientLocation,
-    OptionSet<Modifier> modifiers, unsigned short button, unsigned short buttons, unsigned short syntheticClickType, EventTarget* relatedTarget)
+    OptionSet<Modifier> modifiers, short button, unsigned short buttons, unsigned short syntheticClickType, EventTarget* relatedTarget)
     : MouseRelatedEvent(eventType, canBubble, isCancelable, isComposed, MonotonicTime::now(), WTFMove(view), detail, screenLocation, { }, { }, modifiers, IsSimulated::No)
-    , m_button(button == (unsigned short)-1 ? 0 : button)
+    , m_button(button == -2 ? 0 : button)
     , m_buttons(buttons)
-    , m_syntheticClickType(button == (unsigned short)-1 ? 0 : syntheticClickType)
-    , m_buttonDown(button != (unsigned short)-1)
+    , m_syntheticClickType(button == -2 ? 0 : syntheticClickType)
+    , m_buttonDown(button != -2)
     , m_relatedTarget(relatedTarget)
 {
     initCoordinates(clientLocation);
@@ -108,9 +108,9 @@
 
 MouseEvent::MouseEvent(const AtomicString& eventType, const MouseEventInit& initializer)
     : MouseRelatedEvent(eventType, initializer)
-    , m_button(initializer.button == (unsigned short)-1 ? 0 : initializer.button)
+    , m_button(initializer.button == -2 ? 0 : initializer.button)
     , m_buttons(initializer.buttons)
-    , m_buttonDown(initializer.button != (unsigned short)-1)
+    , m_buttonDown(initializer.button != -2)
     , m_relatedTarget(initializer.relatedTarget)
 {
     initCoordinates({ initializer.clientX, initializer.clientY });
@@ -119,7 +119,7 @@
 MouseEvent::~MouseEvent() = default;
 
 void MouseEvent::initMouseEvent(const AtomicString& type, bool canBubble, bool cancelable, RefPtr<WindowProxy>&& view, int detail,
-    int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, unsigned short button, EventTarget* relatedTarget)
+    int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, short button, EventTarget* relatedTarget)
 {
     if (isBeingDispatched())
         return;
@@ -128,9 +128,9 @@
 
     m_screenLocation = IntPoint(screenX, screenY);
     setModifierKeys(ctrlKey, altKey, shiftKey, metaKey);
-    m_button = button == (unsigned short)-1 ? 0 : button;
+    m_button = button == -2 ? 0 : button;
     m_syntheticClickType = 0;
-    m_buttonDown = button != (unsigned short)-1;
+    m_buttonDown = button != -2;
     m_relatedTarget = relatedTarget;
 
     initCoordinates(IntPoint(clientX, clientY));
@@ -141,7 +141,7 @@
 
 // FIXME: We need this quirk because iAd Producer is calling this function with a relatedTarget that is not an EventTarget (rdar://problem/30640101).
 // We should remove this quirk when possible.
-void MouseEvent::initMouseEventQuirk(ExecState& state, ScriptExecutionContext& scriptExecutionContext, const AtomicString& type, bool canBubble, bool cancelable, RefPtr<WindowProxy>&& view, int detail, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, unsigned short button, JSValue relatedTargetValue)
+void MouseEvent::initMouseEventQuirk(ExecState& state, ScriptExecutionContext& scriptExecutionContext, const AtomicString& type, bool canBubble, bool cancelable, RefPtr<WindowProxy>&& view, int detail, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, short button, JSValue relatedTargetValue)
 {
     EventTarget* relatedTarget = nullptr;
 #if PLATFORM(MAC)

Modified: trunk/Source/WebCore/dom/MouseEvent.h (246102 => 246103)


--- trunk/Source/WebCore/dom/MouseEvent.h	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/Source/WebCore/dom/MouseEvent.h	2019-06-05 08:41:30 UTC (rev 246103)
@@ -40,13 +40,13 @@
 class MouseEvent : public MouseRelatedEvent {
 public:
     WEBCORE_EXPORT static Ref<MouseEvent> create(const AtomicString& type, CanBubble, IsCancelable, IsComposed, MonotonicTime timestamp, RefPtr<WindowProxy>&&, int detail,
-        const IntPoint& screenLocation, const IntPoint& windowLocation, const IntPoint& movementDelta, OptionSet<Modifier>, unsigned short button, unsigned short buttons,
+        const IntPoint& screenLocation, const IntPoint& windowLocation, const IntPoint& movementDelta, OptionSet<Modifier>, short button, unsigned short buttons,
         EventTarget* relatedTarget, double force, unsigned short syntheticClickType, DataTransfer* = nullptr, IsSimulated = IsSimulated::No, IsTrusted = IsTrusted::Yes);
 
     WEBCORE_EXPORT static Ref<MouseEvent> create(const AtomicString& eventType, RefPtr<WindowProxy>&&, const PlatformMouseEvent&, int detail, Node* relatedTarget);
 
     static Ref<MouseEvent> create(const AtomicString& eventType, CanBubble, IsCancelable, IsComposed, RefPtr<WindowProxy>&&, int detail,
-        int screenX, int screenY, int clientX, int clientY, OptionSet<Modifier>, unsigned short button, unsigned short buttons,
+        int screenX, int screenY, int clientX, int clientY, OptionSet<Modifier>, short button, unsigned short buttons,
         unsigned short syntheticClickType, EventTarget* relatedTarget);
 
     static Ref<MouseEvent> createForBindings() { return adoptRef(*new MouseEvent); }
@@ -61,13 +61,13 @@
 
     WEBCORE_EXPORT void initMouseEvent(const AtomicString& type, bool canBubble, bool cancelable, RefPtr<WindowProxy>&&,
         int detail, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
-        unsigned short button, EventTarget* relatedTarget);
+        short button, EventTarget* relatedTarget);
 
     void initMouseEventQuirk(JSC::ExecState&, ScriptExecutionContext&, const AtomicString& type, bool canBubble, bool cancelable, RefPtr<WindowProxy>&&,
         int detail, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
-        unsigned short button, JSC::JSValue relatedTarget);
+        short button, JSC::JSValue relatedTarget);
 
-    unsigned short button() const { return m_button; }
+    short button() const { return m_button; }
     unsigned short buttons() const { return m_buttons; }
     unsigned short syntheticClickType() const { return m_syntheticClickType; }
     bool buttonDown() const { return m_buttonDown; }
@@ -86,11 +86,11 @@
 
 protected:
     MouseEvent(const AtomicString& type, CanBubble, IsCancelable, IsComposed, MonotonicTime timestamp, RefPtr<WindowProxy>&&, int detail,
-        const IntPoint& screenLocation, const IntPoint& windowLocation, const IntPoint& movementDelta, OptionSet<Modifier>, unsigned short button, unsigned short buttons,
+        const IntPoint& screenLocation, const IntPoint& windowLocation, const IntPoint& movementDelta, OptionSet<Modifier>, short button, unsigned short buttons,
         EventTarget* relatedTarget, double force, unsigned short syntheticClickType, DataTransfer*, IsSimulated, IsTrusted);
 
     MouseEvent(const AtomicString& type, CanBubble, IsCancelable, IsComposed, RefPtr<WindowProxy>&&, int detail,
-        const IntPoint& screenLocation, const IntPoint& clientLocation, OptionSet<Modifier>, unsigned short button, unsigned short buttons,
+        const IntPoint& screenLocation, const IntPoint& clientLocation, OptionSet<Modifier>, short button, unsigned short buttons,
         unsigned short syntheticClickType, EventTarget* relatedTarget);
 
     MouseEvent(const AtomicString& type, const MouseEventInit&);
@@ -105,7 +105,7 @@
 
     void setRelatedTarget(EventTarget& relatedTarget) final { m_relatedTarget = &relatedTarget; }
 
-    unsigned short m_button { 0 };
+    short m_button { 0 };
     unsigned short m_buttons { 0 };
     unsigned short m_syntheticClickType { 0 };
     bool m_buttonDown { false };

Modified: trunk/Source/WebCore/dom/MouseEvent.idl (246102 => 246103)


--- trunk/Source/WebCore/dom/MouseEvent.idl	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/Source/WebCore/dom/MouseEvent.idl	2019-06-05 08:41:30 UTC (rev 246103)
@@ -32,7 +32,7 @@
     readonly attribute boolean shiftKey;
     readonly attribute boolean altKey;
     readonly attribute boolean metaKey;
-    readonly attribute unsigned short button;
+    readonly attribute short button;
     readonly attribute unsigned short buttons;
     readonly attribute EventTarget? relatedTarget;
 
@@ -49,7 +49,7 @@
         optional WindowProxy? view = null, optional long detail = 0,
         optional long screenX = 0, optional long screenY = 0, optional long clientX = 0, optional long clientY = 0,
         optional boolean ctrlKey = false, optional boolean altKey = false, optional boolean shiftKey = false, optional boolean metaKey = false,
-        optional unsigned short button = 0, optional any relatedTarget = null);
+        optional short button = 0, optional any relatedTarget = null);
 
     readonly attribute long offsetX;
     readonly attribute long offsetY;

Modified: trunk/Source/WebCore/dom/MouseEventInit.h (246102 => 246103)


--- trunk/Source/WebCore/dom/MouseEventInit.h	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/Source/WebCore/dom/MouseEventInit.h	2019-06-05 08:41:30 UTC (rev 246103)
@@ -32,7 +32,7 @@
 struct MouseEventInit : MouseRelatedEventInit {
     int clientX { 0 };
     int clientY { 0 };
-    unsigned short button { 0 };
+    short button { 0 };
     unsigned short buttons { 0 };
     RefPtr<EventTarget> relatedTarget;
 };

Modified: trunk/Source/WebCore/dom/MouseEventInit.idl (246102 => 246103)


--- trunk/Source/WebCore/dom/MouseEventInit.idl	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/Source/WebCore/dom/MouseEventInit.idl	2019-06-05 08:41:30 UTC (rev 246103)
@@ -28,7 +28,7 @@
     long screenY = 0;
     long clientX = 0;
     long clientY = 0;
-    unsigned short button = 0;
+    short button = 0;
     unsigned short buttons = 0;
 
     // FIXME: We need to support the following member.

Modified: trunk/Source/WebCore/dom/PointerEvent.cpp (246102 => 246103)


--- trunk/Source/WebCore/dom/PointerEvent.cpp	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/Source/WebCore/dom/PointerEvent.cpp	2019-06-05 08:41:30 UTC (rev 246103)
@@ -71,17 +71,22 @@
     return nullAtom();
 }
 
-RefPtr<PointerEvent> PointerEvent::create(const MouseEvent& mouseEvent)
+RefPtr<PointerEvent> PointerEvent::create(short button, const MouseEvent& mouseEvent)
 {
     auto type = pointerEventType(mouseEvent.type());
     if (type.isEmpty())
         return nullptr;
 
+    return create(type, button, mouseEvent);
+}
+
+Ref<PointerEvent> PointerEvent::create(const String& type, short button, const MouseEvent& mouseEvent)
+{
     auto isEnterOrLeave = type == eventNames().pointerenterEvent || type == eventNames().pointerleaveEvent;
     auto canBubble = isEnterOrLeave ? CanBubble::No : CanBubble::Yes;
     auto isCancelable = isEnterOrLeave ? IsCancelable::No : IsCancelable::Yes;
     auto isComposed = isEnterOrLeave ? IsComposed::No : IsComposed::Yes;
-    return adoptRef(*new PointerEvent(type, canBubble, isCancelable, isComposed, mouseEvent));
+    return adoptRef(*new PointerEvent(type, canBubble, isCancelable, isComposed, button, mouseEvent));
 }
 
 Ref<PointerEvent> PointerEvent::create(const String& type, PointerID pointerId, const String& pointerType, IsPrimary isPrimary)
@@ -106,8 +111,8 @@
 {
 }
 
-PointerEvent::PointerEvent(const AtomicString& type, CanBubble canBubble, IsCancelable isCancelable, IsComposed isComposed, const MouseEvent& mouseEvent)
-    : MouseEvent(type, canBubble, isCancelable, isComposed, mouseEvent.view(), mouseEvent.detail(), mouseEvent.screenLocation(), { mouseEvent.clientX(), mouseEvent.clientY() }, mouseEvent.modifierKeys(), mouseEvent.button(), mouseEvent.buttons(), mouseEvent.syntheticClickType(), mouseEvent.relatedTarget())
+PointerEvent::PointerEvent(const AtomicString& type, CanBubble canBubble, IsCancelable isCancelable, IsComposed isComposed, short button, const MouseEvent& mouseEvent)
+    : MouseEvent(type, canBubble, isCancelable, isComposed, mouseEvent.view(), mouseEvent.detail(), mouseEvent.screenLocation(), { mouseEvent.clientX(), mouseEvent.clientY() }, mouseEvent.modifierKeys(), button, mouseEvent.buttons(), mouseEvent.syntheticClickType(), mouseEvent.relatedTarget())
     , m_isPrimary(true)
 {
 }

Modified: trunk/Source/WebCore/dom/PointerEvent.h (246102 => 246103)


--- trunk/Source/WebCore/dom/PointerEvent.h	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/Source/WebCore/dom/PointerEvent.h	2019-06-05 08:41:30 UTC (rev 246103)
@@ -75,7 +75,8 @@
         return adoptRef(*new PointerEvent);
     }
 
-    static RefPtr<PointerEvent> create(const MouseEvent&);
+    static RefPtr<PointerEvent> create(short button, const MouseEvent&);
+    static Ref<PointerEvent> create(const String& type, short button, const MouseEvent&);
     static Ref<PointerEvent> create(const String& type, PointerID, const String& pointerType, IsPrimary = IsPrimary::No);
 
 #if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
@@ -115,7 +116,7 @@
 private:
     PointerEvent();
     PointerEvent(const AtomicString&, Init&&);
-    PointerEvent(const AtomicString& type, CanBubble, IsCancelable, IsComposed, const MouseEvent&);
+    PointerEvent(const AtomicString& type, CanBubble, IsCancelable, IsComposed, short button, const MouseEvent&);
     PointerEvent(const AtomicString& type, CanBubble, IsCancelable, IsComposed, PointerID, const String& pointerType, IsPrimary);
 #if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
     PointerEvent(const AtomicString& type, const PlatformTouchEvent&, IsCancelable isCancelable, unsigned touchIndex, bool isPrimary, Ref<WindowProxy>&&);

Modified: trunk/Source/WebCore/loader/NavigationAction.h (246102 => 246103)


--- trunk/Source/WebCore/loader/NavigationAction.h	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/Source/WebCore/loader/NavigationAction.h	2019-06-05 08:41:30 UTC (rev 246103)
@@ -94,7 +94,7 @@
 
         LayoutPoint absoluteLocation;
         FloatPoint locationInRootViewCoordinates;
-        unsigned short button;
+        short button;
         unsigned short syntheticClickType;
         bool buttonDown;
     };

Modified: trunk/Source/WebCore/page/PointerCaptureController.cpp (246102 => 246103)


--- trunk/Source/WebCore/page/PointerCaptureController.cpp	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/Source/WebCore/page/PointerCaptureController.cpp	2019-06-05 08:41:30 UTC (rev 246103)
@@ -231,6 +231,41 @@
 }
 #endif
 
+RefPtr<PointerEvent> PointerCaptureController::pointerEventForMouseEvent(const MouseEvent& mouseEvent)
+{
+    const auto& type = mouseEvent.type();
+    const auto& names = eventNames();
+
+    auto iterator = m_activePointerIdsToCapturingData.find(mousePointerID);
+    ASSERT(iterator != m_activePointerIdsToCapturingData.end());
+    auto& capturingData = iterator->value;
+
+    short newButton = mouseEvent.button();
+    short button = newButton == capturingData.previousMouseButton ? -1 : newButton;
+
+    // https://w3c.github.io/pointerevents/#chorded-button-interactions
+    // Some pointer devices, such as mouse or pen, support multiple buttons. In the Mouse Event model, each button
+    // press produces a mousedown and mouseup event. To better abstract this hardware difference and simplify
+    // cross-device input authoring, Pointer Events do not fire overlapping pointerdown and pointerup events
+    // for chorded button presses (depressing an additional button while another button on the pointer device is
+    // already depressed).
+    if (type == names.mousedownEvent || type == names.mouseupEvent) {
+        // We're already active and getting another mousedown, this means that we should dispatch
+        // a pointermove event and let the button state show the newly depressed button.
+        if (type == names.mousedownEvent && capturingData.pointerIsPressed)
+            return PointerEvent::create(names.pointermoveEvent, button, mouseEvent);
+
+        // We're active and the mouseup still has some pressed button, this means we should dispatch
+        // a pointermove event.
+        if (type == names.mouseupEvent && capturingData.pointerIsPressed && mouseEvent.buttons() > 0)
+            return PointerEvent::create(names.pointermoveEvent, button, mouseEvent);
+    }
+
+    capturingData.previousMouseButton = newButton;
+
+    return PointerEvent::create(button, mouseEvent);
+}
+
 void PointerCaptureController::dispatchEvent(PointerEvent& event, EventTarget* target)
 {
     auto iterator = m_activePointerIdsToCapturingData.find(event.pointerId());

Modified: trunk/Source/WebCore/page/PointerCaptureController.h (246102 => 246103)


--- trunk/Source/WebCore/page/PointerCaptureController.h	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/Source/WebCore/page/PointerCaptureController.h	2019-06-05 08:41:30 UTC (rev 246103)
@@ -49,6 +49,8 @@
     void pointerLockWasApplied();
     void elementWasRemoved(Element&);
 
+    RefPtr<PointerEvent> pointerEventForMouseEvent(const MouseEvent&);
+
 #if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
     void dispatchEventForTouchAtIndex(EventTarget&, const PlatformTouchEvent&, unsigned, bool isPrimary, WindowProxy&);
 #endif
@@ -68,6 +70,7 @@
         bool isPrimary { false };
         bool preventsCompatibilityMouseEvents { false };
         bool pointerIsPressed { false };
+        short previousMouseButton { -1 };
     };
 
     void pointerEventWillBeDispatched(const PointerEvent&, EventTarget*);

Modified: trunk/Source/WebCore/platform/PlatformMouseEvent.h (246102 => 246103)


--- trunk/Source/WebCore/platform/PlatformMouseEvent.h	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/Source/WebCore/platform/PlatformMouseEvent.h	2019-06-05 08:41:30 UTC (rev 246103)
@@ -42,7 +42,9 @@
 const double ForceAtForceClick = 2;
 
     // These button numbers match the ones used in the DOM API, 0 through 2, except for NoButton which isn't specified.
-    enum MouseButton : int8_t { NoButton = -1, LeftButton, MiddleButton, RightButton };
+    // We use -2 for NoButton because -1 is a valid value in the DOM API for Pointer Events for pointermove events that
+    // indicate that the pressed mouse button hasn't changed since the last event.
+    enum MouseButton : int8_t { LeftButton = 0, MiddleButton, RightButton, NoButton = -2 };
     enum SyntheticClickType : int8_t { NoTap, OneFingerTap, TwoFingerTap };
 
     class PlatformMouseEvent : public PlatformEvent {
@@ -136,15 +138,15 @@
 
 #if COMPILER(MSVC)
     // These functions are necessary to work around the fact that MSVC will not find a most-specific
-    // operator== to use after implicitly converting MouseButton to an unsigned short.
-    inline bool operator==(unsigned short a, MouseButton b)
+    // operator== to use after implicitly converting MouseButton to a short.
+    inline bool operator==(short a, MouseButton b)
     {
-        return a == static_cast<unsigned short>(b);
+        return a == static_cast<short>(b);
     }
 
-    inline bool operator!=(unsigned short a, MouseButton b)
+    inline bool operator!=(short a, MouseButton b)
     {
-        return a != static_cast<unsigned short>(b);
+        return a != static_cast<short>(b);
     }
 #endif
 

Modified: trunk/Source/WebKit/ChangeLog (246102 => 246103)


--- trunk/Source/WebKit/ChangeLog	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/Source/WebKit/ChangeLog	2019-06-05 08:41:30 UTC (rev 246103)
@@ -1,3 +1,15 @@
+2019-06-01  Antoine Quint  <[email protected]>
+
+        [Pointer Events] Add support for chorded button interactions
+        https://bugs.webkit.org/show_bug.cgi?id=198462
+
+        Reviewed by Dean Jackson.
+
+        Update to use -2 instead of -1 for NoButton.
+
+        * Shared/API/c/WKEvent.h:
+        * Shared/WebEvent.h:
+
 2019-06-05  Michael Catanzaro  <[email protected]>
 
         REGRESSION(r245796): [WPE][GTK] Web process crash on startup

Modified: trunk/Source/WebKit/Shared/API/c/WKEvent.h (246102 => 246103)


--- trunk/Source/WebKit/Shared/API/c/WKEvent.h	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/Source/WebKit/Shared/API/c/WKEvent.h	2019-06-05 08:41:30 UTC (rev 246103)
@@ -42,10 +42,10 @@
 typedef uint32_t WKEventModifiers;
 
 enum {
-    kWKEventMouseButtonNoButton = -1,
     kWKEventMouseButtonLeftButton = 0,
     kWKEventMouseButtonMiddleButton = 1,
     kWKEventMouseButtonRightButton = 2,
+    kWKEventMouseButtonNoButton = -2
 };
 typedef int32_t WKEventMouseButton;
 

Modified: trunk/Source/WebKit/Shared/WebEvent.h (246102 => 246103)


--- trunk/Source/WebKit/Shared/WebEvent.h	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/Source/WebKit/Shared/WebEvent.h	2019-06-05 08:41:30 UTC (rev 246103)
@@ -127,10 +127,10 @@
 class WebMouseEvent : public WebEvent {
 public:
     enum Button {
-        NoButton = -1,
-        LeftButton,
+        LeftButton = 0,
         MiddleButton,
-        RightButton
+        RightButton,
+        NoButton = -2
     };
 
     enum SyntheticClickType { NoTap, OneFingerTap, TwoFingerTap };

Modified: trunk/Source/WebKitLegacy/mac/ChangeLog (246102 => 246103)


--- trunk/Source/WebKitLegacy/mac/ChangeLog	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/Source/WebKitLegacy/mac/ChangeLog	2019-06-05 08:41:30 UTC (rev 246103)
@@ -1,3 +1,18 @@
+2019-06-01  Antoine Quint  <[email protected]>
+
+        [Pointer Events] Add support for chorded button interactions
+        https://bugs.webkit.org/show_bug.cgi?id=198462
+
+        Reviewed by Dean Jackson.
+
+        Update -[DOMMouseEvent button] to be a "short" and update the noButton value from -1 to -2.
+
+        * DOM/DOMMouseEvent.h:
+        * DOM/DOMMouseEvent.mm:
+        (-[DOMMouseEvent button]):
+        * WebView/WebPDFView.mm:
+        (-[WebPDFView PDFViewWillClickOnLink:withURL:]):
+
 2019-06-03  Rob Buis  <[email protected]>
 
         Implement imagesrcset and imagesizes attributes on link rel=preload

Modified: trunk/Source/WebKitLegacy/mac/DOM/DOMMouseEvent.h (246102 => 246103)


--- trunk/Source/WebKitLegacy/mac/DOM/DOMMouseEvent.h	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/Source/WebKitLegacy/mac/DOM/DOMMouseEvent.h	2019-06-05 08:41:30 UTC (rev 246103)
@@ -40,7 +40,7 @@
 @property (readonly) BOOL shiftKey;
 @property (readonly) BOOL altKey;
 @property (readonly) BOOL metaKey;
-@property (readonly) unsigned short button;
+@property (readonly) short button;
 @property (readonly, strong) id <DOMEventTarget> relatedTarget;
 @property (readonly) int offsetX WEBKIT_AVAILABLE_MAC(10_5);
 @property (readonly) int offsetY WEBKIT_AVAILABLE_MAC(10_5);

Modified: trunk/Source/WebKitLegacy/mac/DOM/DOMMouseEvent.mm (246102 => 246103)


--- trunk/Source/WebKitLegacy/mac/DOM/DOMMouseEvent.mm	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/Source/WebKitLegacy/mac/DOM/DOMMouseEvent.mm	2019-06-05 08:41:30 UTC (rev 246103)
@@ -92,7 +92,7 @@
     return IMPL->metaKey();
 }
 
-- (unsigned short)button
+- (short)button
 {
     WebCore::JSMainThreadNullState state;
     return IMPL->button();

Modified: trunk/Source/WebKitLegacy/mac/WebView/WebPDFView.mm (246102 => 246103)


--- trunk/Source/WebKitLegacy/mac/WebView/WebPDFView.mm	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/Source/WebKitLegacy/mac/WebView/WebPDFView.mm	2019-06-05 08:41:30 UTC (rev 246103)
@@ -960,7 +960,7 @@
 
     NSWindow *window = [sender window];
     NSEvent *nsEvent = [window currentEvent];
-    const int noButton = -1;
+    const int noButton = -2;
     int button = noButton;
     RefPtr<Event> event;
     switch ([nsEvent type]) {

Modified: trunk/Tools/ChangeLog (246102 => 246103)


--- trunk/Tools/ChangeLog	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/Tools/ChangeLog	2019-06-05 08:41:30 UTC (rev 246103)
@@ -1,3 +1,35 @@
+2019-06-01  Antoine Quint  <[email protected]>
+
+        [Pointer Events] Add support for chorded button interactions
+        https://bugs.webkit.org/show_bug.cgi?id=198462
+
+        Reviewed by Dean Jackson.
+
+        Until now, MouseEvent.buttons would always return 0 when used within DRT and WKTR as [NSEvent pressedMouseButtons], used
+        by PlatformMouseEventBuilder to set the m_buttons value eventually used to set MouseEvent.buttons, not account for the
+        NSEvent created through the eventSender JS object in tests. To fix this, we now track the pressed mouse buttons within
+        DRT and WKTR as mouseDown() and mouseUp() are called, and swizzle [NSEvent pressedMouseButtons] to return that value.
+
+        In the case of DRT, one test would fail when swizzling this method in the case where the target view for the event would
+        be the DRTMockScroller, a subclass of NSScroller. So we only swizzle when the target view is *not* an NSScroller or a
+        subclass.
+
+        Finally, we change the NoMouseButton enum value from -1 to -2 to adjust to MouseEvent.button now being a "short".
+
+        * DumpRenderTree/mac/EventSendingController.mm:
+        (swizzledEventPressedMouseButtons):
+        (-[EventSendingController mouseDown:withModifiers:]):
+        (-[EventSendingController mouseUp:withModifiers:]):
+        (-[EventSendingController mouseMoveToX:Y:]):
+        * TestWebKitAPI/Tests/mac/IsNavigationActionTrusted.mm:
+        * WebKitTestRunner/EventSenderProxy.h:
+        (WTR::EventSenderProxy::mouseButtonsCurrentlyDown const):
+        * WebKitTestRunner/mac/EventSenderProxy.mm:
+        (WTR::swizzledEventPressedMouseButtons):
+        (WTR::EventSenderProxy::mouseDown):
+        (WTR::EventSenderProxy::mouseUp):
+        (WTR::EventSenderProxy::mouseMoveTo):
+
 2019-06-04  Chris Dumez  <[email protected]>
 
         Cookies set via [WKHTTPCookieStore setCookie:] on store right after constructing WKWebView get lost

Modified: trunk/Tools/DumpRenderTree/mac/EventSendingController.mm (246102 => 246103)


--- trunk/Tools/DumpRenderTree/mac/EventSendingController.mm	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/Tools/DumpRenderTree/mac/EventSendingController.mm	2019-06-05 08:41:30 UTC (rev 246103)
@@ -32,6 +32,7 @@
 #import "config.h"
 #import "EventSendingController.h"
 
+#import "ClassMethodSwizzler.h"
 #import "DumpRenderTree.h"
 #import "DumpRenderTreeDraggingInfo.h"
 #import "DumpRenderTreeFileDraggingSource.h"
@@ -77,7 +78,7 @@
     LeftMouseButton = 0,
     MiddleMouseButton = 1,
     RightMouseButton = 2,
-    NoMouseButton = -1
+    NoMouseButton = -2
 };
 
 struct KeyMappingEntry {
@@ -93,8 +94,8 @@
 NSArray *webkitDomEventNames;
 NSMutableArray *savedMouseEvents; // mouse events sent between mouseDown and mouseUp are stored here, and then executed at once.
 BOOL replayingSavedEvents;
+unsigned mouseButtonsCurrentlyDown = 0;
 
-
 #if PLATFORM(IOS_FAMILY)
 @interface SyntheticTouch : NSObject {
 @public
@@ -561,8 +562,17 @@
     return flags;
 }
 
+#if !PLATFORM(IOS_FAMILY)
+static NSUInteger swizzledEventPressedMouseButtons()
+{
+    return mouseButtonsCurrentlyDown;
+}
+#endif
+
 - (void)mouseDown:(int)buttonNumber withModifiers:(WebScriptObject*)modifiers
 {
+    mouseButtonsCurrentlyDown |= (1 << buttonNumber);
+
     [[[mainFrame frameView] documentView] layout];
     [self updateClickCountForButton:buttonNumber];
     
@@ -588,8 +598,13 @@
 #if !PLATFORM(IOS_FAMILY)
         [NSApp _setCurrentEvent:event];
 #endif
-        [subView mouseDown:event];
+        {
 #if !PLATFORM(IOS_FAMILY)
+            auto eventPressedMouseButtonsSwizzler = ![subView isKindOfClass:[NSScroller class]] ? std::make_unique<ClassMethodSwizzler>([NSEvent class], @selector(pressedMouseButtons), reinterpret_cast<IMP>(swizzledEventPressedMouseButtons)) : NULL;
+#endif
+            [subView mouseDown:event];
+        }
+#if !PLATFORM(IOS_FAMILY)
         [NSApp _setCurrentEvent:nil];
 #endif
         if (buttonNumber == LeftMouseButton)
@@ -637,6 +652,8 @@
 
 - (void)mouseUp:(int)buttonNumber withModifiers:(WebScriptObject*)modifiers
 {
+    mouseButtonsCurrentlyDown &= ~(1 << buttonNumber);
+
     if (dragMode && !replayingSavedEvents) {
         NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[EventSendingController instanceMethodSignatureForSelector:@selector(mouseUp:withModifiers:)]];
         [invocation setTarget:self];
@@ -677,8 +694,13 @@
 #if !PLATFORM(IOS_FAMILY)
     [NSApp _setCurrentEvent:event];
 #endif
-    [targetView mouseUp:event];
+    {
 #if !PLATFORM(IOS_FAMILY)
+        auto eventPressedMouseButtonsSwizzler = ![targetView isKindOfClass:[NSScroller class]] ? std::make_unique<ClassMethodSwizzler>([NSEvent class], @selector(pressedMouseButtons), reinterpret_cast<IMP>(swizzledEventPressedMouseButtons)) : NULL;
+#endif
+        [targetView mouseUp:event];
+    }
+#if !PLATFORM(IOS_FAMILY)
     [NSApp _setCurrentEvent:nil];
 #endif
     if (buttonNumber == LeftMouseButton)
@@ -762,11 +784,19 @@
                 if ([[draggingInfo draggingSource] respondsToSelector:@selector(draggedImage:movedTo:)])
                     [[draggingInfo draggingSource] draggedImage:[draggingInfo draggedImage] movedTo:lastMousePosition];
                 [[mainFrame webView] draggingUpdated:draggingInfo];
-            } else
+            } else {
+#if !PLATFORM(IOS_FAMILY)
+                auto eventPressedMouseButtonsSwizzler = ![subView isKindOfClass:[NSScroller class]] ? std::make_unique<ClassMethodSwizzler>([NSEvent class], @selector(pressedMouseButtons), reinterpret_cast<IMP>(swizzledEventPressedMouseButtons)) : NULL;
+#endif
                 [subView mouseDragged:event];
+            }
 #endif
-        } else
+        } else {
+#if !PLATFORM(IOS_FAMILY)
+            auto eventPressedMouseButtonsSwizzler = ![subView isKindOfClass:[NSScroller class]] ? std::make_unique<ClassMethodSwizzler>([NSEvent class], @selector(pressedMouseButtons), reinterpret_cast<IMP>(swizzledEventPressedMouseButtons)) : NULL;
+#endif
             [subView mouseMoved:event];
+        }
 #if !PLATFORM(IOS_FAMILY)
         [NSApp _setCurrentEvent:nil];
 #endif

Modified: trunk/Tools/TestWebKitAPI/Tests/mac/IsNavigationActionTrusted.mm (246102 => 246103)


--- trunk/Tools/TestWebKitAPI/Tests/mac/IsNavigationActionTrusted.mm	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/Tools/TestWebKitAPI/Tests/mac/IsNavigationActionTrusted.mm	2019-06-05 08:41:30 UTC (rev 246103)
@@ -33,7 +33,7 @@
 static bool didFinishTest;
 const static NSURL *targetUrl = [[NSURL alloc] initWithString:@"http://www.example.com/"];
 const static unsigned expectedModifierFlags = 0;
-const static int expectedButtonNumber = -1;
+const static int expectedButtonNumber = -2;
 
 const static int expectedWKButtonNumber = 0; // unlike DOM spec, 0 is the value for no button in Cocoa.
 

Modified: trunk/Tools/WebKitTestRunner/EventSenderProxy.h (246102 => 246103)


--- trunk/Tools/WebKitTestRunner/EventSenderProxy.h	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/Tools/WebKitTestRunner/EventSenderProxy.h	2019-06-05 08:41:30 UTC (rev 246103)
@@ -76,6 +76,10 @@
 
     void keyDown(WKStringRef key, WKEventModifiers, unsigned location);
 
+#if PLATFORM(COCOA)
+    unsigned mouseButtonsCurrentlyDown() const { return m_mouseButtonsCurrentlyDown; }
+#endif
+
 #if ENABLE(TOUCH_EVENTS)
     // Touch events.
     void addTouchPoint(int x, int y);
@@ -137,6 +141,7 @@
     WKEventMouseButton m_clickButton;
 #if PLATFORM(COCOA)
     int eventNumber;
+    unsigned m_mouseButtonsCurrentlyDown { 0 };
 #elif PLATFORM(GTK)
     Deque<WTREventQueueItem> m_eventQueue;
     unsigned m_mouseButtonsCurrentlyDown { 0 };

Modified: trunk/Tools/WebKitTestRunner/mac/EventSenderProxy.mm (246102 => 246103)


--- trunk/Tools/WebKitTestRunner/mac/EventSenderProxy.mm	2019-06-05 07:56:07 UTC (rev 246102)
+++ trunk/Tools/WebKitTestRunner/mac/EventSenderProxy.mm	2019-06-05 08:41:30 UTC (rev 246103)
@@ -204,7 +204,7 @@
     LeftMouseButton = 0,
     MiddleMouseButton = 1,
     RightMouseButton = 2,
-    NoMouseButton = -1
+    NoMouseButton = -2
 };
 
 struct KeyMappingEntry {
@@ -301,8 +301,15 @@
     m_clickButton = button;
 }
 
+static NSUInteger swizzledEventPressedMouseButtons()
+{
+    return TestController::singleton().eventSenderProxy()->mouseButtonsCurrentlyDown();
+}
+
 void EventSenderProxy::mouseDown(unsigned buttonNumber, WKEventModifiers modifiers)
 {
+    m_mouseButtonsCurrentlyDown |= (1 << buttonNumber);
+
     updateClickCountForButton(buttonNumber);
 
     NSEventType eventType = eventTypeForMouseButtonAndAction(buttonNumber, MouseDown);
@@ -318,6 +325,7 @@
 
     NSView *targetView = [m_testController->mainWebView()->platformView() hitTest:[event locationInWindow]];
     if (targetView) {
+        auto eventPressedMouseButtonsSwizzler = std::make_unique<ClassMethodSwizzler>([NSEvent class], @selector(pressedMouseButtons), reinterpret_cast<IMP>(swizzledEventPressedMouseButtons));
         [NSApp _setCurrentEvent:event];
         [targetView mouseDown:event];
         [NSApp _setCurrentEvent:nil];
@@ -328,6 +336,8 @@
 
 void EventSenderProxy::mouseUp(unsigned buttonNumber, WKEventModifiers modifiers)
 {
+    m_mouseButtonsCurrentlyDown &= ~(1 << buttonNumber);
+
     NSEventType eventType = eventTypeForMouseButtonAndAction(buttonNumber, MouseUp);
     NSEvent *event = [NSEvent mouseEventWithType:eventType
                                         location:NSMakePoint(m_position.x, m_position.y)
@@ -347,6 +357,7 @@
         targetView = m_testController->mainWebView()->platformView();
 
     ASSERT(targetView);
+    auto eventPressedMouseButtonsSwizzler = std::make_unique<ClassMethodSwizzler>([NSEvent class], @selector(pressedMouseButtons), reinterpret_cast<IMP>(swizzledEventPressedMouseButtons));
     [NSApp _setCurrentEvent:event];
     [targetView mouseUp:event];
     [NSApp _setCurrentEvent:nil];
@@ -582,6 +593,7 @@
     // Always target drags at the WKWebView to allow for drag-scrolling outside the view.
     NSView *targetView = isDrag ? m_testController->mainWebView()->platformView() : [m_testController->mainWebView()->platformView() hitTest:windowLocation];
     if (targetView) {
+        auto eventPressedMouseButtonsSwizzler = std::make_unique<ClassMethodSwizzler>([NSEvent class], @selector(pressedMouseButtons), reinterpret_cast<IMP>(swizzledEventPressedMouseButtons));
         [NSApp _setCurrentEvent:event];
         if (isDrag)
             [targetView mouseDragged:event];
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to