WebKit Bugzilla
Attachment 371126 Details for
Bug 198462
: [Pointer Events] Add support for chorded button interactions
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-198462-20190602004238.patch (text/plain), 62.47 KB, created by
Antoine Quint
on 2019-06-01 15:42:40 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Antoine Quint
Created:
2019-06-01 15:42:40 PDT
Size:
62.47 KB
patch
obsolete
>Subversion Revision: 246017 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 203c57960c114b8fd1fe86a102687cf03d307e38..16a5071a9a03b242c0fcb20ae27739d5eaa6dacf 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,59 @@ >+2019-06-01 Antoine Quint <graouts@apple.com> >+ >+ [Pointer Events] Add support for chorded button interactions >+ https://bugs.webkit.org/show_bug.cgi?id=198462 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ 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-01 Simon Fraser <simon.fraser@apple.com> > > Non-composited negative z-order children should not trigger creation of a foreground layer >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index 0d9ca5ad48c2be6edd7a200a6aa61438f0eb433b..47d2f69acb41a3d431778e5513902552d1970a46 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,15 @@ >+2019-06-01 Antoine Quint <graouts@apple.com> >+ >+ [Pointer Events] Add support for chorded button interactions >+ https://bugs.webkit.org/show_bug.cgi?id=198462 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Update to use -2 instead of -1 for NoButton. >+ >+ * Shared/API/c/WKEvent.h: >+ * Shared/WebEvent.h: >+ > 2019-05-31 Megan Gardner <megan_gardner@apple.com> > > Ensure keyboard editing is up to date >diff --git a/Source/WebKitLegacy/mac/ChangeLog b/Source/WebKitLegacy/mac/ChangeLog >index c36a5f965cb416892025b33f666d08c1ec0e19ae..7f6145b63d2f40ec25291277fddeda15027f2f8a 100644 >--- a/Source/WebKitLegacy/mac/ChangeLog >+++ b/Source/WebKitLegacy/mac/ChangeLog >@@ -1,3 +1,18 @@ >+2019-06-01 Antoine Quint <graouts@apple.com> >+ >+ [Pointer Events] Add support for chorded button interactions >+ https://bugs.webkit.org/show_bug.cgi?id=198462 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ 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-01 Andy Estes <aestes@apple.com> > > [Apple Pay] Every PaymentCoordinator client should explicitly decide whether they support unrestricted Apple Pay >diff --git a/Source/WebCore/dom/Element.cpp b/Source/WebCore/dom/Element.cpp >index 385e2223e0f3efc06163985b9a07e12909aa25ab..b1090d93041457cd3a196e8931ca42a625c8ec50 100644 >--- a/Source/WebCore/dom/Element.cpp >+++ b/Source/WebCore/dom/Element.cpp >@@ -314,25 +314,24 @@ bool Element::dispatchMouseEvent(const PlatformMouseEvent& platformEvent, const > > #if ENABLE(POINTER_EVENTS) > if (RuntimeEnabledFeatures::sharedFeatures().pointerEventsEnabled()) { >-#if ENABLE(TOUCH_EVENTS) > if (auto* page = document().page()) { >- if (mouseEvent->type() != eventNames().clickEvent && page->pointerCaptureController().preventsCompatibilityMouseEventsForIdentifier(platformEvent.pointerId())) >+ auto& pointerCaptureController = page->pointerCaptureController(); >+#if ENABLE(TOUCH_EVENTS) >+ 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())) >- return false; >- } >- if (pointerEvent->defaultPrevented() || pointerEvent->defaultHandled()) { >- didNotSwallowEvent = false; >- if (pointerEvent->type() == eventNames().pointerdownEvent) >+ 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; >+ } > } >- } > #endif >+ } > } > #endif > >diff --git a/Source/WebCore/dom/MouseEvent.cpp b/Source/WebCore/dom/MouseEvent.cpp >index 2091a1a55db28a34a839dab9e2d55f24d7a76453..f2516f75ecdabf672025bb190904fdef247ab844 100644 >--- a/Source/WebCore/dom/MouseEvent.cpp >+++ b/Source/WebCore/dom/MouseEvent.cpp >@@ -62,7 +62,7 @@ Ref<MouseEvent> MouseEvent::create(const AtomicString& eventType, RefPtr<WindowP > } > > 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& type, CanBubble canBubble > } > > 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() = default; > > 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, IsCan > > 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, CanBubble canBubble, IsCan > > 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(const AtomicString& eventType, const MouseEventInit& init > 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 @@ void MouseEvent::initMouseEvent(const AtomicString& type, bool canBubble, bool c > > 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 @@ void MouseEvent::initMouseEvent(const AtomicString& type, bool canBubble, bool c > > // 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) >diff --git a/Source/WebCore/dom/MouseEvent.h b/Source/WebCore/dom/MouseEvent.h >index 719a41c7c634e13caaa41b9892213fbc275cd608..cf8200d72e3d813960c54939d932ad623e85ae5f 100644 >--- a/Source/WebCore/dom/MouseEvent.h >+++ b/Source/WebCore/dom/MouseEvent.h >@@ -40,13 +40,13 @@ class PlatformMouseEvent; > 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 @@ public: > > 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 @@ public: > > 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 @@ private: > > 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 }; >diff --git a/Source/WebCore/dom/MouseEvent.idl b/Source/WebCore/dom/MouseEvent.idl >index a56220bf0f050fbe57b4a204f1da21d7211fe755..7e63d217266917df1b8859a78452cbb9d79d8bd0 100644 >--- a/Source/WebCore/dom/MouseEvent.idl >+++ b/Source/WebCore/dom/MouseEvent.idl >@@ -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; >diff --git a/Source/WebCore/dom/MouseEventInit.h b/Source/WebCore/dom/MouseEventInit.h >index 19a5ead472dedca3b7e64f6673f2684b09895a2d..9fc4fed5156e1ccdf5784030c4af37e0ebb9c296 100644 >--- a/Source/WebCore/dom/MouseEventInit.h >+++ b/Source/WebCore/dom/MouseEventInit.h >@@ -32,7 +32,7 @@ namespace WebCore { > struct MouseEventInit : MouseRelatedEventInit { > int clientX { 0 }; > int clientY { 0 }; >- unsigned short button { 0 }; >+ short button { 0 }; > unsigned short buttons { 0 }; > RefPtr<EventTarget> relatedTarget; > }; >diff --git a/Source/WebCore/dom/MouseEventInit.idl b/Source/WebCore/dom/MouseEventInit.idl >index 6142760ace06e1679fb2e9889034edc83b6acb3d..1dcb732cdc9ee38c0aab6717cda33756db36055d 100644 >--- a/Source/WebCore/dom/MouseEventInit.idl >+++ b/Source/WebCore/dom/MouseEventInit.idl >@@ -28,7 +28,7 @@ dictionary MouseEventInit : EventModifierInit { > 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. >diff --git a/Source/WebCore/dom/PointerEvent.cpp b/Source/WebCore/dom/PointerEvent.cpp >index 7a18898958efed76dc6b029c24bb5e15512cf76a..93e37f034c77bdc387b8872d73bfb94cd218086d 100644 >--- a/Source/WebCore/dom/PointerEvent.cpp >+++ b/Source/WebCore/dom/PointerEvent.cpp >@@ -71,17 +71,22 @@ static AtomicString pointerEventType(const AtomicString& mouseEventType) > 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, Init&& initializer) > { > } > >-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) > { > } >diff --git a/Source/WebCore/dom/PointerEvent.h b/Source/WebCore/dom/PointerEvent.h >index 9b603b6f1095149675a86daeb76d4f858651b348..bc7c97ffdda7e09a42bae8ffab151e5907bb339f 100644 >--- a/Source/WebCore/dom/PointerEvent.h >+++ b/Source/WebCore/dom/PointerEvent.h >@@ -75,7 +75,8 @@ public: > 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 @@ public: > 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>&&); >diff --git a/Source/WebCore/loader/NavigationAction.h b/Source/WebCore/loader/NavigationAction.h >index ed7d09cf2892bb84df2f249b051475d8dc736791..4b611bf5be67ba7e01314639902fce79a84499ec 100644 >--- a/Source/WebCore/loader/NavigationAction.h >+++ b/Source/WebCore/loader/NavigationAction.h >@@ -94,7 +94,7 @@ public: > > LayoutPoint absoluteLocation; > FloatPoint locationInRootViewCoordinates; >- unsigned short button; >+ short button; > unsigned short syntheticClickType; > bool buttonDown; > }; >diff --git a/Source/WebCore/page/PointerCaptureController.cpp b/Source/WebCore/page/PointerCaptureController.cpp >index efa12a15d9bd7e19d2ae1841160a8694a0a66391..b4b3d808544aa36ffc98763332dc4733d1b05243 100644 >--- a/Source/WebCore/page/PointerCaptureController.cpp >+++ b/Source/WebCore/page/PointerCaptureController.cpp >@@ -220,6 +220,41 @@ void PointerCaptureController::dispatchEventForTouchAtIndex(EventTarget& target, > } > #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()); >diff --git a/Source/WebCore/page/PointerCaptureController.h b/Source/WebCore/page/PointerCaptureController.h >index 4311c46e13d20678d8361e7a06fea3904bb19fc3..3041e3a88d5a7851502506b314819466484efdd4 100644 >--- a/Source/WebCore/page/PointerCaptureController.h >+++ b/Source/WebCore/page/PointerCaptureController.h >@@ -49,6 +49,8 @@ public: > 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 @@ private: > bool isPrimary { false }; > bool preventsCompatibilityMouseEvents { false }; > bool pointerIsPressed { false }; >+ short previousMouseButton { -1 }; > }; > > void pointerEventWillBeDispatched(const PointerEvent&, EventTarget*); >diff --git a/Source/WebCore/platform/PlatformMouseEvent.h b/Source/WebCore/platform/PlatformMouseEvent.h >index 2aee4aade74d6939035b085013562fdc3789ec54..c6073f34b844d6c04c66126ac87602140e77d9dc 100644 >--- a/Source/WebCore/platform/PlatformMouseEvent.h >+++ b/Source/WebCore/platform/PlatformMouseEvent.h >@@ -42,7 +42,9 @@ const double ForceAtClick = 1; > 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 { >diff --git a/Source/WebKit/Shared/API/c/WKEvent.h b/Source/WebKit/Shared/API/c/WKEvent.h >index 477d554c96608c60fcaea87b59bea5a23edf48a4..f6f76fea16a7e06433d85469f998073c2f2ab92f 100644 >--- a/Source/WebKit/Shared/API/c/WKEvent.h >+++ b/Source/WebKit/Shared/API/c/WKEvent.h >@@ -42,10 +42,10 @@ enum { > typedef uint32_t WKEventModifiers; > > enum { >- kWKEventMouseButtonNoButton = -1, > kWKEventMouseButtonLeftButton = 0, > kWKEventMouseButtonMiddleButton = 1, > kWKEventMouseButtonRightButton = 2, >+ kWKEventMouseButtonNoButton = -2 > }; > typedef int32_t WKEventMouseButton; > >diff --git a/Source/WebKit/Shared/WebEvent.h b/Source/WebKit/Shared/WebEvent.h >index 28286f6cc62a991c95eb6f4ad43af6492032af9d..7e8b01865d18a89ce6576aba609bc687f3e5f6d7 100644 >--- a/Source/WebKit/Shared/WebEvent.h >+++ b/Source/WebKit/Shared/WebEvent.h >@@ -127,10 +127,10 @@ private: > class WebMouseEvent : public WebEvent { > public: > enum Button { >- NoButton = -1, >- LeftButton, >+ LeftButton = 0, > MiddleButton, >- RightButton >+ RightButton, >+ NoButton = -2 > }; > > enum SyntheticClickType { NoTap, OneFingerTap, TwoFingerTap }; >diff --git a/Source/WebKitLegacy/mac/DOM/DOMMouseEvent.h b/Source/WebKitLegacy/mac/DOM/DOMMouseEvent.h >index fefce48012ce3ba818d5a4b088d70d8c8bb2d976..ac6f45c9605bf0cc459ba05fe5dce431d0a17634 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMMouseEvent.h >+++ b/Source/WebKitLegacy/mac/DOM/DOMMouseEvent.h >@@ -40,7 +40,7 @@ WEBKIT_CLASS_DEPRECATED_MAC(10_4, 10_14) > @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); >diff --git a/Source/WebKitLegacy/mac/DOM/DOMMouseEvent.mm b/Source/WebKitLegacy/mac/DOM/DOMMouseEvent.mm >index 95f2235d4572fb396d624c39fc5069b3096dc39f..bf82345020f5bdd2fcccd3bb7eba9f850ceebcc7 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMMouseEvent.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMMouseEvent.mm >@@ -92,7 +92,7 @@ - (BOOL)metaKey > return IMPL->metaKey(); > } > >-- (unsigned short)button >+- (short)button > { > WebCore::JSMainThreadNullState state; > return IMPL->button(); >diff --git a/Source/WebKitLegacy/mac/WebView/WebPDFView.mm b/Source/WebKitLegacy/mac/WebView/WebPDFView.mm >index 786925ed1504b18fced18b5fa62b0f4041ce7a58..b5761f2390cb8f88322aff18fd90d70b673c02e4 100644 >--- a/Source/WebKitLegacy/mac/WebView/WebPDFView.mm >+++ b/Source/WebKitLegacy/mac/WebView/WebPDFView.mm >@@ -960,7 +960,7 @@ - (void)PDFViewWillClickOnLink:(PDFView *)sender withURL:(NSURL *)URL > > 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]) { >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index 288349033ceec728bdcd2b28d92272549e0c674c..431ef739e7e0f0f7a434d89b04acc8556b846372 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,34 @@ >+2019-06-01 Antoine Quint <graouts@apple.com> >+ >+ [Pointer Events] Add support for chorded button interactions >+ https://bugs.webkit.org/show_bug.cgi?id=198462 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ 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:]): >+ * WebKitTestRunner/EventSenderProxy.h: >+ (WTR::EventSenderProxy::mouseButtonsCurrentlyDown const): >+ * WebKitTestRunner/mac/EventSenderProxy.mm: >+ (WTR::swizzledEventPressedMouseButtons): >+ (WTR::EventSenderProxy::mouseDown): >+ (WTR::EventSenderProxy::mouseUp): >+ (WTR::EventSenderProxy::mouseMoveTo): >+ > 2019-05-31 Sihui Liu <sihui_liu@apple.com> > > TestWebKitAPI.WKWebView.LocalStorageProcessSuspends is flaky >diff --git a/Tools/DumpRenderTree/mac/EventSendingController.mm b/Tools/DumpRenderTree/mac/EventSendingController.mm >index 19fefadfabdb2547da3e4e68601dfb79660aa166..6a8647d246bacdd7cacf2e4385c45413467b9b15 100644 >--- a/Tools/DumpRenderTree/mac/EventSendingController.mm >+++ b/Tools/DumpRenderTree/mac/EventSendingController.mm >@@ -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 @@ enum MouseButton { > LeftMouseButton = 0, > MiddleMouseButton = 1, > RightMouseButton = 2, >- NoMouseButton = -1 >+ NoMouseButton = -2 > }; > > struct KeyMappingEntry { >@@ -93,7 +94,7 @@ int lastClickButton = NoMouseButton; > 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 { >@@ -561,8 +562,15 @@ static int buildModifierFlags(const WebScriptObject* modifiers) > return flags; > } > >+static NSUInteger swizzledEventPressedMouseButtons() >+{ >+ return mouseButtonsCurrentlyDown; >+} >+ > - (void)mouseDown:(int)buttonNumber withModifiers:(WebScriptObject*)modifiers > { >+ mouseButtonsCurrentlyDown |= (1 << buttonNumber); >+ > [[[mainFrame frameView] documentView] layout]; > [self updateClickCountForButton:buttonNumber]; > >@@ -588,7 +596,10 @@ - (void)mouseDown:(int)buttonNumber withModifiers:(WebScriptObject*)modifiers > #if !PLATFORM(IOS_FAMILY) > [NSApp _setCurrentEvent:event]; > #endif >- [subView mouseDown:event]; >+ { >+ auto eventPressedMouseButtonsSwizzler = ![subView isKindOfClass:[NSScroller class]] ? std::make_unique<ClassMethodSwizzler>([NSEvent class], @selector(pressedMouseButtons), reinterpret_cast<IMP>(swizzledEventPressedMouseButtons)) : NULL; >+ [subView mouseDown:event]; >+ } > #if !PLATFORM(IOS_FAMILY) > [NSApp _setCurrentEvent:nil]; > #endif >@@ -637,6 +648,8 @@ - (void)scalePageBy:(float)scale atX:(float)x andY:(float)y > > - (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,7 +690,10 @@ - (void)mouseUp:(int)buttonNumber withModifiers:(WebScriptObject*)modifiers > #if !PLATFORM(IOS_FAMILY) > [NSApp _setCurrentEvent:event]; > #endif >- [targetView mouseUp:event]; >+ { >+ auto eventPressedMouseButtonsSwizzler = ![targetView isKindOfClass:[NSScroller class]] ? std::make_unique<ClassMethodSwizzler>([NSEvent class], @selector(pressedMouseButtons), reinterpret_cast<IMP>(swizzledEventPressedMouseButtons)) : NULL; >+ [targetView mouseUp:event]; >+ } > #if !PLATFORM(IOS_FAMILY) > [NSApp _setCurrentEvent:nil]; > #endif >@@ -762,11 +778,15 @@ - (void)mouseMoveToX:(int)x Y:(int)y > if ([[draggingInfo draggingSource] respondsToSelector:@selector(draggedImage:movedTo:)]) > [[draggingInfo draggingSource] draggedImage:[draggingInfo draggedImage] movedTo:lastMousePosition]; > [[mainFrame webView] draggingUpdated:draggingInfo]; >- } else >+ } else { >+ auto eventPressedMouseButtonsSwizzler = ![subView isKindOfClass:[NSScroller class]] ? std::make_unique<ClassMethodSwizzler>([NSEvent class], @selector(pressedMouseButtons), reinterpret_cast<IMP>(swizzledEventPressedMouseButtons)) : NULL; > [subView mouseDragged:event]; >+ } > #endif >- } else >+ } else { >+ auto eventPressedMouseButtonsSwizzler = ![subView isKindOfClass:[NSScroller class]] ? std::make_unique<ClassMethodSwizzler>([NSEvent class], @selector(pressedMouseButtons), reinterpret_cast<IMP>(swizzledEventPressedMouseButtons)) : NULL; > [subView mouseMoved:event]; >+ } > #if !PLATFORM(IOS_FAMILY) > [NSApp _setCurrentEvent:nil]; > #endif >diff --git a/Tools/WebKitTestRunner/EventSenderProxy.h b/Tools/WebKitTestRunner/EventSenderProxy.h >index 0ea1b5bfb74902cc7f65460b8c4dba302ddc67a5..15322182699e0ea30754a0226c3a7b6295976d00 100644 >--- a/Tools/WebKitTestRunner/EventSenderProxy.h >+++ b/Tools/WebKitTestRunner/EventSenderProxy.h >@@ -76,6 +76,10 @@ public: > > 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 @@ private: > WKEventMouseButton m_clickButton; > #if PLATFORM(COCOA) > int eventNumber; >+ unsigned m_mouseButtonsCurrentlyDown { 0 }; > #elif PLATFORM(GTK) > Deque<WTREventQueueItem> m_eventQueue; > unsigned m_mouseButtonsCurrentlyDown { 0 }; >diff --git a/Tools/WebKitTestRunner/mac/EventSenderProxy.mm b/Tools/WebKitTestRunner/mac/EventSenderProxy.mm >index 75537f1d88466a4c3f1cc942399d7c6111310cc4..d1cfc6a3321e029c8ba8115f4a6d9207f8e7184f 100644 >--- a/Tools/WebKitTestRunner/mac/EventSenderProxy.mm >+++ b/Tools/WebKitTestRunner/mac/EventSenderProxy.mm >@@ -204,7 +204,7 @@ enum MouseButton { > LeftMouseButton = 0, > MiddleMouseButton = 1, > RightMouseButton = 2, >- NoMouseButton = -1 >+ NoMouseButton = -2 > }; > > struct KeyMappingEntry { >@@ -301,8 +301,15 @@ void EventSenderProxy::updateClickCountForButton(int button) > 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 @@ void EventSenderProxy::mouseDown(unsigned buttonNumber, WKEventModifiers modifie > > 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::mouseDown(unsigned buttonNumber, WKEventModifiers modifie > > 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 @@ void EventSenderProxy::mouseUp(unsigned buttonNumber, WKEventModifiers modifiers > 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 @@ void EventSenderProxy::mouseMoveTo(double x, double y) > // 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]; >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index dd7c0847f1f6d731c123680e35de466d5b238389..6bfd7aca8a066b7b305d1504c401693daf5837c0 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,24 @@ >+2019-06-01 Antoine Quint <graouts@apple.com> >+ >+ [Pointer Events] Add support for chorded button interactions >+ https://bugs.webkit.org/show_bug.cgi?id=198462 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ 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: >+ This test fails differently in WK1 and WK2 and will be addressed in a future patch. >+ > 2019-06-01 Simon Fraser <simon.fraser@apple.com> > > Non-composited negative z-order children should not trigger creation of a foreground layer >diff --git a/LayoutTests/imported/w3c/ChangeLog b/LayoutTests/imported/w3c/ChangeLog >index 9bc4229105c8c76c73951377639f653913759af3..1e6f898761d530e4daa3e74aa89b44c2897c61ab 100644 >--- a/LayoutTests/imported/w3c/ChangeLog >+++ b/LayoutTests/imported/w3c/ChangeLog >@@ -1,3 +1,21 @@ >+2019-06-01 Antoine Quint <graouts@apple.com> >+ >+ [Pointer Events] Add support for chorded button interactions >+ https://bugs.webkit.org/show_bug.cgi?id=198462 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ 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-05-31 Joonghun Park <jh718.park@samsung.com> > > Always min-width should win over max-width. >diff --git a/LayoutTests/fast/events/constructors/mouse-event-constructor-expected.txt b/LayoutTests/fast/events/constructors/mouse-event-constructor-expected.txt >index c93a54e94bffcb174d27f6856efc9804d73edd87..88be2e1d42199f1a34116c197d2223fb8da0b31c 100644 >--- a/LayoutTests/fast/events/constructors/mouse-event-constructor-expected.txt >+++ b/LayoutTests/fast/events/constructors/mouse-event-constructor-expected.txt >@@ -151,11 +151,13 @@ PASS new MouseEvent('eventType', { shiftKey: true }).shiftKey is true > 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 >diff --git a/LayoutTests/fast/events/constructors/mouse-event-constructor.html b/LayoutTests/fast/events/constructors/mouse-event-constructor.html >index bc1d3c856b6f1b937b50410645398b7a9224dc2a..ac2f245a6ccccf7acf400227e5d6922b4ee6f489 100644 >--- a/LayoutTests/fast/events/constructors/mouse-event-constructor.html >+++ b/LayoutTests/fast/events/constructors/mouse-event-constructor.html >@@ -100,15 +100,15 @@ shouldThrow("new MouseEvent('eventType', { get view() { throw 'MouseEvent Error' > }); > > // 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"); >- >-// 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"); >+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 out of the unsigned short range. > // 2^{64}-1 >diff --git a/LayoutTests/fast/events/constructors/wheel-event-constructor-expected.txt b/LayoutTests/fast/events/constructors/wheel-event-constructor-expected.txt >index 11c595bb310307fad5c56f17443849481486bca7..720f5e8d8cb424ef668bc995195ec793eac5481c 100644 >--- a/LayoutTests/fast/events/constructors/wheel-event-constructor-expected.txt >+++ b/LayoutTests/fast/events/constructors/wheel-event-constructor-expected.txt >@@ -221,11 +221,13 @@ PASS new WheelEvent('eventType', { shiftKey: true }).shiftKey is true > 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 >diff --git a/LayoutTests/fast/events/constructors/wheel-event-constructor.html b/LayoutTests/fast/events/constructors/wheel-event-constructor.html >index ac40f1abecfdaa686d9e8f353c1c40c8c6d97bc2..fa06b26103eeee7fd9a59facf595271f9c6d733a 100644 >--- a/LayoutTests/fast/events/constructors/wheel-event-constructor.html >+++ b/LayoutTests/fast/events/constructors/wheel-event-constructor.html >@@ -137,15 +137,15 @@ shouldBe("new WheelEvent('eventType', { deltaMode: {valueOf: function () { retur > }); > > // 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"); >- >-// 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"); >+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 out of the unsigned short range. > // 2^{64}-1 >diff --git a/LayoutTests/fast/events/fire-mousedown-while-pressing-mouse-button.html b/LayoutTests/fast/events/fire-mousedown-while-pressing-mouse-button.html >index 351c5aa66d8490c7c374755bec50b13e2985e7f6..17643fe639ce95f1e36c2b9a6aaab2abebc2a4c4 100644 >--- a/LayoutTests/fast/events/fire-mousedown-while-pressing-mouse-button.html >+++ b/LayoutTests/fast/events/fire-mousedown-while-pressing-mouse-button.html >@@ -47,15 +47,15 @@ window.onload = function() > 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 cancelContextMenu(event) > > 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) + "."); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt >index 801620b89c38138a648217870d18e962ba7255d4..295300e2e6cf9652b2c368a69019eb4e6a84a917 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt >@@ -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 > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_pointermove_on_chorded_mouse_button-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_pointermove_on_chorded_mouse_button-expected.txt >index 926b75ff40fe6e7ca159d3cd5f7e7a1d22f052e6..a9b9f0f999383edf4cf55686d349c3f85676f0f6 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_pointermove_on_chorded_mouse_button-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_pointermove_on_chorded_mouse_button-expected.txt >@@ -14,5 +14,5 @@ The following pointer types were detected: mouse. > 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 > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver-vendor.js b/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver-vendor.js >index c4bb28a43b514fd80f5730df8df290191930b8ab..dcbbf1fb68585c6bdd9ab987f17f3a1b32955182 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver-vendor.js >+++ b/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver-vendor.js >@@ -28,14 +28,12 @@ function dispatchMouseActions(actions) > 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}".`)); >diff --git a/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt b/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt >index c2848c8b3df83ce157a56af5d746e0bcf1fb99fa..3e54bf8dbb6b6a967ab879ab3a77a9c7348b5ade 100644 >--- a/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt >+++ b/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt >@@ -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 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 198462
:
371126
|
371132
|
371133
|
371134
|
371140
|
371144
|
371147
|
371155