Skip to content
Permalink
Browse files
Support Pointer Events on macOS
https://bugs.webkit.org/show_bug.cgi?id=195008
<rdar://problem/47454419>

Patch by Antoine Quint <graouts@apple.com> on 2019-02-27
Reviewed by Dean Jackson.

Source/JavaScriptCore:

* Configurations/FeatureDefines.xcconfig:

Source/WebCore:

We now dispatch relevant pointer events as we prepare to dispatch mouse events. In most cases, this means we dispatch
a pointer event of the same type, with "mouse" being substituted by "pointer", and with the same properties with the
exception that if preventDefault() is called for a "pointerdown" event, the matching "mousedown" will not be dispatched,
and the same behavior also extends to "pointerup".

Tests: pointerevents/mouse/over-enter-out-leave.html
       pointerevents/mouse/pointer-capture.html
       pointerevents/mouse/pointer-event-basic-properties.html
       pointerevents/mouse/pointer-events-before-mouse-events.html
       pointerevents/mouse/pointerdown-prevent-default.html

* Configurations/FeatureDefines.xcconfig:
* dom/Document.cpp: All of the touch-action related members and functions should be iOS-specific since the touch-action
property does not have any effect on macOS.
(WebCore::Document::invalidateRenderingDependentRegions):
(WebCore::Document::nodeWillBeRemoved):
(WebCore::Document::updateTouchActionElements):
* dom/Document.h:
* dom/Element.cpp:
(WebCore::Element::dispatchMouseEvent): Dispatch a pointer event matching the mouse event that is about to be dispatched.
If preventDefault() is called in the event handler for either "pointerdown" or "pointerup", do not proceed with dispatching
the mouse event.
* dom/PointerEvent.cpp:
(WebCore::pointerEventType):
(WebCore::PointerEvent::create):
* dom/PointerEvent.h:
* page/EventHandler.cpp: Check both the pointer and mouse events to see if we need to dispatch "enter" and "leave" events.
(WebCore::hierarchyHasCapturingEventListeners):
(WebCore::EventHandler::updateMouseEventTargetNode):
* page/PointerCaptureController.cpp: Fix a build error which only happened on macOS.
(WebCore::PointerCaptureController::PointerCaptureController): Create the CapturingData for the unique mouse pointer.
(WebCore::PointerCaptureController::hasPointerCapture): The code did not match the spec cited in the comment, only the
pending target override needs to be considered to determine whether a given element has pointer capture enabled.
(WebCore::PointerCaptureController::dispatchEvent): Dispatch the provided pointer event, accounting for pointer capture if
it is set.
* page/PointerLockController.cpp: Fix a build error which only happened on macOS.
* style/StyleTreeResolver.cpp:
(WebCore::Style::TreeResolver::resolveElement): Code related to touch-action is only relevant to iOS.

Source/WebCore/PAL:

* Configurations/FeatureDefines.xcconfig:

Source/WebKit:

* Configurations/FeatureDefines.xcconfig:

Source/WebKitLegacy/mac:

Add a WebKitLegacy API to enable and disable the Pointer Events runtime feature.

* Configurations/FeatureDefines.xcconfig:
* WebView/WebPreferenceKeysPrivate.h:
* WebView/WebPreferences.mm:
(+[WebPreferences initialize]):
(-[WebPreferences pointerEventsEnabled]):
(-[WebPreferences setPointerEventsEnabled:]):
* WebView/WebPreferencesPrivate.h:
* WebView/WebView.mm:
(-[WebView _preferencesChanged:]):

Tools:

* DumpRenderTree/mac/DumpRenderTree.mm:
(enableExperimentalFeatures): Enable the PointerEvents runtime feature in DumpRenderTree such that tests targeting WK1 may test the Pointer Events feature.
* TestWebKitAPI/Configurations/FeatureDefines.xcconfig:

LayoutTests:

* platform/mac-wk1/TestExpectations: Mark select tests as failures due to webkit.org/b/195008.
* platform/mac/TestExpectations: Enable the new mouse-based tests.
* pointerevents/mouse/over-enter-out-leave-expected.txt: Added.
* pointerevents/mouse/over-enter-out-leave.html: Added.
* pointerevents/mouse/pointer-capture-expected.txt: Added.
* pointerevents/mouse/pointer-capture.html: Added.
* pointerevents/mouse/pointer-event-basic-properties-expected.txt: Added.
* pointerevents/mouse/pointer-event-basic-properties.html: Added.
* pointerevents/mouse/pointer-events-before-mouse-events-expected.txt: Added.
* pointerevents/mouse/pointer-events-before-mouse-events.html: Added.
* pointerevents/mouse/pointerdown-prevent-default-expected.txt: Added.
* pointerevents/mouse/pointerdown-prevent-default.html: Added.
* pointerevents/utils.js:
(prototype.clear):

Canonical link: https://commits.webkit.org/209453@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242137 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
graouts authored and webkit-commit-queue committed Feb 27, 2019
1 parent 560d978 commit 8d0069b644e77635e68d0354377bb27a7a7fba04
Showing 40 changed files with 535 additions and 23 deletions.
@@ -1,3 +1,26 @@
2019-02-27 Antoine Quint <graouts@apple.com>

Support Pointer Events on macOS
https://bugs.webkit.org/show_bug.cgi?id=195008
<rdar://problem/47454419>

Reviewed by Dean Jackson.

* platform/mac-wk1/TestExpectations: Mark select tests as failures due to webkit.org/b/195008.
* platform/mac/TestExpectations: Enable the new mouse-based tests.
* pointerevents/mouse/over-enter-out-leave-expected.txt: Added.
* pointerevents/mouse/over-enter-out-leave.html: Added.
* pointerevents/mouse/pointer-capture-expected.txt: Added.
* pointerevents/mouse/pointer-capture.html: Added.
* pointerevents/mouse/pointer-event-basic-properties-expected.txt: Added.
* pointerevents/mouse/pointer-event-basic-properties.html: Added.
* pointerevents/mouse/pointer-events-before-mouse-events-expected.txt: Added.
* pointerevents/mouse/pointer-events-before-mouse-events.html: Added.
* pointerevents/mouse/pointerdown-prevent-default-expected.txt: Added.
* pointerevents/mouse/pointerdown-prevent-default.html: Added.
* pointerevents/utils.js:
(prototype.clear):

2019-02-27 Simon Fraser <simon.fraser@apple.com>

scrolling/ios/hit-testing-iframe* tests need to hide the tap highlight
@@ -672,4 +672,8 @@ webkit.org/b/190627 [ Mojave+ ] compositing/masks/compositing-clip-path-change-

webkit.org/b/172384 fast/hidpi/hidpi-long-page-with-inset-element.html [ Skip ]

webkit.org/b/194309 media/modern-media-controls/compact-media-controls/compact-media-controls-layout.html [ Pass Failure ]
webkit.org/b/194309 media/modern-media-controls/compact-media-controls/compact-media-controls-layout.html [ Pass Failure ]

webkit.org/b/195098 pointerevents/mouse/over-enter-out-leave.html [ Failure ]
webkit.org/b/195098 pointerevents/mouse/pointer-capture.html [ Failure ]
webkit.org/b/195098 pointerevents/mouse/pointer-events-before-mouse-events.html [ Failure ]
@@ -39,6 +39,8 @@ http/tests/gzip-content-encoding [ Pass ]
fast/text/mac [ Pass ]
webkit.org/b/181964 fast/text/mac/select-character-before-zero-width-joiner.html [ ImageOnlyFailure ]

pointerevents/mouse [ Pass ]

#//////////////////////////////////////////////////////////////////////////////////////////
# End platform-specific directories.
#//////////////////////////////////////////////////////////////////////////////////////////
@@ -0,0 +1,3 @@

PASS Testing that "pointerover" and "pointerenter" are dispatched when entering an element's bounds and that "pointerout" and "pointerleave" are dispatched when leaving an element's bounds.

@@ -0,0 +1,32 @@
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../utils.js"></script>
<script>

'use strict';

target_test({ x: "100px", y: "100px", width: "100px", height: "100px" }, (target, test) => {
const eventTracker = new EventTracker(target, ["pointerover", "pointerenter", "pointerout", "pointerleave"]);

eventSender.mouseMoveTo(50, 50);
eventSender.mouseMoveTo(150, 150);
eventSender.mouseMoveTo(250, 250);

eventTracker.assertMatchesEvents([
{ type: "pointerover", x: 150, y: 150, isPrimary: true },
{ type: "pointerenter", x: 150, y: 150, isPrimary: true },
{ type: "pointerout", x: 250, y: 250, isPrimary: true },
{ type: "pointerleave", x: 250, y: 250, isPrimary: true },
]);
test.done();
}, `Testing that "pointerover" and "pointerenter" are dispatched when entering an element's bounds and that "pointerout" and "pointerleave" are dispatched when leaving an element's bounds.`);

</script>
</body>
</html>
@@ -0,0 +1,3 @@

PASS Testing that setting pointer capture on an element dispatches pointermove events to that element even when the pointer is outside of its bounds.

@@ -0,0 +1,73 @@
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../utils.js"></script>
<script>

'use strict';

target_test({ x: "100px", y: "100px", width: "100px", height: "100px" }, (target, test) => {
const eventTracker = new EventTracker(target, ["pointermove", "gotpointercapture", "lostpointercapture"]);

// Start with the mouse outside of the target.
eventSender.mouseMoveTo(50, 50);

// Move it over the target, this yields a "pointermove" event.
eventSender.mouseMoveTo(150, 150);
eventTracker.assertMatchesEvents([
{ type: "pointermove", x: 150, y: 150 }
]);
eventTracker.clear();

// Press the mouse and move it outside the target and release it, this does not yield a "pointermove" event since there is no capture.
eventSender.mouseDown();
eventSender.mouseMoveTo(250, 250);
eventSender.mouseUp();

// Now, move the mouse over the target again.
eventSender.mouseMoveTo(150, 150);
eventTracker.assertMatchesEvents([
{ type: "pointermove", x: 150, y: 150 }
]);
eventTracker.clear();

// And press the mouse button again, but set the capture while handling the "pointerdown" event.
let pointerId;
target.addEventListener("pointerdown", event => {
pointerId = event.pointerId;
assert_false(target.hasPointerCapture(pointerId), "The target does not have pointer capture by default.");
target.setPointerCapture(pointerId);
assert_true(target.hasPointerCapture(pointerId), "The target has pointer capture after calling setPointerCapture().");
});
eventSender.mouseDown();
eventTracker.assertMatchesEvents([
{ type: "gotpointercapture" }
]);
eventTracker.clear();

// Move the mouse oustide the target again, this time this yields a "pointermove" event since the target has pointer capture.
eventSender.mouseMoveTo(250, 250);
eventTracker.assertMatchesEvents([
{ type: "pointermove", x: 250, y: 250 }
]);
eventTracker.clear();

// Finally, release capture and mouse the mouse again, this should not yield a "pointermove" event.
target.releasePointerCapture(pointerId);
assert_false(target.hasPointerCapture(pointerId), "The target no longer has pointer capture after calling releasePointerCapture().");
eventSender.mouseMoveTo(240, 240);
eventTracker.assertMatchesEvents([
{ type: "lostpointercapture" }
]);

test.done();
}, `Testing that setting pointer capture on an element dispatches pointermove events to that element even when the pointer is outside of its bounds.`);

</script>
</body>
</html>
@@ -0,0 +1,3 @@

PASS Testing the basic properties of a pointer event triggered by a mouse.

@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../utils.js"></script>
<script>

'use strict';

target_test((target, test) => {
eventSender.mouseMoveTo(50, 50);
eventSender.mouseDown();

target.addEventListener("pointerdown", event => {
assert_equals(event.pointerId, 1, "The pointer's identifier is 1.");
assert_equals(event.pointerType, "mouse", "The pointer type is 'mouse'.");
assert_true(event.isPrimary, "The pointer is the primary pointer.");
});

test.done();
}, `Testing the basic properties of a pointer event triggered by a mouse.`);

</script>
</body>
</html>
@@ -0,0 +1,3 @@

PASS Testing that pointer events are dispatched prior to compatibility mouse events.

@@ -0,0 +1,59 @@
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../utils.js"></script>
<script>

'use strict';

target_test({ x: "100px", y: "100px", width: "100px", height: "100px" }, (target, test) => {
const eventTracker = new EventTracker(target, ["pointerover", "pointerenter", "pointermove", "pointerdown", "pointerup", "pointerout", "pointerleave",
"mouseover", "mouseenter", "mousemove", "mousedown", "mouseup", "mouseout", "mouseleave", "click"]);
// Start outside of the target.
eventSender.mouseMoveTo(50, 50);

// Move the cursor over the target.
eventSender.mouseMoveTo(150, 150);
eventTracker.assertMatchesEvents([
{ type: "pointerover", x: 150, y: 150 },
{ type: "mouseover", x: 150, y: 150 },
{ type: "pointerenter", x: 150, y: 150 },
{ type: "mouseenter", x: 150, y: 150 },
{ type: "pointermove", x: 150, y: 150 },
{ type: "mousemove", x: 150, y: 150 },
]);
eventTracker.clear();

// Click.
eventSender.mouseDown();
eventSender.mouseUp();
eventTracker.assertMatchesEvents([
{ type: "pointerdown", x: 150, y: 150 },
{ type: "mousedown", x: 150, y: 150 },
{ type: "pointerup", x: 150, y: 150 },
{ type: "mouseup", x: 150, y: 150 },
{ type: "click", x: 150, y: 150 },
]);
eventTracker.clear();

// Move the cursor outside the target.
eventSender.mouseMoveTo(250, 250);
eventTracker.assertMatchesEvents([
{ type: "pointerout", x: 250, y: 250 },
{ type: "mouseout", x: 250, y: 250 },
{ type: "pointerleave", x: 250, y: 250 },
{ type: "mouseleave", x: 250, y: 250 },
]);
eventTracker.clear();

test.done();
}, `Testing that pointer events are dispatched prior to compatibility mouse events.`);

</script>
</body>
</html>
@@ -0,0 +1,3 @@

PASS Testing that calling preventDefault() when handling a "pointerdown" event does not dispatch a "mousedown" event.

@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../utils.js"></script>
<script>

'use strict';

target_test((target, test) => {
const eventTracker = new EventTracker(target, ["pointerdown", "mousedown"]);

// Press the mouse once without calling preventDefault().
eventSender.mouseMoveTo(50, 50);
eventSender.mouseDown();
eventSender.mouseUp();

// Press it again and call preventDefault().
target.addEventListener("pointerdown", event => event.preventDefault());
eventSender.mouseMoveTo(50, 50);
eventSender.mouseDown();
eventSender.mouseUp();

eventTracker.assertMatchesEvents([
{ type: "pointerdown", x: 50, y: 50 },
{ type: "mousedown", x: 50, y: 50 },
{ type: "pointerdown", x: 50, y: 50 },
]);
test.done();
}, `Testing that calling preventDefault() when handling a "pointerdown" event does not dispatch a "mousedown" event.`);

</script>
</body>
</html>
@@ -44,6 +44,11 @@ class EventTracker
target.addEventListener(eventName, this);
}

clear()
{
this.events = [];
}

handleEvent(event)
{
if (event instanceof PointerEvent)
@@ -1,3 +1,13 @@
2019-02-27 Antoine Quint <graouts@apple.com>

Support Pointer Events on macOS
https://bugs.webkit.org/show_bug.cgi?id=195008
<rdar://problem/47454419>

Reviewed by Dean Jackson.

* Configurations/FeatureDefines.xcconfig:

2019-02-26 Mark Lam <mark.lam@apple.com>

Remove poisons in JSCPoison and uses of them.
@@ -305,6 +305,7 @@ ENABLE_POINTER_EVENTS = $(ENABLE_POINTER_EVENTS_$(WK_PLATFORM_NAME));
ENABLE_POINTER_EVENTS_iosmac = ENABLE_POINTER_EVENTS;
ENABLE_POINTER_EVENTS_iphoneos = ENABLE_POINTER_EVENTS;
ENABLE_POINTER_EVENTS_iphonesimulator = ENABLE_POINTER_EVENTS;
ENABLE_POINTER_EVENTS_macosx = ENABLE_POINTER_EVENTS;

ENABLE_POINTER_LOCK = $(ENABLE_POINTER_LOCK_$(WK_PLATFORM_NAME));
ENABLE_POINTER_LOCK_macosx = ENABLE_POINTER_LOCK;
@@ -1,3 +1,50 @@
2019-02-27 Antoine Quint <graouts@apple.com>

Support Pointer Events on macOS
https://bugs.webkit.org/show_bug.cgi?id=195008
<rdar://problem/47454419>

Reviewed by Dean Jackson.

We now dispatch relevant pointer events as we prepare to dispatch mouse events. In most cases, this means we dispatch
a pointer event of the same type, with "mouse" being substituted by "pointer", and with the same properties with the
exception that if preventDefault() is called for a "pointerdown" event, the matching "mousedown" will not be dispatched,
and the same behavior also extends to "pointerup".

Tests: pointerevents/mouse/over-enter-out-leave.html
pointerevents/mouse/pointer-capture.html
pointerevents/mouse/pointer-event-basic-properties.html
pointerevents/mouse/pointer-events-before-mouse-events.html
pointerevents/mouse/pointerdown-prevent-default.html

* Configurations/FeatureDefines.xcconfig:
* dom/Document.cpp: All of the touch-action related members and functions should be iOS-specific since the touch-action
property does not have any effect on macOS.
(WebCore::Document::invalidateRenderingDependentRegions):
(WebCore::Document::nodeWillBeRemoved):
(WebCore::Document::updateTouchActionElements):
* dom/Document.h:
* dom/Element.cpp:
(WebCore::Element::dispatchMouseEvent): Dispatch a pointer event matching the mouse event that is about to be dispatched.
If preventDefault() is called in the event handler for either "pointerdown" or "pointerup", do not proceed with dispatching
the mouse event.
* dom/PointerEvent.cpp:
(WebCore::pointerEventType):
(WebCore::PointerEvent::create):
* dom/PointerEvent.h:
* page/EventHandler.cpp: Check both the pointer and mouse events to see if we need to dispatch "enter" and "leave" events.
(WebCore::hierarchyHasCapturingEventListeners):
(WebCore::EventHandler::updateMouseEventTargetNode):
* page/PointerCaptureController.cpp: Fix a build error which only happened on macOS.
(WebCore::PointerCaptureController::PointerCaptureController): Create the CapturingData for the unique mouse pointer.
(WebCore::PointerCaptureController::hasPointerCapture): The code did not match the spec cited in the comment, only the
pending target override needs to be considered to determine whether a given element has pointer capture enabled.
(WebCore::PointerCaptureController::dispatchEvent): Dispatch the provided pointer event, accounting for pointer capture if
it is set.
* page/PointerLockController.cpp: Fix a build error which only happened on macOS.
* style/StyleTreeResolver.cpp:
(WebCore::Style::TreeResolver::resolveElement): Code related to touch-action is only relevant to iOS.

2019-02-27 Sihui Liu <sihui_liu@apple.com>

Network Process is put to suspended when holding locked IndexedDB files

0 comments on commit 8d0069b

Please sign in to comment.