haikuwebkit/Source/WebCore/page/PointerCaptureController.h

124 lines
4.6 KiB
C
Raw Permalink Normal View History

Implement capture for Pointer Events on iOS https://bugs.webkit.org/show_bug.cgi?id=193917 <rdar://problem/47605689> Reviewed by Dean Jackson. Source/WebCore: We add a new PointerCaptureController object which gets notified upon dispatch of pointer events to implement implicit pointer capture, dispatch the gotpointercapture and lostpointercaptiure events, and implement the Element APIs for pointer capture: hasPointerCapture(), setPointerCapture() and releasePointerCapture(). Tests: pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down.html pointerevents/ios/pointer-events-implicit-capture-release-exception.html pointerevents/ios/pointer-events-implicit-capture-release.html pointerevents/ios/pointer-events-implicit-capture.html pointerevents/ios/pointer-events-set-pointer-capture-exceptions.html * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * dom/Element.cpp: (WebCore::Element::setPointerCapture): (WebCore::Element::releasePointerCapture): (WebCore::Element::hasPointerCapture): * dom/Element.h: * dom/Element.idl: * dom/EventNames.h: * dom/PointerEvent.h: * page/Page.cpp: (WebCore::Page::Page): * page/Page.h: (WebCore::Page::pointerCaptureController const): * page/PointerCaptureController.cpp: Added. (WebCore::PointerCaptureController::PointerCaptureController): (WebCore::PointerCaptureController::setPointerCapture): (WebCore::PointerCaptureController::releasePointerCapture): (WebCore::PointerCaptureController::hasPointerCapture): (WebCore::PointerCaptureController::pointerLockWasApplied): (WebCore::PointerCaptureController::touchEndedOrWasCancelledForIdentifier): (WebCore::PointerCaptureController::pointerEventWillBeDispatched): (WebCore::PointerCaptureController::pointerEventWasDispatched): (WebCore::PointerCaptureController::processPendingPointerCapture): * page/PointerCaptureController.h: Added. * page/PointerLockController.cpp: (WebCore::PointerLockController::requestPointerLock): * page/PointerLockController.h: LayoutTests: New tests for implicit pointer capture and the Element APIs related to pointer capture. * pointerevents/ios/pointer-events-implicit-capture-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down.html: Added. * pointerevents/ios/pointer-events-implicit-capture-release-exception-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-release-exception.html: Added. * pointerevents/ios/pointer-events-implicit-capture-release-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-release.html: Added. * pointerevents/ios/pointer-events-implicit-capture.html: Added. * pointerevents/ios/pointer-events-set-pointer-capture-exceptions-expected.txt: Added. * pointerevents/ios/pointer-events-set-pointer-capture-exceptions.html: Added. Canonical link: https://commits.webkit.org/208432@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240634 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-29 03:15:02 +00:00
/*
* Copyright (C) 2019 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
IsLoggedIn: Add as experimental feature https://bugs.webkit.org/show_bug.cgi?id=202707 <rdar://problem/56095064> Reviewed by Brent Fulgham and Chris Dumez. IsLoggedIn was proposed to the WebAppSec WG at TPAC 2019. So far there is only an explainer posted to the mailing list: https://lists.w3.org/Archives/Public/public-webappsec/2019Sep/0004.html Source/WebCore: This patch adds the three experimental web APIs: - Promise<void> setLoggedIn() - Promise<void> setLoggedOut() - Promise<bool> isLoggedIn() It also tests that those APIs are only exposed in secure contexts. The functionality is implemented as a supplement to Navigator. Tests: http/tests/is-logged-in/available-in-secure-contexts.https.html http/tests/is-logged-in/unavailable-in-insecure-contexts.html * DerivedSources-input.xcfilelist: * DerivedSources-output.xcfilelist: * DerivedSources.make: * Headers.cmake: * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * page/NavigatorIsLoggedIn.cpp: Added. (WebCore::NavigatorIsLoggedIn::from): (WebCore::NavigatorIsLoggedIn::supplementName): (WebCore::NavigatorIsLoggedIn::setLoggedIn): (WebCore::NavigatorIsLoggedIn::setLoggedOut): (WebCore::NavigatorIsLoggedIn::isLoggedIn): * page/NavigatorIsLoggedIn.h: Added. * page/NavigatorIsLoggedIn.idl: Added. * page/PointerCaptureController.cpp: * page/PointerCaptureController.h: * page/Settings.yaml: Source/WebKit: * Shared/WebPreferences.yaml: LayoutTests: * http/tests/is-logged-in/available-in-secure-contexts.https-expected.txt: Added. * http/tests/is-logged-in/available-in-secure-contexts.https.html: Added. * http/tests/is-logged-in/unavailable-in-insecure-contexts-expected.txt: Added. * http/tests/is-logged-in/unavailable-in-insecure-contexts.html: Added. * platform/ios-device-wk1/TestExpectations: * platform/ios-simulator-wk1/TestExpectations: * platform/ios-wk1/TestExpectations: * platform/mac-highsierra/fast/dom/navigator-detached-no-crash-expected.txt: * platform/mac-wk1/TestExpectations: * platform/mac-wk2/fast/dom/navigator-detached-no-crash-expected.txt: * platform/wincairo-wk1/TestExpectations: Canonical link: https://commits.webkit.org/216235@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@250944 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-10 00:03:47 +00:00
#include "ExceptionOr.h"
#include "PointerID.h"
Implement capture for Pointer Events on iOS https://bugs.webkit.org/show_bug.cgi?id=193917 <rdar://problem/47605689> Reviewed by Dean Jackson. Source/WebCore: We add a new PointerCaptureController object which gets notified upon dispatch of pointer events to implement implicit pointer capture, dispatch the gotpointercapture and lostpointercaptiure events, and implement the Element APIs for pointer capture: hasPointerCapture(), setPointerCapture() and releasePointerCapture(). Tests: pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down.html pointerevents/ios/pointer-events-implicit-capture-release-exception.html pointerevents/ios/pointer-events-implicit-capture-release.html pointerevents/ios/pointer-events-implicit-capture.html pointerevents/ios/pointer-events-set-pointer-capture-exceptions.html * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * dom/Element.cpp: (WebCore::Element::setPointerCapture): (WebCore::Element::releasePointerCapture): (WebCore::Element::hasPointerCapture): * dom/Element.h: * dom/Element.idl: * dom/EventNames.h: * dom/PointerEvent.h: * page/Page.cpp: (WebCore::Page::Page): * page/Page.h: (WebCore::Page::pointerCaptureController const): * page/PointerCaptureController.cpp: Added. (WebCore::PointerCaptureController::PointerCaptureController): (WebCore::PointerCaptureController::setPointerCapture): (WebCore::PointerCaptureController::releasePointerCapture): (WebCore::PointerCaptureController::hasPointerCapture): (WebCore::PointerCaptureController::pointerLockWasApplied): (WebCore::PointerCaptureController::touchEndedOrWasCancelledForIdentifier): (WebCore::PointerCaptureController::pointerEventWillBeDispatched): (WebCore::PointerCaptureController::pointerEventWasDispatched): (WebCore::PointerCaptureController::processPendingPointerCapture): * page/PointerCaptureController.h: Added. * page/PointerLockController.cpp: (WebCore::PointerLockController::requestPointerLock): * page/PointerLockController.h: LayoutTests: New tests for implicit pointer capture and the Element APIs related to pointer capture. * pointerevents/ios/pointer-events-implicit-capture-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down.html: Added. * pointerevents/ios/pointer-events-implicit-capture-release-exception-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-release-exception.html: Added. * pointerevents/ios/pointer-events-implicit-capture-release-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-release.html: Added. * pointerevents/ios/pointer-events-implicit-capture.html: Added. * pointerevents/ios/pointer-events-set-pointer-capture-exceptions-expected.txt: Added. * pointerevents/ios/pointer-events-set-pointer-capture-exceptions.html: Added. Canonical link: https://commits.webkit.org/208432@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240634 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-29 03:15:02 +00:00
#include <wtf/HashMap.h>
namespace WebCore {
IsLoggedIn: Add as experimental feature https://bugs.webkit.org/show_bug.cgi?id=202707 <rdar://problem/56095064> Reviewed by Brent Fulgham and Chris Dumez. IsLoggedIn was proposed to the WebAppSec WG at TPAC 2019. So far there is only an explainer posted to the mailing list: https://lists.w3.org/Archives/Public/public-webappsec/2019Sep/0004.html Source/WebCore: This patch adds the three experimental web APIs: - Promise<void> setLoggedIn() - Promise<void> setLoggedOut() - Promise<bool> isLoggedIn() It also tests that those APIs are only exposed in secure contexts. The functionality is implemented as a supplement to Navigator. Tests: http/tests/is-logged-in/available-in-secure-contexts.https.html http/tests/is-logged-in/unavailable-in-insecure-contexts.html * DerivedSources-input.xcfilelist: * DerivedSources-output.xcfilelist: * DerivedSources.make: * Headers.cmake: * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * page/NavigatorIsLoggedIn.cpp: Added. (WebCore::NavigatorIsLoggedIn::from): (WebCore::NavigatorIsLoggedIn::supplementName): (WebCore::NavigatorIsLoggedIn::setLoggedIn): (WebCore::NavigatorIsLoggedIn::setLoggedOut): (WebCore::NavigatorIsLoggedIn::isLoggedIn): * page/NavigatorIsLoggedIn.h: Added. * page/NavigatorIsLoggedIn.idl: Added. * page/PointerCaptureController.cpp: * page/PointerCaptureController.h: * page/Settings.yaml: Source/WebKit: * Shared/WebPreferences.yaml: LayoutTests: * http/tests/is-logged-in/available-in-secure-contexts.https-expected.txt: Added. * http/tests/is-logged-in/available-in-secure-contexts.https.html: Added. * http/tests/is-logged-in/unavailable-in-insecure-contexts-expected.txt: Added. * http/tests/is-logged-in/unavailable-in-insecure-contexts.html: Added. * platform/ios-device-wk1/TestExpectations: * platform/ios-simulator-wk1/TestExpectations: * platform/ios-wk1/TestExpectations: * platform/mac-highsierra/fast/dom/navigator-detached-no-crash-expected.txt: * platform/mac-wk1/TestExpectations: * platform/mac-wk2/fast/dom/navigator-detached-no-crash-expected.txt: * platform/wincairo-wk1/TestExpectations: Canonical link: https://commits.webkit.org/216235@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@250944 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-10 00:03:47 +00:00
class Document;
Implement capture for Pointer Events on iOS https://bugs.webkit.org/show_bug.cgi?id=193917 <rdar://problem/47605689> Reviewed by Dean Jackson. Source/WebCore: We add a new PointerCaptureController object which gets notified upon dispatch of pointer events to implement implicit pointer capture, dispatch the gotpointercapture and lostpointercaptiure events, and implement the Element APIs for pointer capture: hasPointerCapture(), setPointerCapture() and releasePointerCapture(). Tests: pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down.html pointerevents/ios/pointer-events-implicit-capture-release-exception.html pointerevents/ios/pointer-events-implicit-capture-release.html pointerevents/ios/pointer-events-implicit-capture.html pointerevents/ios/pointer-events-set-pointer-capture-exceptions.html * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * dom/Element.cpp: (WebCore::Element::setPointerCapture): (WebCore::Element::releasePointerCapture): (WebCore::Element::hasPointerCapture): * dom/Element.h: * dom/Element.idl: * dom/EventNames.h: * dom/PointerEvent.h: * page/Page.cpp: (WebCore::Page::Page): * page/Page.h: (WebCore::Page::pointerCaptureController const): * page/PointerCaptureController.cpp: Added. (WebCore::PointerCaptureController::PointerCaptureController): (WebCore::PointerCaptureController::setPointerCapture): (WebCore::PointerCaptureController::releasePointerCapture): (WebCore::PointerCaptureController::hasPointerCapture): (WebCore::PointerCaptureController::pointerLockWasApplied): (WebCore::PointerCaptureController::touchEndedOrWasCancelledForIdentifier): (WebCore::PointerCaptureController::pointerEventWillBeDispatched): (WebCore::PointerCaptureController::pointerEventWasDispatched): (WebCore::PointerCaptureController::processPendingPointerCapture): * page/PointerCaptureController.h: Added. * page/PointerLockController.cpp: (WebCore::PointerLockController::requestPointerLock): * page/PointerLockController.h: LayoutTests: New tests for implicit pointer capture and the Element APIs related to pointer capture. * pointerevents/ios/pointer-events-implicit-capture-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down.html: Added. * pointerevents/ios/pointer-events-implicit-capture-release-exception-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-release-exception.html: Added. * pointerevents/ios/pointer-events-implicit-capture-release-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-release.html: Added. * pointerevents/ios/pointer-events-implicit-capture.html: Added. * pointerevents/ios/pointer-events-set-pointer-capture-exceptions-expected.txt: Added. * pointerevents/ios/pointer-events-set-pointer-capture-exceptions.html: Added. Canonical link: https://commits.webkit.org/208432@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240634 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-29 03:15:02 +00:00
class Element;
class EventTarget;
IsLoggedIn: Add as experimental feature https://bugs.webkit.org/show_bug.cgi?id=202707 <rdar://problem/56095064> Reviewed by Brent Fulgham and Chris Dumez. IsLoggedIn was proposed to the WebAppSec WG at TPAC 2019. So far there is only an explainer posted to the mailing list: https://lists.w3.org/Archives/Public/public-webappsec/2019Sep/0004.html Source/WebCore: This patch adds the three experimental web APIs: - Promise<void> setLoggedIn() - Promise<void> setLoggedOut() - Promise<bool> isLoggedIn() It also tests that those APIs are only exposed in secure contexts. The functionality is implemented as a supplement to Navigator. Tests: http/tests/is-logged-in/available-in-secure-contexts.https.html http/tests/is-logged-in/unavailable-in-insecure-contexts.html * DerivedSources-input.xcfilelist: * DerivedSources-output.xcfilelist: * DerivedSources.make: * Headers.cmake: * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * page/NavigatorIsLoggedIn.cpp: Added. (WebCore::NavigatorIsLoggedIn::from): (WebCore::NavigatorIsLoggedIn::supplementName): (WebCore::NavigatorIsLoggedIn::setLoggedIn): (WebCore::NavigatorIsLoggedIn::setLoggedOut): (WebCore::NavigatorIsLoggedIn::isLoggedIn): * page/NavigatorIsLoggedIn.h: Added. * page/NavigatorIsLoggedIn.idl: Added. * page/PointerCaptureController.cpp: * page/PointerCaptureController.h: * page/Settings.yaml: Source/WebKit: * Shared/WebPreferences.yaml: LayoutTests: * http/tests/is-logged-in/available-in-secure-contexts.https-expected.txt: Added. * http/tests/is-logged-in/available-in-secure-contexts.https.html: Added. * http/tests/is-logged-in/unavailable-in-insecure-contexts-expected.txt: Added. * http/tests/is-logged-in/unavailable-in-insecure-contexts.html: Added. * platform/ios-device-wk1/TestExpectations: * platform/ios-simulator-wk1/TestExpectations: * platform/ios-wk1/TestExpectations: * platform/mac-highsierra/fast/dom/navigator-detached-no-crash-expected.txt: * platform/mac-wk1/TestExpectations: * platform/mac-wk2/fast/dom/navigator-detached-no-crash-expected.txt: * platform/wincairo-wk1/TestExpectations: Canonical link: https://commits.webkit.org/216235@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@250944 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-10 00:03:47 +00:00
class IntPoint;
class MouseEvent;
class Page;
class PlatformTouchEvent;
Implement capture for Pointer Events on iOS https://bugs.webkit.org/show_bug.cgi?id=193917 <rdar://problem/47605689> Reviewed by Dean Jackson. Source/WebCore: We add a new PointerCaptureController object which gets notified upon dispatch of pointer events to implement implicit pointer capture, dispatch the gotpointercapture and lostpointercaptiure events, and implement the Element APIs for pointer capture: hasPointerCapture(), setPointerCapture() and releasePointerCapture(). Tests: pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down.html pointerevents/ios/pointer-events-implicit-capture-release-exception.html pointerevents/ios/pointer-events-implicit-capture-release.html pointerevents/ios/pointer-events-implicit-capture.html pointerevents/ios/pointer-events-set-pointer-capture-exceptions.html * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * dom/Element.cpp: (WebCore::Element::setPointerCapture): (WebCore::Element::releasePointerCapture): (WebCore::Element::hasPointerCapture): * dom/Element.h: * dom/Element.idl: * dom/EventNames.h: * dom/PointerEvent.h: * page/Page.cpp: (WebCore::Page::Page): * page/Page.h: (WebCore::Page::pointerCaptureController const): * page/PointerCaptureController.cpp: Added. (WebCore::PointerCaptureController::PointerCaptureController): (WebCore::PointerCaptureController::setPointerCapture): (WebCore::PointerCaptureController::releasePointerCapture): (WebCore::PointerCaptureController::hasPointerCapture): (WebCore::PointerCaptureController::pointerLockWasApplied): (WebCore::PointerCaptureController::touchEndedOrWasCancelledForIdentifier): (WebCore::PointerCaptureController::pointerEventWillBeDispatched): (WebCore::PointerCaptureController::pointerEventWasDispatched): (WebCore::PointerCaptureController::processPendingPointerCapture): * page/PointerCaptureController.h: Added. * page/PointerLockController.cpp: (WebCore::PointerLockController::requestPointerLock): * page/PointerLockController.h: LayoutTests: New tests for implicit pointer capture and the Element APIs related to pointer capture. * pointerevents/ios/pointer-events-implicit-capture-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down.html: Added. * pointerevents/ios/pointer-events-implicit-capture-release-exception-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-release-exception.html: Added. * pointerevents/ios/pointer-events-implicit-capture-release-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-release.html: Added. * pointerevents/ios/pointer-events-implicit-capture.html: Added. * pointerevents/ios/pointer-events-set-pointer-capture-exceptions-expected.txt: Added. * pointerevents/ios/pointer-events-set-pointer-capture-exceptions.html: Added. Canonical link: https://commits.webkit.org/208432@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240634 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-29 03:15:02 +00:00
class PointerEvent;
class WindowProxy;
Implement capture for Pointer Events on iOS https://bugs.webkit.org/show_bug.cgi?id=193917 <rdar://problem/47605689> Reviewed by Dean Jackson. Source/WebCore: We add a new PointerCaptureController object which gets notified upon dispatch of pointer events to implement implicit pointer capture, dispatch the gotpointercapture and lostpointercaptiure events, and implement the Element APIs for pointer capture: hasPointerCapture(), setPointerCapture() and releasePointerCapture(). Tests: pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down.html pointerevents/ios/pointer-events-implicit-capture-release-exception.html pointerevents/ios/pointer-events-implicit-capture-release.html pointerevents/ios/pointer-events-implicit-capture.html pointerevents/ios/pointer-events-set-pointer-capture-exceptions.html * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * dom/Element.cpp: (WebCore::Element::setPointerCapture): (WebCore::Element::releasePointerCapture): (WebCore::Element::hasPointerCapture): * dom/Element.h: * dom/Element.idl: * dom/EventNames.h: * dom/PointerEvent.h: * page/Page.cpp: (WebCore::Page::Page): * page/Page.h: (WebCore::Page::pointerCaptureController const): * page/PointerCaptureController.cpp: Added. (WebCore::PointerCaptureController::PointerCaptureController): (WebCore::PointerCaptureController::setPointerCapture): (WebCore::PointerCaptureController::releasePointerCapture): (WebCore::PointerCaptureController::hasPointerCapture): (WebCore::PointerCaptureController::pointerLockWasApplied): (WebCore::PointerCaptureController::touchEndedOrWasCancelledForIdentifier): (WebCore::PointerCaptureController::pointerEventWillBeDispatched): (WebCore::PointerCaptureController::pointerEventWasDispatched): (WebCore::PointerCaptureController::processPendingPointerCapture): * page/PointerCaptureController.h: Added. * page/PointerLockController.cpp: (WebCore::PointerLockController::requestPointerLock): * page/PointerLockController.h: LayoutTests: New tests for implicit pointer capture and the Element APIs related to pointer capture. * pointerevents/ios/pointer-events-implicit-capture-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down.html: Added. * pointerevents/ios/pointer-events-implicit-capture-release-exception-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-release-exception.html: Added. * pointerevents/ios/pointer-events-implicit-capture-release-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-release.html: Added. * pointerevents/ios/pointer-events-implicit-capture.html: Added. * pointerevents/ios/pointer-events-set-pointer-capture-exceptions-expected.txt: Added. * pointerevents/ios/pointer-events-set-pointer-capture-exceptions.html: Added. Canonical link: https://commits.webkit.org/208432@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240634 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-29 03:15:02 +00:00
class PointerCaptureController {
WTF_MAKE_NONCOPYABLE(PointerCaptureController);
WTF_MAKE_FAST_ALLOCATED;
public:
Dispatch pointercancel events when content is panned or zoomed on iOS https://bugs.webkit.org/show_bug.cgi?id=193962 <rdar://problem/47629134> Reviewed by Dean Jackson. Source/WebCore: Expose two new methods on PointerCaptureController so that, given a pointer id, it can be established whether this pointer has been cancelled, which is important because a cancelled pointer should no longer dispatch any further pointer events, and to cancel a pointer. Tests: pointerevents/ios/touch-action-pointercancel-pan-x.html pointerevents/ios/touch-action-pointercancel-pan-y.html pointerevents/ios/touch-action-pointercancel-pinch-zoom.html * WebCore.xcodeproj/project.pbxproj: Make PointerCaptureController.h Private so that it can be imported from WebKit. * dom/PointerEvent.h: Remove an unnecessary #if ENABLE(POINTER_EVENTS) since the entire file is already contained in one. Then we add a new create() method that takes an event type, a pointer id and a pointer type (touch vs. pen) that we use to create pointercancel events in PointerCaptureController::cancelPointer(). * page/Page.cpp: (WebCore::Page::Page): Pass the Page as a parameter when creating the PointerCaptureController. * page/PointerCaptureController.cpp: (WebCore::PointerCaptureController::PointerCaptureController): Add a Page reference to the constructor since we'll need the page to access its main frame's EventHandler to perform hit testing in case we do not have a capture target override in cancelPointer(). (WebCore::PointerCaptureController::releasePointerCapture): Drive-by, remove the the implicit parameter since on iOS we don't need to differentiate. We'll bring this back for the macOS work. (WebCore::PointerCaptureController::hasCancelledPointerEventForIdentifier): New method we'll use when dispatching pointer events to identify whether a pointer id has already been cancelled which will allow for _not_ dispatching any further pointer events for this pointer id. (WebCore::PointerCaptureController::pointerEventWillBeDispatched): Keep track of the pointer type so we can preserve it when dispatching pointercancel events for a given pointer id. (WebCore::PointerCaptureController::cancelPointer): Dispatch a pointercancel for the provided pointer id, using the capture target override as the event's target, if there is one, and otherwise hit-testing at the provided location to figure out what the target should be. * page/PointerCaptureController.h: Switch the target overrides from Element* to RefPtr<Element> to ensure it may not be deleted while we still need them. Existing code already ensures these get set to nullptr. Source/WebKit: When a user-agent-provided interaction, such as panning or zooming on iOS, uses a set of touches, we should dispatch a pointercancel event for the pointer ids of the touches involved. To facilitate this, we add a new method on WKContentView to cancel all the pointers matching active touches for a provided UIGestureRecognizer through an async IPC call into the Web process using the new method PointerCaptureController::cancelPointer(). * Platform/spi/ios/UIKitSPI.h: Add the necessary forward declaration for a necessary UIKit SPI allowing us to get the set of last-seen UITouches by the identifier generated for the matching WebKit touch. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView scrollViewWillBeginZooming:withView:]): Dispatch touchcancel events for all pointers involved in a pinch gesture on the top-level UIScrollView. (-[WKWebView _scrollView:adjustedOffsetForOffset:translation:startPoint:locationInView:horizontalVelocity:verticalVelocity:]): Dispatch touchcancel events for all pointers involved in a pan gesture on the top-level UIScrollView. We can infer this by looking at whether the adjusted content offset, after accounting for the permitted touch actions, is different from the original content offset. * UIProcess/PageClient.h: Expose a new virtual cancelPointersForGestureRecognizer() method which will allow the iOS implementation to forward the call to WKContentViewInteraction. (WebKit::PageClient::cancelPointersForGestureRecognizer): * UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h: Expose the WebPageProxy such that we may access it to cancel pointers for a given gesture recognizer from within ScrollingTreeScrollingNodeDelegateIOS. (WebKit::RemoteScrollingCoordinatorProxy::webPageProxy const): * UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.h: * UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm: (-[WKScrollingNodeScrollViewDelegate _scrollView:adjustedOffsetForOffset:translation:startPoint:locationInView:horizontalVelocity:verticalVelocity:]): Dispatch touchcancel events for all pointers involved in a pan gesture on a nested UIScrollView. We can infer this by looking at whether the adjusted content offset, after accounting for the permitted touch actions, is different from the original content offset. (-[WKScrollingNodeScrollViewDelegate scrollViewWillBeginZooming:withView:]): Dispatch touchcancel events for all pointers involved in a pinch gesture on a nested UIScrollView. (-[WKScrollingNodeScrollViewDelegate cancelPointersForGestureRecognizer:]): (WebKit::ScrollingTreeScrollingNodeDelegateIOS::cancelPointersForGestureRecognizer): * UIProcess/WebPageProxy.cpp: (WebKit::WebPageProxy::cancelPointer): * UIProcess/WebPageProxy.h: * UIProcess/ios/PageClientImplIOS.h: * UIProcess/ios/PageClientImplIOS.mm: (WebKit::PageClientImpl::cancelPointersForGestureRecognizer): * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView cancelPointersForGestureRecognizer:]): Obtain all active UITouch objects for the view and dispatch a pointercancel event, through the WebPageProxy, for all touches associated with the provided gesture recognizer. * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::cancelPointer): * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/WebPage.messages.in: LayoutTests: Adding a few tests for "pointercancel" and adding "touch-action: none" on tests that would now be affected by canceling pointers. We also unflake a few tests. * pointerevents/ios/pointer-events-implicit-capture.html: * pointerevents/ios/pointer-events-is-primary.html: * pointerevents/ios/touch-action-pan-x-pan-y.html: * pointerevents/ios/touch-action-pan-x.html: * pointerevents/ios/touch-action-pan-y-expected.txt: * pointerevents/ios/touch-action-pan-y.html: * pointerevents/ios/touch-action-pinch-zoom-allows-zooming.html: * pointerevents/ios/touch-action-pointercancel-pan-x-expected.txt: Added. * pointerevents/ios/touch-action-pointercancel-pan-x.html: Added. * pointerevents/ios/touch-action-pointercancel-pan-y-expected.txt: Added. * pointerevents/ios/touch-action-pointercancel-pan-y.html: Added. * pointerevents/ios/touch-action-pointercancel-pinch-zoom-expected.txt: Added. * pointerevents/ios/touch-action-pointercancel-pinch-zoom.html: Added. Canonical link: https://commits.webkit.org/208642@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240875 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-02-01 21:53:40 +00:00
explicit PointerCaptureController(Page&);
Implement capture for Pointer Events on iOS https://bugs.webkit.org/show_bug.cgi?id=193917 <rdar://problem/47605689> Reviewed by Dean Jackson. Source/WebCore: We add a new PointerCaptureController object which gets notified upon dispatch of pointer events to implement implicit pointer capture, dispatch the gotpointercapture and lostpointercaptiure events, and implement the Element APIs for pointer capture: hasPointerCapture(), setPointerCapture() and releasePointerCapture(). Tests: pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down.html pointerevents/ios/pointer-events-implicit-capture-release-exception.html pointerevents/ios/pointer-events-implicit-capture-release.html pointerevents/ios/pointer-events-implicit-capture.html pointerevents/ios/pointer-events-set-pointer-capture-exceptions.html * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * dom/Element.cpp: (WebCore::Element::setPointerCapture): (WebCore::Element::releasePointerCapture): (WebCore::Element::hasPointerCapture): * dom/Element.h: * dom/Element.idl: * dom/EventNames.h: * dom/PointerEvent.h: * page/Page.cpp: (WebCore::Page::Page): * page/Page.h: (WebCore::Page::pointerCaptureController const): * page/PointerCaptureController.cpp: Added. (WebCore::PointerCaptureController::PointerCaptureController): (WebCore::PointerCaptureController::setPointerCapture): (WebCore::PointerCaptureController::releasePointerCapture): (WebCore::PointerCaptureController::hasPointerCapture): (WebCore::PointerCaptureController::pointerLockWasApplied): (WebCore::PointerCaptureController::touchEndedOrWasCancelledForIdentifier): (WebCore::PointerCaptureController::pointerEventWillBeDispatched): (WebCore::PointerCaptureController::pointerEventWasDispatched): (WebCore::PointerCaptureController::processPendingPointerCapture): * page/PointerCaptureController.h: Added. * page/PointerLockController.cpp: (WebCore::PointerLockController::requestPointerLock): * page/PointerLockController.h: LayoutTests: New tests for implicit pointer capture and the Element APIs related to pointer capture. * pointerevents/ios/pointer-events-implicit-capture-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down.html: Added. * pointerevents/ios/pointer-events-implicit-capture-release-exception-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-release-exception.html: Added. * pointerevents/ios/pointer-events-implicit-capture-release-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-release.html: Added. * pointerevents/ios/pointer-events-implicit-capture.html: Added. * pointerevents/ios/pointer-events-set-pointer-capture-exceptions-expected.txt: Added. * pointerevents/ios/pointer-events-set-pointer-capture-exceptions.html: Added. Canonical link: https://commits.webkit.org/208432@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240634 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-29 03:15:02 +00:00
Optimize PointerCaptureController::elementWasRemoved() https://bugs.webkit.org/show_bug.cgi?id=221316 Reviewed by Ryosuke Niwa. Speedometer profiles show HashTable iteration code under PointerCaptureController::elementWasRemoved() because we always add a hash entry for the mouse pointer. Optimize away by setting a flag that's only true if any element is referenced by pointer capture. * page/PointerCaptureController.cpp: (WebCore::PointerCaptureController::pointerCaptureElement const): (WebCore::PointerCaptureController::setPointerCapture): (WebCore::PointerCaptureController::releasePointerCapture): (WebCore::PointerCaptureController::hasPointerCapture): (WebCore::PointerCaptureController::pointerLockWasApplied): (WebCore::PointerCaptureController::elementWasRemoved): (WebCore::PointerCaptureController::reset): (WebCore::PointerCaptureController::updateHaveAnyCapturingElement): (WebCore::PointerCaptureController::touchWithIdentifierWasRemoved): (WebCore::PointerCaptureController::hasCancelledPointerEventForIdentifier const): (WebCore::PointerCaptureController::preventsCompatibilityMouseEventsForIdentifier const): (WebCore::PointerCaptureController::pointerCaptureElement): Deleted. (WebCore::PointerCaptureController::hasCancelledPointerEventForIdentifier): Deleted. (WebCore::PointerCaptureController::preventsCompatibilityMouseEventsForIdentifier): Deleted. * page/PointerCaptureController.h: Canonical link: https://commits.webkit.org/233659@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@272331 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-02-03 18:41:16 +00:00
Element* pointerCaptureElement(Document*, PointerID) const;
ExceptionOr<void> setPointerCapture(Element*, PointerID);
ExceptionOr<void> releasePointerCapture(Element*, PointerID);
bool hasPointerCapture(Element*, PointerID);
void reset();
Implement capture for Pointer Events on iOS https://bugs.webkit.org/show_bug.cgi?id=193917 <rdar://problem/47605689> Reviewed by Dean Jackson. Source/WebCore: We add a new PointerCaptureController object which gets notified upon dispatch of pointer events to implement implicit pointer capture, dispatch the gotpointercapture and lostpointercaptiure events, and implement the Element APIs for pointer capture: hasPointerCapture(), setPointerCapture() and releasePointerCapture(). Tests: pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down.html pointerevents/ios/pointer-events-implicit-capture-release-exception.html pointerevents/ios/pointer-events-implicit-capture-release.html pointerevents/ios/pointer-events-implicit-capture.html pointerevents/ios/pointer-events-set-pointer-capture-exceptions.html * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * dom/Element.cpp: (WebCore::Element::setPointerCapture): (WebCore::Element::releasePointerCapture): (WebCore::Element::hasPointerCapture): * dom/Element.h: * dom/Element.idl: * dom/EventNames.h: * dom/PointerEvent.h: * page/Page.cpp: (WebCore::Page::Page): * page/Page.h: (WebCore::Page::pointerCaptureController const): * page/PointerCaptureController.cpp: Added. (WebCore::PointerCaptureController::PointerCaptureController): (WebCore::PointerCaptureController::setPointerCapture): (WebCore::PointerCaptureController::releasePointerCapture): (WebCore::PointerCaptureController::hasPointerCapture): (WebCore::PointerCaptureController::pointerLockWasApplied): (WebCore::PointerCaptureController::touchEndedOrWasCancelledForIdentifier): (WebCore::PointerCaptureController::pointerEventWillBeDispatched): (WebCore::PointerCaptureController::pointerEventWasDispatched): (WebCore::PointerCaptureController::processPendingPointerCapture): * page/PointerCaptureController.h: Added. * page/PointerLockController.cpp: (WebCore::PointerLockController::requestPointerLock): * page/PointerLockController.h: LayoutTests: New tests for implicit pointer capture and the Element APIs related to pointer capture. * pointerevents/ios/pointer-events-implicit-capture-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down.html: Added. * pointerevents/ios/pointer-events-implicit-capture-release-exception-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-release-exception.html: Added. * pointerevents/ios/pointer-events-implicit-capture-release-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-release.html: Added. * pointerevents/ios/pointer-events-implicit-capture.html: Added. * pointerevents/ios/pointer-events-set-pointer-capture-exceptions-expected.txt: Added. * pointerevents/ios/pointer-events-set-pointer-capture-exceptions.html: Added. Canonical link: https://commits.webkit.org/208432@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240634 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-29 03:15:02 +00:00
void pointerLockWasApplied();
[Pointer Events WPT] Unskip imported/w3c/web-platform-tests/pointerevents/pointerevent_lostpointercapture_for_disconnected_node.html https://bugs.webkit.org/show_bug.cgi?id=197004 Reviewed by Antti Koivisto. LayoutTests/imported/w3c: * web-platform-tests/pointerevents/pointerevent_lostpointercapture_for_disconnected_node-expected.txt: Added. Source/WebCore: We need to release pointer capture when an element that has pointer capture is disconnected from the DOM. * dom/Element.cpp: (WebCore::Element::removedFromAncestor): Notify the PointerCaptureController that an element was disconnected. * dom/PointerEvent.cpp: (WebCore::PointerEvent::create): Broaden createPointerCancelEvent() to take in an event type so that we may use it to create a lostpointercapture event as well. (WebCore::PointerEvent::createPointerCancelEvent): Deleted. * dom/PointerEvent.h: * page/PointerCaptureController.cpp: (WebCore::PointerCaptureController::elementWasRemoved): Check whether the provided element matches one of the target overrides recorded in the map of captured pointer IDs. (WebCore::PointerCaptureController::pointerEventWasDispatched): This block of code was actually useless in this location, the new code added in elementWasRemoved() performs the actions that the spec text mandates. (WebCore::PointerCaptureController::cancelPointer): Replace the call to createPointerCancelEvent() with one to create(). * page/PointerCaptureController.h: LayoutTests: * platform/mac/TestExpectations: Canonical link: https://commits.webkit.org/211306@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@244423 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-04-18 13:31:17 +00:00
void elementWasRemoved(Element&);
Implement capture for Pointer Events on iOS https://bugs.webkit.org/show_bug.cgi?id=193917 <rdar://problem/47605689> Reviewed by Dean Jackson. Source/WebCore: We add a new PointerCaptureController object which gets notified upon dispatch of pointer events to implement implicit pointer capture, dispatch the gotpointercapture and lostpointercaptiure events, and implement the Element APIs for pointer capture: hasPointerCapture(), setPointerCapture() and releasePointerCapture(). Tests: pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down.html pointerevents/ios/pointer-events-implicit-capture-release-exception.html pointerevents/ios/pointer-events-implicit-capture-release.html pointerevents/ios/pointer-events-implicit-capture.html pointerevents/ios/pointer-events-set-pointer-capture-exceptions.html * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * dom/Element.cpp: (WebCore::Element::setPointerCapture): (WebCore::Element::releasePointerCapture): (WebCore::Element::hasPointerCapture): * dom/Element.h: * dom/Element.idl: * dom/EventNames.h: * dom/PointerEvent.h: * page/Page.cpp: (WebCore::Page::Page): * page/Page.h: (WebCore::Page::pointerCaptureController const): * page/PointerCaptureController.cpp: Added. (WebCore::PointerCaptureController::PointerCaptureController): (WebCore::PointerCaptureController::setPointerCapture): (WebCore::PointerCaptureController::releasePointerCapture): (WebCore::PointerCaptureController::hasPointerCapture): (WebCore::PointerCaptureController::pointerLockWasApplied): (WebCore::PointerCaptureController::touchEndedOrWasCancelledForIdentifier): (WebCore::PointerCaptureController::pointerEventWillBeDispatched): (WebCore::PointerCaptureController::pointerEventWasDispatched): (WebCore::PointerCaptureController::processPendingPointerCapture): * page/PointerCaptureController.h: Added. * page/PointerLockController.cpp: (WebCore::PointerLockController::requestPointerLock): * page/PointerLockController.h: LayoutTests: New tests for implicit pointer capture and the Element APIs related to pointer capture. * pointerevents/ios/pointer-events-implicit-capture-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down.html: Added. * pointerevents/ios/pointer-events-implicit-capture-release-exception-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-release-exception.html: Added. * pointerevents/ios/pointer-events-implicit-capture-release-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-release.html: Added. * pointerevents/ios/pointer-events-implicit-capture.html: Added. * pointerevents/ios/pointer-events-set-pointer-capture-exceptions-expected.txt: Added. * pointerevents/ios/pointer-events-set-pointer-capture-exceptions.html: Added. Canonical link: https://commits.webkit.org/208432@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240634 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-29 03:15:02 +00:00
WebDriver: add support for pen pointer events https://bugs.webkit.org/show_bug.cgi?id=219024 Patch by Carlos Garcia Campos <cgarcia@igalia.com> on 2020-12-09 Reviewed by Brian Burg. LayoutTests/imported/w3c: Handle pen pointer events in testdriver. * web-platform-tests/resources/testdriver-vendor.js: (window.test_driver_internal.action_sequence): Source/WebCore: * Headers.cmake: * dom/Element.cpp: (WebCore::dispatchPointerEventIfNeeded): Pass pointer ID and pointer type to pointerEventForMouseEvent(). * dom/PointerEvent.cpp: (WebCore::PointerEvent::create): Add pointer ID and pointer type parameters. (WebCore::PointerEvent::PointerEvent): Ditto. * dom/PointerEvent.h: * page/PointerCaptureController.cpp: (WebCore::PointerCaptureController::pointerEventForMouseEvent): Do not assume the pointer type is always mouse. We might not have a capturing data yet for other pointer types. (WebCore::PointerCaptureController::pointerEventWillBeDispatched): Explicilty check it's not touch pointer event. * page/PointerCaptureController.h: * platform/PlatformMouseEvent.h: (WebCore::PlatformMouseEvent::pointerType const): Source/WebDriver: Pass the actual pointer type to the automation as a different input source. * Session.cpp: (WebDriver::automationSourceType): (WebDriver::Session::performActions): Source/WebKit: Make it possible to synthesize pointer events for any pointer type. Add pen input source to automation and handle it when dispatching actions. * Shared/NativeWebMouseEvent.h: * Shared/WebEventConversion.cpp: (WebKit::WebKit2PlatformMouseEvent::WebKit2PlatformMouseEvent): * Shared/WebMouseEvent.cpp: (WebKit::WebMouseEvent::WebMouseEvent): (WebKit::WebMouseEvent::encode const): (WebKit::WebMouseEvent::decode): * Shared/WebMouseEvent.h: (WebKit::WebMouseEvent::pointerId const): (WebKit::WebMouseEvent::pointerType const): * Shared/gtk/NativeWebMouseEventGtk.cpp: (WebKit::NativeWebMouseEvent::NativeWebMouseEvent): * UIProcess/API/gtk/WebKitWebViewBase.cpp: (primaryPointerForType): (webkitWebViewBaseSynthesizeMouseEvent): * UIProcess/API/gtk/WebKitWebViewBaseInternal.h: * UIProcess/Automation/Automation.json: * UIProcess/Automation/SimulatedInputDispatcher.cpp: (WebKit::SimulatedInputSourceState::emptyStateForSourceType): (WebKit::SimulatedInputDispatcher::transitionInputSourceToState): * UIProcess/Automation/SimulatedInputDispatcher.h: * UIProcess/Automation/WebAutomationSession.cpp: (WebKit::WebAutomationSession::simulateMouseInteraction): (WebKit::WebAutomationSession::performMouseInteraction): (WebKit::simulatedInputSourceTypeFromProtocolSourceType): (WebKit::WebAutomationSession::performInteractionSequence): * UIProcess/Automation/WebAutomationSession.h: * UIProcess/Automation/gtk/WebAutomationSessionGtk.cpp: (WebKit::WebAutomationSession::platformSimulateMouseInteraction): * UIProcess/Automation/mac/WebAutomationSessionMac.mm: (WebKit::WebAutomationSession::platformSimulateMouseInteraction): * UIProcess/Automation/wpe/WebAutomationSessionWPE.cpp: (WebKit::WebAutomationSession::platformSimulateMouseInteraction): * UIProcess/gtk/PointerLockManager.cpp: (WebKit::PointerLockManager::handleMotion): Tools: Add optional pointerType parameter to EventSenderProxy mouseDown(), mouseUp() and mouseMoveTo() methods. * WebKitTestRunner/EventSenderProxy.h: * WebKitTestRunner/InjectedBundle/Bindings/EventSendingController.idl: * WebKitTestRunner/InjectedBundle/EventSendingController.cpp: (WTR::createMouseMessageBody): (WTR::EventSendingController::mouseDown): (WTR::EventSendingController::mouseUp): (WTR::EventSendingController::mouseMoveTo): (WTR::EventSendingController::scheduleAsynchronousClick): * WebKitTestRunner/InjectedBundle/EventSendingController.h: * WebKitTestRunner/InjectedBundle/ios/EventSenderProxyIOS.mm: (WTR::EventSenderProxy::mouseDown): (WTR::EventSenderProxy::mouseUp): (WTR::EventSenderProxy::mouseMoveTo): * WebKitTestRunner/TestController.cpp: (WTR::TestController::didReceiveMessageFromInjectedBundle): (WTR::TestController::didReceiveSynchronousMessageFromInjectedBundle): * WebKitTestRunner/gtk/EventSenderProxyGtk.cpp: (WTR::EventSenderProxy::mouseDown): (WTR::EventSenderProxy::mouseUp): (WTR::EventSenderProxy::mouseMoveTo): * WebKitTestRunner/mac/EventSenderProxy.mm: (WTR::EventSenderProxy::mouseDown): (WTR::EventSenderProxy::mouseUp): (WTR::EventSenderProxy::mouseMoveTo): * WebKitTestRunner/win/EventSenderProxyWin.cpp: (WTR::EventSenderProxy::mouseDown): (WTR::EventSenderProxy::mouseUp): (WTR::EventSenderProxy::mouseMoveTo): * WebKitTestRunner/wpe/EventSenderProxyWPE.cpp: (WTR::EventSenderProxy::mouseDown): (WTR::EventSenderProxy::mouseUp): (WTR::EventSenderProxy::mouseMoveTo): LayoutTests: Update expectations of imported/w3c/web-platform-tests/pointerevents/pointerevent_attributes_hoverable_pointers.html. The test is now timing out, but because tesdriver doesn't correctly handle the iframe element. * platform/gtk/imported/w3c/web-platform-tests/pointerevents/pointerevent_attributes_hoverable_pointers-expected.txt: Added. * platform/mac-wk2/imported/w3c/web-platform-tests/pointerevents/pointerevent_attributes_hoverable_pointers-expected.txt: Added. Canonical link: https://commits.webkit.org/232253@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@270582 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-12-09 17:03:08 +00:00
RefPtr<PointerEvent> pointerEventForMouseEvent(const MouseEvent&, PointerID, const String& pointerType);
[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. Canonical link: https://commits.webkit.org/212560@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246103 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-05 08:41:30 +00:00
[iOS] Dispatch additional events along with pointerdown and pointerup https://bugs.webkit.org/show_bug.cgi?id=194776 <rdar://problem/48164284> Reviewed by Brent Fulgham. Source/WebCore: The Pointer Events specification mandates that "pointerover" and "pointerenter" events precede a "pointerdown" event and that "pointerout" and "pointerleave" events follow a "pointerup" event. We remove the EventHandler::dispatchPointerEventForTouchAtIndex() method and replace it with a PointerCaptureController::dispatchEventForTouchAtIndex() that can handle the dispatch of such additional events correctly, also allowing for two PointerCaptureController methods (pointerEventWillBeDispatched and pointerEventWasDispatched) to become private. Test: pointerevents/ios/over-enter-out-leave.html * dom/EventNames.h: Add the new "pointerover", "pointerenter", "pointerout" and "pointerleave" event types. * dom/PointerEvent.h: * dom/ios/PointerEventIOS.cpp: (WebCore::PointerEvent::create): * page/EventHandler.cpp: (WebCore::EventHandler::dispatchPointerEventForTouchAtIndex): Deleted. * page/EventHandler.h: * page/PointerCaptureController.cpp: (WebCore::PointerCaptureController::dispatchEventForTouchAtIndex): Take the existing code from EventHandler::dispatchPointerEventForTouchAtIndex() and extend it to dispatch additional events as mandated. Since several events may be dispatched we check whether the dispatch of any of those events had defaultPrevented() or defaultHanded() return true and return those values as a pair. (WebCore::PointerCaptureController::pointerEventWasDispatched): * page/PointerCaptureController.h: LayoutTests: Added a new test that checks that "pointerover" and "pointerenter" precede "pointerdown" and that "pointerout" and "pointerleave" follow "pointerup". * pointerevents/ios/over-enter-out-leave-expected.txt: Added. * pointerevents/ios/over-enter-out-leave.html: Added. Canonical link: https://commits.webkit.org/209158@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@241723 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-02-18 17:52:34 +00:00
#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
[iOS] Calling preventDefault() when handling a pointerdown event should not prevent panning, zooming or click event dispatch https://bugs.webkit.org/show_bug.cgi?id=195839 <rdar://problem/48946154> Reviewed by Brent Fulgham. Source/WebCore: Tests: pointerevents/ios/pointer-events-prevent-default-allows-click-event.html pointerevents/ios/pointer-events-prevent-default-allows-scrolling.html The Pointer Events specification defines that the default action of any and all pointer events MUST NOT be a manipulation of the viewport (e.g. panning or zooming). In practice, this means that calling preventDefault() while handling a Pointer Event has no effect on the inner workings of the user agent, so we change the method signature of PointerCaptureController::dispatchEventForTouchAtIndex() to return void since we don't need to know whether preventDefault() was called. https://www.w3.org/TR/pointerevents/#declaring-candidate-regions-for-default-touch-behaviors * page/PointerCaptureController.cpp: (WebCore::PointerCaptureController::dispatchEventForTouchAtIndex): * page/PointerCaptureController.h: LayoutTests: Modify the existing test to check that we *have* scrolled after performing a swipe gesture and calling preventDefault() while handling the pointerdown handling. We also add a new test that checks that the click event is indeed dispatched when tapping on an element and calling preventDefault() while handling the pointerdown event. * pointerevents/ios/pointer-events-prevent-default-allows-click-event-expected.txt: Added. * pointerevents/ios/pointer-events-prevent-default-allows-click-event.html: Added. * pointerevents/ios/pointer-events-prevent-default-allows-scrolling-expected.txt: Added. * pointerevents/ios/pointer-events-prevent-default-allows-scrolling.html: Renamed from LayoutTests/pointerevents/ios/pointer-events-prevent-default.html. * pointerevents/ios/pointer-events-prevent-default-expected.txt: Removed. Canonical link: https://commits.webkit.org/211458@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@244598 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-04-24 18:00:11 +00:00
void dispatchEventForTouchAtIndex(EventTarget&, const PlatformTouchEvent&, unsigned, bool isPrimary, WindowProxy&);
[iOS] Dispatch additional events along with pointerdown and pointerup https://bugs.webkit.org/show_bug.cgi?id=194776 <rdar://problem/48164284> Reviewed by Brent Fulgham. Source/WebCore: The Pointer Events specification mandates that "pointerover" and "pointerenter" events precede a "pointerdown" event and that "pointerout" and "pointerleave" events follow a "pointerup" event. We remove the EventHandler::dispatchPointerEventForTouchAtIndex() method and replace it with a PointerCaptureController::dispatchEventForTouchAtIndex() that can handle the dispatch of such additional events correctly, also allowing for two PointerCaptureController methods (pointerEventWillBeDispatched and pointerEventWasDispatched) to become private. Test: pointerevents/ios/over-enter-out-leave.html * dom/EventNames.h: Add the new "pointerover", "pointerenter", "pointerout" and "pointerleave" event types. * dom/PointerEvent.h: * dom/ios/PointerEventIOS.cpp: (WebCore::PointerEvent::create): * page/EventHandler.cpp: (WebCore::EventHandler::dispatchPointerEventForTouchAtIndex): Deleted. * page/EventHandler.h: * page/PointerCaptureController.cpp: (WebCore::PointerCaptureController::dispatchEventForTouchAtIndex): Take the existing code from EventHandler::dispatchPointerEventForTouchAtIndex() and extend it to dispatch additional events as mandated. Since several events may be dispatched we check whether the dispatch of any of those events had defaultPrevented() or defaultHanded() return true and return those values as a pair. (WebCore::PointerCaptureController::pointerEventWasDispatched): * page/PointerCaptureController.h: LayoutTests: Added a new test that checks that "pointerover" and "pointerenter" precede "pointerdown" and that "pointerout" and "pointerleave" follow "pointerup". * pointerevents/ios/over-enter-out-leave-expected.txt: Added. * pointerevents/ios/over-enter-out-leave.html: Added. Canonical link: https://commits.webkit.org/209158@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@241723 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-02-18 17:52:34 +00:00
#endif
[iOS] Compatibility mouse events aren't prevented by calling preventDefault() on pointerdown https://bugs.webkit.org/show_bug.cgi?id=198124 <rdar://problem/50410863> Reviewed by Tim Horton. LayoutTests/imported/w3c: We add basic support to run a test that wasn't specifically designed for a touch-based interaction such that the test at imported/w3c/web-platform-tests/pointerevents/pointerevent_suppress_compat_events_on_click.html may run on iOS. The trick here is to add a pause after a touch ends to avoid the likelihood or two tap gestures triggering a double tap. * web-platform-tests/resources/testdriver-vendor.js: Source/WebCore: This fix builds atop the one made for wkb.ug/198072 which fixes this bug on macOS alone. In order to correctly prevent "compatibility" mouse events from being dispatched when the initial "pointerdown" event had preventDefault() called while handled, we need to pass the PointerID for the touch that triggered a tap gesture in the UI process down in the Web process and into the resulting PlatformMouseEvent. This will allow upon dispatch of a PlatformMouseEvent to call into PointerCaptureController to identify if the dispatch of mouse events is allowed for the event's PointerID. To support this, some refactoring was required. The PointerID header is now under platform/ such that PlatformMouseEvent may safely use it. Additionally, PointerEvent::defaultMousePointerIdentifier() is now a global mousePointerID defined in PointerID.h. Finally, PointerCaptureController::touchEndedOrWasCancelledForIdentifier() has been renamed to PointerCaptureController::touchWithIdentifierWasRemoved() and has WEBCORE_EXPORT such that it may be called from WebKit as the indication that a pointer is no longer active will now be initiated in WebKit on the UI process side. Testing is covered by the pre-existing imported/w3c/web-platform-tests/pointerevents/pointerevent_suppress_compat_events_on_click.html which will now run on iOS through a change to WebKitAdditions. * Headers.cmake: * WebCore.xcodeproj/project.pbxproj: * dom/Element.cpp: (WebCore::Element::dispatchMouseEvent): When dealing with a mouse event on iOS, check whether the mouse event's PointerID allows for compatibility mouse events to be dispatched using PointerCaptureController::preventsCompatibilityMouseEventsForIdentifier(). The "click" event is not a compatibility mouse event. * dom/PointerEvent.h: * page/PointerCaptureController.cpp: (WebCore::PointerCaptureController::PointerCaptureController): (WebCore::PointerCaptureController::touchWithIdentifierWasRemoved): (WebCore::PointerCaptureController::touchEndedOrWasCancelledForIdentifier): Deleted. * page/PointerCaptureController.h: * platform/PlatformMouseEvent.h: (WebCore::PlatformMouseEvent::PlatformMouseEvent): (WebCore::PlatformMouseEvent::pointerId const): * platform/PointerID.h: Renamed from Source/WebCore/dom/PointerID.h. (WebCore::mousePointerID): Source/WebKit: In order to correctly prevent "compatibility" mouse events from being dispatched when the initial "pointerdown" event had preventDefault() called while handled, we need to pass the PointerID for the touch that triggered a tap gesture in the UI process down in the Web process and into the resulting PlatformMouseEvent. This means we need to identify the touch identifier, which is the same as the PointerID used for Pointer Events, in the single tap gesture recognizer, an instance of WKSyntheticTapGestureRecognizer. To do this, we subclass the -[UIResponder touchesEnded:withEvent:] method and track the touch identifier as the lastActiveTouchIdentifier, a new public property of WKSyntheticTapGestureRecognizer. To allow for this, we need the support of the content view's UIWebTouchEventsGestureRecognizer which is exposed to the WKSyntheticTapGestureRecognizer as its supportingWebTouchEventsGestureRecognizer property. This lastActiveTouchIdentifier property is cleared as the gesture recognizer is reset. This allows the content view to pass the PointerID down to the Web process starting from -[WKContentView _singleTapRecognized:], going through WebPageProxy::commitPotentialTap() and eventually WebPage::completeSyntheticClick(). While we used to tell the PointerCaptureController that a PointerID was no longer active when a given touch ended or was canceled (in WebKitAdditions code), we can no longer do this as the dispatch of a synthetic tap is performed asynchronously and will happen past the dispatch of "pointerup" and "pointercancel" Pointer Events. To clear inactive PointerIDs from the PointerCaptureController, we add a new touchWithIdentifierWasRemoved() method on the WebPage and its proxy. When the WKSyntheticTapGestureRecognizer resets and -[WKContentView _singleTapDidReset:] is called, we call that method which allows for only active PointerIDs to be tracked by the PointerCaptureController. * UIProcess/WebPageProxy.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView setupInteraction]): (-[WKContentView cleanupInteraction]): (-[WKContentView _singleTapDidReset:]): (-[WKContentView _singleTapRecognized:]): * UIProcess/ios/WKSyntheticTapGestureRecognizer.h: * UIProcess/ios/WKSyntheticTapGestureRecognizer.m: (-[WKSyntheticTapGestureRecognizer reset]): (-[WKSyntheticTapGestureRecognizer touchesEnded:withEvent:]): * UIProcess/ios/WebPageProxyIOS.mm: (WebKit::WebPageProxy::touchWithIdentifierWasRemoved): (WebKit::WebPageProxy::commitPotentialTap): * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/WebPage.messages.in: * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::dispatchSyntheticMouseMove): (WebKit::WebPage::handleSyntheticClick): (WebKit::WebPage::completePendingSyntheticClickForContentChangeObserver): (WebKit::WebPage::completeSyntheticClick): (WebKit::WebPage::commitPotentialTap): (WebKit::WebPage::touchWithIdentifierWasRemoved): LayoutTests: We're adding an iOS-specific expectation since this test prints out the pointer type detected while it runs, which is "touch" on iOS and "mouse" in the expectation that already exists for macOS. * platform/ios/imported/w3c/web-platform-tests/pointerevents/pointerevent_suppress_compat_events_on_click-expected.txt: Added. Canonical link: https://commits.webkit.org/212200@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@245639 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-05-22 19:58:15 +00:00
WEBCORE_EXPORT void touchWithIdentifierWasRemoved(PointerID);
Optimize PointerCaptureController::elementWasRemoved() https://bugs.webkit.org/show_bug.cgi?id=221316 Reviewed by Ryosuke Niwa. Speedometer profiles show HashTable iteration code under PointerCaptureController::elementWasRemoved() because we always add a hash entry for the mouse pointer. Optimize away by setting a flag that's only true if any element is referenced by pointer capture. * page/PointerCaptureController.cpp: (WebCore::PointerCaptureController::pointerCaptureElement const): (WebCore::PointerCaptureController::setPointerCapture): (WebCore::PointerCaptureController::releasePointerCapture): (WebCore::PointerCaptureController::hasPointerCapture): (WebCore::PointerCaptureController::pointerLockWasApplied): (WebCore::PointerCaptureController::elementWasRemoved): (WebCore::PointerCaptureController::reset): (WebCore::PointerCaptureController::updateHaveAnyCapturingElement): (WebCore::PointerCaptureController::touchWithIdentifierWasRemoved): (WebCore::PointerCaptureController::hasCancelledPointerEventForIdentifier const): (WebCore::PointerCaptureController::preventsCompatibilityMouseEventsForIdentifier const): (WebCore::PointerCaptureController::pointerCaptureElement): Deleted. (WebCore::PointerCaptureController::hasCancelledPointerEventForIdentifier): Deleted. (WebCore::PointerCaptureController::preventsCompatibilityMouseEventsForIdentifier): Deleted. * page/PointerCaptureController.h: Canonical link: https://commits.webkit.org/233659@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@272331 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-02-03 18:41:16 +00:00
bool hasCancelledPointerEventForIdentifier(PointerID) const;
bool preventsCompatibilityMouseEventsForIdentifier(PointerID) const;
[iOS] Dispatch additional events along with pointerdown and pointerup https://bugs.webkit.org/show_bug.cgi?id=194776 <rdar://problem/48164284> Reviewed by Brent Fulgham. Source/WebCore: The Pointer Events specification mandates that "pointerover" and "pointerenter" events precede a "pointerdown" event and that "pointerout" and "pointerleave" events follow a "pointerup" event. We remove the EventHandler::dispatchPointerEventForTouchAtIndex() method and replace it with a PointerCaptureController::dispatchEventForTouchAtIndex() that can handle the dispatch of such additional events correctly, also allowing for two PointerCaptureController methods (pointerEventWillBeDispatched and pointerEventWasDispatched) to become private. Test: pointerevents/ios/over-enter-out-leave.html * dom/EventNames.h: Add the new "pointerover", "pointerenter", "pointerout" and "pointerleave" event types. * dom/PointerEvent.h: * dom/ios/PointerEventIOS.cpp: (WebCore::PointerEvent::create): * page/EventHandler.cpp: (WebCore::EventHandler::dispatchPointerEventForTouchAtIndex): Deleted. * page/EventHandler.h: * page/PointerCaptureController.cpp: (WebCore::PointerCaptureController::dispatchEventForTouchAtIndex): Take the existing code from EventHandler::dispatchPointerEventForTouchAtIndex() and extend it to dispatch additional events as mandated. Since several events may be dispatched we check whether the dispatch of any of those events had defaultPrevented() or defaultHanded() return true and return those values as a pair. (WebCore::PointerCaptureController::pointerEventWasDispatched): * page/PointerCaptureController.h: LayoutTests: Added a new test that checks that "pointerover" and "pointerenter" precede "pointerdown" and that "pointerout" and "pointerleave" follow "pointerup". * pointerevents/ios/over-enter-out-leave-expected.txt: Added. * pointerevents/ios/over-enter-out-leave.html: Added. Canonical link: https://commits.webkit.org/209158@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@241723 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-02-18 17:52:34 +00:00
void dispatchEvent(PointerEvent&, EventTarget*);
WEBCORE_EXPORT void cancelPointer(PointerID, const IntPoint&);
[Pointer Events] Respect pointer capture when dispatching mouse boundary events and updating :hover https://bugs.webkit.org/show_bug.cgi?id=198999 <rdar://problem/51979477> Reviewed by Dean Jackson. LayoutTests/imported/w3c: Mark the progressions in 3 WPT tests. * web-platform-tests/pointerevents/pointerevent_boundary_events_at_implicit_release_hoverable_pointers-expected.txt: * web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt: * web-platform-tests/pointerevents/pointerevent_setpointercapture_relatedtarget-expected.txt: Source/WebCore: Up until now, we would not account for pointer capture (see ​https://w3c.github.io/pointerevents/#pointer-capture) when dispatching mouse boundary events (mouseover, mouseout, mouseenter, mouseleave) and their counterpart pointer events. We would also not account for it when updating :hover styles. Now, when pointer capture changes for an element, we call setCapturingMouseEventsElement() on the EventHandler such that the element that would naturally hit-test is overridden by the pointer capture element when identifying which target to use for the dispatch of boundary mouse events. Additionally, when calling Document::prepareMouseEvent(), we also use the pointer capture element to pass down to Document::updateHoverActiveState() such that :hover styles are applied to the correct element. * dom/Document.cpp: (WebCore::Document::prepareMouseEvent): When a new event is going to be dispatched, we must run the Process Pending Capture Element steps as mandated by the Pointer Events spec. Calling this will dispatch the appropriate pointer capture change events and also required boundary events since EventHandler::setCapturingMouseEventsElement() calls into EventHandler::updateMouseEventTargetNode(). Since this may update the capturing mouse events element, we ensure that we call updateHoverActiveState() with a flag that indicates that. Finally, we use the capturing mouse events element instead of the hit-testing element to pass to updateHoverActiveState() to ensure that is has :hover styles applied. (WebCore::Document::updateHoverActiveState): Account for the new CaptureChange flag to force the invalidation of the :hover and :active elements chain at all times when the capturing mouse events element changed. * dom/Document.h: * dom/PointerEvent.h: Update PointerEvent::createForPointerCapture() to take specific parameters rather than a single PointerEvent to set the pointerId, isPrimary and pointerType properties of the generated event. This is required to call processPendingPointerCapture() outside of PointerEvent dispatch logic since we now call it from Document::prepareMouseEvent() where we haven't yet generated such an event. * page/EventHandler.cpp: (WebCore::EventHandler::pointerCaptureElementDidChange): When a new pointer capture element is set, call updateMouseEventTargetNode() to ensure that boundary events are fired to indicate the pointer capture state change. (WebCore::EventHandler::prepareMouseEvent): Keep track of the last PlatformMouseEvent used to prepare a mouse event so that we can use it when setCapturingMouseEventsElement() is called. * page/EventHandler.h: * page/PointerCaptureController.cpp: (WebCore::PointerCaptureController::pointerCaptureElement): Since Document::prepareMouseEvent() needs to know the current pointer capture element, add a new public method that indicates the pointer capture element if that element is contained in the provided document. We need to provide the document since PointerCaptureController is owned by the Page and may manage several documents. (WebCore::PointerCaptureController::dispatchEvent): Only run the Process Pending Capture Element steps when dealing with a touch or pen event since those steps are already ran for mouse events in Document::prepareMouseEvent(). Additionally, since the element target is already set to be the pointer capture element with the changes made to processPendingPointerCapture(), and because on iOS pointer capture is always active, we can remove the code that would retarget the event to the pointer capture element. (WebCore::PointerCaptureController::pointerEventWasDispatched): (WebCore::PointerCaptureController::cancelPointer): (WebCore::PointerCaptureController::processPendingPointerCapture): We now call into EventHandler::setCapturingMouseEventsElement() when the capture target element changes. We must be careful to call this method prior to dispatching the "gotpointercapture" event and after dispatching the "lostpointercapture" event so that boundary events are fired at the right time. * page/PointerCaptureController.h: LayoutTests: Update some WK1-specific expectations. * platform/mac-wk1/imported/w3c/web-platform-tests/pointerevents/pointerevent_boundary_events_at_implicit_release_hoverable_pointers-expected.txt: * platform/mac-wk1/imported/w3c/web-platform-tests/pointerevents/pointerevent_setpointercapture_relatedtarget-expected.txt: Canonical link: https://commits.webkit.org/213414@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@247148 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-07-05 10:25:06 +00:00
void processPendingPointerCapture(PointerID);
Implement capture for Pointer Events on iOS https://bugs.webkit.org/show_bug.cgi?id=193917 <rdar://problem/47605689> Reviewed by Dean Jackson. Source/WebCore: We add a new PointerCaptureController object which gets notified upon dispatch of pointer events to implement implicit pointer capture, dispatch the gotpointercapture and lostpointercaptiure events, and implement the Element APIs for pointer capture: hasPointerCapture(), setPointerCapture() and releasePointerCapture(). Tests: pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down.html pointerevents/ios/pointer-events-implicit-capture-release-exception.html pointerevents/ios/pointer-events-implicit-capture-release.html pointerevents/ios/pointer-events-implicit-capture.html pointerevents/ios/pointer-events-set-pointer-capture-exceptions.html * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * dom/Element.cpp: (WebCore::Element::setPointerCapture): (WebCore::Element::releasePointerCapture): (WebCore::Element::hasPointerCapture): * dom/Element.h: * dom/Element.idl: * dom/EventNames.h: * dom/PointerEvent.h: * page/Page.cpp: (WebCore::Page::Page): * page/Page.h: (WebCore::Page::pointerCaptureController const): * page/PointerCaptureController.cpp: Added. (WebCore::PointerCaptureController::PointerCaptureController): (WebCore::PointerCaptureController::setPointerCapture): (WebCore::PointerCaptureController::releasePointerCapture): (WebCore::PointerCaptureController::hasPointerCapture): (WebCore::PointerCaptureController::pointerLockWasApplied): (WebCore::PointerCaptureController::touchEndedOrWasCancelledForIdentifier): (WebCore::PointerCaptureController::pointerEventWillBeDispatched): (WebCore::PointerCaptureController::pointerEventWasDispatched): (WebCore::PointerCaptureController::processPendingPointerCapture): * page/PointerCaptureController.h: Added. * page/PointerLockController.cpp: (WebCore::PointerLockController::requestPointerLock): * page/PointerLockController.h: LayoutTests: New tests for implicit pointer capture and the Element APIs related to pointer capture. * pointerevents/ios/pointer-events-implicit-capture-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down.html: Added. * pointerevents/ios/pointer-events-implicit-capture-release-exception-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-release-exception.html: Added. * pointerevents/ios/pointer-events-implicit-capture-release-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-release.html: Added. * pointerevents/ios/pointer-events-implicit-capture.html: Added. * pointerevents/ios/pointer-events-set-pointer-capture-exceptions-expected.txt: Added. * pointerevents/ios/pointer-events-set-pointer-capture-exceptions.html: Added. Canonical link: https://commits.webkit.org/208432@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240634 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-29 03:15:02 +00:00
private:
Deploy smart pointers in PointerCaptureController https://bugs.webkit.org/show_bug.cgi?id=227352 Reviewed by Wenson Hsieh. Deployed Ref/RefPtr in more places in PointerCaptureController. Also made PointerCaptureController::CapturingData ref counted. * page/PointerCaptureController.cpp: (WebCore::PointerCaptureController::pointerCaptureElement const): (WebCore::PointerCaptureController::setPointerCapture): (WebCore::PointerCaptureController::releasePointerCapture): (WebCore::PointerCaptureController::hasPointerCapture): (WebCore::PointerCaptureController::pointerLockWasApplied): (WebCore::PointerCaptureController::elementWasRemoved): (WebCore::PointerCaptureController::reset): (WebCore::PointerCaptureController::updateHaveAnyCapturingElement): (WebCore::PointerCaptureController::hasCancelledPointerEventForIdentifier const): (WebCore::PointerCaptureController::preventsCompatibilityMouseEventsForIdentifier const): (WebCore::hierarchyHasCapturingEventListeners): (WebCore::PointerCaptureController::dispatchEventForTouchAtIndex): (WebCore::PointerCaptureController::pointerEventForMouseEvent): (WebCore::PointerCaptureController::pointerEventWillBeDispatched): (WebCore::PointerCaptureController::ensureCapturingDataForPointerEvent): (WebCore::PointerCaptureController::pointerEventWasDispatched): (WebCore::PointerCaptureController::cancelPointer): (WebCore::PointerCaptureController::processPendingPointerCapture): * page/PointerCaptureController.h: (WebCore::PointerCaptureController::CapturingData::create): (WebCore::PointerCaptureController::CapturingData::CapturingData): Canonical link: https://commits.webkit.org/239525@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@279749 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-07-08 20:45:38 +00:00
struct CapturingData : public RefCounted<CapturingData> {
static Ref<CapturingData> create(const String& pointerType)
{
return adoptRef(*new CapturingData(pointerType));
}
Dispatch pointercancel events when content is panned or zoomed on iOS https://bugs.webkit.org/show_bug.cgi?id=193962 <rdar://problem/47629134> Reviewed by Dean Jackson. Source/WebCore: Expose two new methods on PointerCaptureController so that, given a pointer id, it can be established whether this pointer has been cancelled, which is important because a cancelled pointer should no longer dispatch any further pointer events, and to cancel a pointer. Tests: pointerevents/ios/touch-action-pointercancel-pan-x.html pointerevents/ios/touch-action-pointercancel-pan-y.html pointerevents/ios/touch-action-pointercancel-pinch-zoom.html * WebCore.xcodeproj/project.pbxproj: Make PointerCaptureController.h Private so that it can be imported from WebKit. * dom/PointerEvent.h: Remove an unnecessary #if ENABLE(POINTER_EVENTS) since the entire file is already contained in one. Then we add a new create() method that takes an event type, a pointer id and a pointer type (touch vs. pen) that we use to create pointercancel events in PointerCaptureController::cancelPointer(). * page/Page.cpp: (WebCore::Page::Page): Pass the Page as a parameter when creating the PointerCaptureController. * page/PointerCaptureController.cpp: (WebCore::PointerCaptureController::PointerCaptureController): Add a Page reference to the constructor since we'll need the page to access its main frame's EventHandler to perform hit testing in case we do not have a capture target override in cancelPointer(). (WebCore::PointerCaptureController::releasePointerCapture): Drive-by, remove the the implicit parameter since on iOS we don't need to differentiate. We'll bring this back for the macOS work. (WebCore::PointerCaptureController::hasCancelledPointerEventForIdentifier): New method we'll use when dispatching pointer events to identify whether a pointer id has already been cancelled which will allow for _not_ dispatching any further pointer events for this pointer id. (WebCore::PointerCaptureController::pointerEventWillBeDispatched): Keep track of the pointer type so we can preserve it when dispatching pointercancel events for a given pointer id. (WebCore::PointerCaptureController::cancelPointer): Dispatch a pointercancel for the provided pointer id, using the capture target override as the event's target, if there is one, and otherwise hit-testing at the provided location to figure out what the target should be. * page/PointerCaptureController.h: Switch the target overrides from Element* to RefPtr<Element> to ensure it may not be deleted while we still need them. Existing code already ensures these get set to nullptr. Source/WebKit: When a user-agent-provided interaction, such as panning or zooming on iOS, uses a set of touches, we should dispatch a pointercancel event for the pointer ids of the touches involved. To facilitate this, we add a new method on WKContentView to cancel all the pointers matching active touches for a provided UIGestureRecognizer through an async IPC call into the Web process using the new method PointerCaptureController::cancelPointer(). * Platform/spi/ios/UIKitSPI.h: Add the necessary forward declaration for a necessary UIKit SPI allowing us to get the set of last-seen UITouches by the identifier generated for the matching WebKit touch. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView scrollViewWillBeginZooming:withView:]): Dispatch touchcancel events for all pointers involved in a pinch gesture on the top-level UIScrollView. (-[WKWebView _scrollView:adjustedOffsetForOffset:translation:startPoint:locationInView:horizontalVelocity:verticalVelocity:]): Dispatch touchcancel events for all pointers involved in a pan gesture on the top-level UIScrollView. We can infer this by looking at whether the adjusted content offset, after accounting for the permitted touch actions, is different from the original content offset. * UIProcess/PageClient.h: Expose a new virtual cancelPointersForGestureRecognizer() method which will allow the iOS implementation to forward the call to WKContentViewInteraction. (WebKit::PageClient::cancelPointersForGestureRecognizer): * UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h: Expose the WebPageProxy such that we may access it to cancel pointers for a given gesture recognizer from within ScrollingTreeScrollingNodeDelegateIOS. (WebKit::RemoteScrollingCoordinatorProxy::webPageProxy const): * UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.h: * UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm: (-[WKScrollingNodeScrollViewDelegate _scrollView:adjustedOffsetForOffset:translation:startPoint:locationInView:horizontalVelocity:verticalVelocity:]): Dispatch touchcancel events for all pointers involved in a pan gesture on a nested UIScrollView. We can infer this by looking at whether the adjusted content offset, after accounting for the permitted touch actions, is different from the original content offset. (-[WKScrollingNodeScrollViewDelegate scrollViewWillBeginZooming:withView:]): Dispatch touchcancel events for all pointers involved in a pinch gesture on a nested UIScrollView. (-[WKScrollingNodeScrollViewDelegate cancelPointersForGestureRecognizer:]): (WebKit::ScrollingTreeScrollingNodeDelegateIOS::cancelPointersForGestureRecognizer): * UIProcess/WebPageProxy.cpp: (WebKit::WebPageProxy::cancelPointer): * UIProcess/WebPageProxy.h: * UIProcess/ios/PageClientImplIOS.h: * UIProcess/ios/PageClientImplIOS.mm: (WebKit::PageClientImpl::cancelPointersForGestureRecognizer): * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView cancelPointersForGestureRecognizer:]): Obtain all active UITouch objects for the view and dispatch a pointercancel event, through the WebPageProxy, for all touches associated with the provided gesture recognizer. * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::cancelPointer): * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/WebPage.messages.in: LayoutTests: Adding a few tests for "pointercancel" and adding "touch-action: none" on tests that would now be affected by canceling pointers. We also unflake a few tests. * pointerevents/ios/pointer-events-implicit-capture.html: * pointerevents/ios/pointer-events-is-primary.html: * pointerevents/ios/touch-action-pan-x-pan-y.html: * pointerevents/ios/touch-action-pan-x.html: * pointerevents/ios/touch-action-pan-y-expected.txt: * pointerevents/ios/touch-action-pan-y.html: * pointerevents/ios/touch-action-pinch-zoom-allows-zooming.html: * pointerevents/ios/touch-action-pointercancel-pan-x-expected.txt: Added. * pointerevents/ios/touch-action-pointercancel-pan-x.html: Added. * pointerevents/ios/touch-action-pointercancel-pan-y-expected.txt: Added. * pointerevents/ios/touch-action-pointercancel-pan-y.html: Added. * pointerevents/ios/touch-action-pointercancel-pinch-zoom-expected.txt: Added. * pointerevents/ios/touch-action-pointercancel-pinch-zoom.html: Added. Canonical link: https://commits.webkit.org/208642@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240875 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-02-01 21:53:40 +00:00
RefPtr<Element> pendingTargetOverride;
RefPtr<Element> targetOverride;
releasePointerCapture() not working for implicit capture; can't opt-in to pointerenter/leave for touches https://bugs.webkit.org/show_bug.cgi?id=199803 <rdar://problem/53127223> Reviewed by Dean Jackson. Source/WebCore: In order to dispatch boundary events (pointerover/out/enter/leave) when the implicit pointer capture is released on iOS, we need to track the target of the pointer events that was dispatched last for a given pointer id. Then we compare that target with the current target when dispatching a new pointer event and determine whether we should dispatch boundary events using the exact same approach used to dispatch mouse boundary events in EventHandler::updateMouseEventTargetNode(). Tests: pointerevents/ios/boundary-events-through-hierarchy-without-pointer-capture.html pointerevents/ios/boundary-events-without-pointer-capture.html * page/PointerCaptureController.cpp: (WebCore::hierarchyHasCapturingEventListeners): (WebCore::PointerCaptureController::dispatchEventForTouchAtIndex): (WebCore::PointerCaptureController::pointerEventWillBeDispatched): (WebCore::PointerCaptureController::ensureCapturingDataForPointerEvent): (WebCore::PointerCaptureController::cancelPointer): * page/PointerCaptureController.h: LayoutTests: Add new tests that check we correctly dispatch boundary events on iOS when pointer capture is disabled. * pointerevents/ios/boundary-events-through-hierarchy-without-pointer-capture-expected.txt: Added. * pointerevents/ios/boundary-events-through-hierarchy-without-pointer-capture.html: Added. * pointerevents/ios/boundary-events-without-pointer-capture-expected.txt: Added. * pointerevents/ios/boundary-events-without-pointer-capture.html: Added. * pointerevents/utils.js: Canonical link: https://commits.webkit.org/215679@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@250182 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-09-21 15:34:43 +00:00
#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
RefPtr<Element> previousTarget;
#endif
Optimize PointerCaptureController::elementWasRemoved() https://bugs.webkit.org/show_bug.cgi?id=221316 Reviewed by Ryosuke Niwa. Speedometer profiles show HashTable iteration code under PointerCaptureController::elementWasRemoved() because we always add a hash entry for the mouse pointer. Optimize away by setting a flag that's only true if any element is referenced by pointer capture. * page/PointerCaptureController.cpp: (WebCore::PointerCaptureController::pointerCaptureElement const): (WebCore::PointerCaptureController::setPointerCapture): (WebCore::PointerCaptureController::releasePointerCapture): (WebCore::PointerCaptureController::hasPointerCapture): (WebCore::PointerCaptureController::pointerLockWasApplied): (WebCore::PointerCaptureController::elementWasRemoved): (WebCore::PointerCaptureController::reset): (WebCore::PointerCaptureController::updateHaveAnyCapturingElement): (WebCore::PointerCaptureController::touchWithIdentifierWasRemoved): (WebCore::PointerCaptureController::hasCancelledPointerEventForIdentifier const): (WebCore::PointerCaptureController::preventsCompatibilityMouseEventsForIdentifier const): (WebCore::PointerCaptureController::pointerCaptureElement): Deleted. (WebCore::PointerCaptureController::hasCancelledPointerEventForIdentifier): Deleted. (WebCore::PointerCaptureController::preventsCompatibilityMouseEventsForIdentifier): Deleted. * page/PointerCaptureController.h: Canonical link: https://commits.webkit.org/233659@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@272331 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-02-03 18:41:16 +00:00
bool hasAnyElement() const {
return pendingTargetOverride || targetOverride
#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
|| previousTarget
#endif
;
}
Dispatch pointercancel events when content is panned or zoomed on iOS https://bugs.webkit.org/show_bug.cgi?id=193962 <rdar://problem/47629134> Reviewed by Dean Jackson. Source/WebCore: Expose two new methods on PointerCaptureController so that, given a pointer id, it can be established whether this pointer has been cancelled, which is important because a cancelled pointer should no longer dispatch any further pointer events, and to cancel a pointer. Tests: pointerevents/ios/touch-action-pointercancel-pan-x.html pointerevents/ios/touch-action-pointercancel-pan-y.html pointerevents/ios/touch-action-pointercancel-pinch-zoom.html * WebCore.xcodeproj/project.pbxproj: Make PointerCaptureController.h Private so that it can be imported from WebKit. * dom/PointerEvent.h: Remove an unnecessary #if ENABLE(POINTER_EVENTS) since the entire file is already contained in one. Then we add a new create() method that takes an event type, a pointer id and a pointer type (touch vs. pen) that we use to create pointercancel events in PointerCaptureController::cancelPointer(). * page/Page.cpp: (WebCore::Page::Page): Pass the Page as a parameter when creating the PointerCaptureController. * page/PointerCaptureController.cpp: (WebCore::PointerCaptureController::PointerCaptureController): Add a Page reference to the constructor since we'll need the page to access its main frame's EventHandler to perform hit testing in case we do not have a capture target override in cancelPointer(). (WebCore::PointerCaptureController::releasePointerCapture): Drive-by, remove the the implicit parameter since on iOS we don't need to differentiate. We'll bring this back for the macOS work. (WebCore::PointerCaptureController::hasCancelledPointerEventForIdentifier): New method we'll use when dispatching pointer events to identify whether a pointer id has already been cancelled which will allow for _not_ dispatching any further pointer events for this pointer id. (WebCore::PointerCaptureController::pointerEventWillBeDispatched): Keep track of the pointer type so we can preserve it when dispatching pointercancel events for a given pointer id. (WebCore::PointerCaptureController::cancelPointer): Dispatch a pointercancel for the provided pointer id, using the capture target override as the event's target, if there is one, and otherwise hit-testing at the provided location to figure out what the target should be. * page/PointerCaptureController.h: Switch the target overrides from Element* to RefPtr<Element> to ensure it may not be deleted while we still need them. Existing code already ensures these get set to nullptr. Source/WebKit: When a user-agent-provided interaction, such as panning or zooming on iOS, uses a set of touches, we should dispatch a pointercancel event for the pointer ids of the touches involved. To facilitate this, we add a new method on WKContentView to cancel all the pointers matching active touches for a provided UIGestureRecognizer through an async IPC call into the Web process using the new method PointerCaptureController::cancelPointer(). * Platform/spi/ios/UIKitSPI.h: Add the necessary forward declaration for a necessary UIKit SPI allowing us to get the set of last-seen UITouches by the identifier generated for the matching WebKit touch. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView scrollViewWillBeginZooming:withView:]): Dispatch touchcancel events for all pointers involved in a pinch gesture on the top-level UIScrollView. (-[WKWebView _scrollView:adjustedOffsetForOffset:translation:startPoint:locationInView:horizontalVelocity:verticalVelocity:]): Dispatch touchcancel events for all pointers involved in a pan gesture on the top-level UIScrollView. We can infer this by looking at whether the adjusted content offset, after accounting for the permitted touch actions, is different from the original content offset. * UIProcess/PageClient.h: Expose a new virtual cancelPointersForGestureRecognizer() method which will allow the iOS implementation to forward the call to WKContentViewInteraction. (WebKit::PageClient::cancelPointersForGestureRecognizer): * UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h: Expose the WebPageProxy such that we may access it to cancel pointers for a given gesture recognizer from within ScrollingTreeScrollingNodeDelegateIOS. (WebKit::RemoteScrollingCoordinatorProxy::webPageProxy const): * UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.h: * UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm: (-[WKScrollingNodeScrollViewDelegate _scrollView:adjustedOffsetForOffset:translation:startPoint:locationInView:horizontalVelocity:verticalVelocity:]): Dispatch touchcancel events for all pointers involved in a pan gesture on a nested UIScrollView. We can infer this by looking at whether the adjusted content offset, after accounting for the permitted touch actions, is different from the original content offset. (-[WKScrollingNodeScrollViewDelegate scrollViewWillBeginZooming:withView:]): Dispatch touchcancel events for all pointers involved in a pinch gesture on a nested UIScrollView. (-[WKScrollingNodeScrollViewDelegate cancelPointersForGestureRecognizer:]): (WebKit::ScrollingTreeScrollingNodeDelegateIOS::cancelPointersForGestureRecognizer): * UIProcess/WebPageProxy.cpp: (WebKit::WebPageProxy::cancelPointer): * UIProcess/WebPageProxy.h: * UIProcess/ios/PageClientImplIOS.h: * UIProcess/ios/PageClientImplIOS.mm: (WebKit::PageClientImpl::cancelPointersForGestureRecognizer): * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView cancelPointersForGestureRecognizer:]): Obtain all active UITouch objects for the view and dispatch a pointercancel event, through the WebPageProxy, for all touches associated with the provided gesture recognizer. * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::cancelPointer): * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/WebPage.messages.in: LayoutTests: Adding a few tests for "pointercancel" and adding "touch-action: none" on tests that would now be affected by canceling pointers. We also unflake a few tests. * pointerevents/ios/pointer-events-implicit-capture.html: * pointerevents/ios/pointer-events-is-primary.html: * pointerevents/ios/touch-action-pan-x-pan-y.html: * pointerevents/ios/touch-action-pan-x.html: * pointerevents/ios/touch-action-pan-y-expected.txt: * pointerevents/ios/touch-action-pan-y.html: * pointerevents/ios/touch-action-pinch-zoom-allows-zooming.html: * pointerevents/ios/touch-action-pointercancel-pan-x-expected.txt: Added. * pointerevents/ios/touch-action-pointercancel-pan-x.html: Added. * pointerevents/ios/touch-action-pointercancel-pan-y-expected.txt: Added. * pointerevents/ios/touch-action-pointercancel-pan-y.html: Added. * pointerevents/ios/touch-action-pointercancel-pinch-zoom-expected.txt: Added. * pointerevents/ios/touch-action-pointercancel-pinch-zoom.html: Added. Canonical link: https://commits.webkit.org/208642@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240875 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-02-01 21:53:40 +00:00
String pointerType;
enum class State : uint8_t {
Ready,
Finished,
Cancelled,
};
State state { State::Ready };
2019-05-07 18:43:27 +00:00
bool isPrimary { false };
bool preventsCompatibilityMouseEvents { false };
bool pointerIsPressed { false };
[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. Canonical link: https://commits.webkit.org/212560@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246103 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-05 08:41:30 +00:00
short previousMouseButton { -1 };
Deploy smart pointers in PointerCaptureController https://bugs.webkit.org/show_bug.cgi?id=227352 Reviewed by Wenson Hsieh. Deployed Ref/RefPtr in more places in PointerCaptureController. Also made PointerCaptureController::CapturingData ref counted. * page/PointerCaptureController.cpp: (WebCore::PointerCaptureController::pointerCaptureElement const): (WebCore::PointerCaptureController::setPointerCapture): (WebCore::PointerCaptureController::releasePointerCapture): (WebCore::PointerCaptureController::hasPointerCapture): (WebCore::PointerCaptureController::pointerLockWasApplied): (WebCore::PointerCaptureController::elementWasRemoved): (WebCore::PointerCaptureController::reset): (WebCore::PointerCaptureController::updateHaveAnyCapturingElement): (WebCore::PointerCaptureController::hasCancelledPointerEventForIdentifier const): (WebCore::PointerCaptureController::preventsCompatibilityMouseEventsForIdentifier const): (WebCore::hierarchyHasCapturingEventListeners): (WebCore::PointerCaptureController::dispatchEventForTouchAtIndex): (WebCore::PointerCaptureController::pointerEventForMouseEvent): (WebCore::PointerCaptureController::pointerEventWillBeDispatched): (WebCore::PointerCaptureController::ensureCapturingDataForPointerEvent): (WebCore::PointerCaptureController::pointerEventWasDispatched): (WebCore::PointerCaptureController::cancelPointer): (WebCore::PointerCaptureController::processPendingPointerCapture): * page/PointerCaptureController.h: (WebCore::PointerCaptureController::CapturingData::create): (WebCore::PointerCaptureController::CapturingData::CapturingData): Canonical link: https://commits.webkit.org/239525@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@279749 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-07-08 20:45:38 +00:00
private:
CapturingData(const String& pointerType)
: pointerType(pointerType)
{ }
Implement capture for Pointer Events on iOS https://bugs.webkit.org/show_bug.cgi?id=193917 <rdar://problem/47605689> Reviewed by Dean Jackson. Source/WebCore: We add a new PointerCaptureController object which gets notified upon dispatch of pointer events to implement implicit pointer capture, dispatch the gotpointercapture and lostpointercaptiure events, and implement the Element APIs for pointer capture: hasPointerCapture(), setPointerCapture() and releasePointerCapture(). Tests: pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down.html pointerevents/ios/pointer-events-implicit-capture-release-exception.html pointerevents/ios/pointer-events-implicit-capture-release.html pointerevents/ios/pointer-events-implicit-capture.html pointerevents/ios/pointer-events-set-pointer-capture-exceptions.html * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * dom/Element.cpp: (WebCore::Element::setPointerCapture): (WebCore::Element::releasePointerCapture): (WebCore::Element::hasPointerCapture): * dom/Element.h: * dom/Element.idl: * dom/EventNames.h: * dom/PointerEvent.h: * page/Page.cpp: (WebCore::Page::Page): * page/Page.h: (WebCore::Page::pointerCaptureController const): * page/PointerCaptureController.cpp: Added. (WebCore::PointerCaptureController::PointerCaptureController): (WebCore::PointerCaptureController::setPointerCapture): (WebCore::PointerCaptureController::releasePointerCapture): (WebCore::PointerCaptureController::hasPointerCapture): (WebCore::PointerCaptureController::pointerLockWasApplied): (WebCore::PointerCaptureController::touchEndedOrWasCancelledForIdentifier): (WebCore::PointerCaptureController::pointerEventWillBeDispatched): (WebCore::PointerCaptureController::pointerEventWasDispatched): (WebCore::PointerCaptureController::processPendingPointerCapture): * page/PointerCaptureController.h: Added. * page/PointerLockController.cpp: (WebCore::PointerLockController::requestPointerLock): * page/PointerLockController.h: LayoutTests: New tests for implicit pointer capture and the Element APIs related to pointer capture. * pointerevents/ios/pointer-events-implicit-capture-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down.html: Added. * pointerevents/ios/pointer-events-implicit-capture-release-exception-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-release-exception.html: Added. * pointerevents/ios/pointer-events-implicit-capture-release-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-release.html: Added. * pointerevents/ios/pointer-events-implicit-capture.html: Added. * pointerevents/ios/pointer-events-set-pointer-capture-exceptions-expected.txt: Added. * pointerevents/ios/pointer-events-set-pointer-capture-exceptions.html: Added. Canonical link: https://commits.webkit.org/208432@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240634 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-29 03:15:02 +00:00
};
Deploy smart pointers in PointerCaptureController https://bugs.webkit.org/show_bug.cgi?id=227352 Reviewed by Wenson Hsieh. Deployed Ref/RefPtr in more places in PointerCaptureController. Also made PointerCaptureController::CapturingData ref counted. * page/PointerCaptureController.cpp: (WebCore::PointerCaptureController::pointerCaptureElement const): (WebCore::PointerCaptureController::setPointerCapture): (WebCore::PointerCaptureController::releasePointerCapture): (WebCore::PointerCaptureController::hasPointerCapture): (WebCore::PointerCaptureController::pointerLockWasApplied): (WebCore::PointerCaptureController::elementWasRemoved): (WebCore::PointerCaptureController::reset): (WebCore::PointerCaptureController::updateHaveAnyCapturingElement): (WebCore::PointerCaptureController::hasCancelledPointerEventForIdentifier const): (WebCore::PointerCaptureController::preventsCompatibilityMouseEventsForIdentifier const): (WebCore::hierarchyHasCapturingEventListeners): (WebCore::PointerCaptureController::dispatchEventForTouchAtIndex): (WebCore::PointerCaptureController::pointerEventForMouseEvent): (WebCore::PointerCaptureController::pointerEventWillBeDispatched): (WebCore::PointerCaptureController::ensureCapturingDataForPointerEvent): (WebCore::PointerCaptureController::pointerEventWasDispatched): (WebCore::PointerCaptureController::cancelPointer): (WebCore::PointerCaptureController::processPendingPointerCapture): * page/PointerCaptureController.h: (WebCore::PointerCaptureController::CapturingData::create): (WebCore::PointerCaptureController::CapturingData::CapturingData): Canonical link: https://commits.webkit.org/239525@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@279749 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-07-08 20:45:38 +00:00
Ref<CapturingData> ensureCapturingDataForPointerEvent(const PointerEvent&);
[iOS] Dispatch additional events along with pointerdown and pointerup https://bugs.webkit.org/show_bug.cgi?id=194776 <rdar://problem/48164284> Reviewed by Brent Fulgham. Source/WebCore: The Pointer Events specification mandates that "pointerover" and "pointerenter" events precede a "pointerdown" event and that "pointerout" and "pointerleave" events follow a "pointerup" event. We remove the EventHandler::dispatchPointerEventForTouchAtIndex() method and replace it with a PointerCaptureController::dispatchEventForTouchAtIndex() that can handle the dispatch of such additional events correctly, also allowing for two PointerCaptureController methods (pointerEventWillBeDispatched and pointerEventWasDispatched) to become private. Test: pointerevents/ios/over-enter-out-leave.html * dom/EventNames.h: Add the new "pointerover", "pointerenter", "pointerout" and "pointerleave" event types. * dom/PointerEvent.h: * dom/ios/PointerEventIOS.cpp: (WebCore::PointerEvent::create): * page/EventHandler.cpp: (WebCore::EventHandler::dispatchPointerEventForTouchAtIndex): Deleted. * page/EventHandler.h: * page/PointerCaptureController.cpp: (WebCore::PointerCaptureController::dispatchEventForTouchAtIndex): Take the existing code from EventHandler::dispatchPointerEventForTouchAtIndex() and extend it to dispatch additional events as mandated. Since several events may be dispatched we check whether the dispatch of any of those events had defaultPrevented() or defaultHanded() return true and return those values as a pair. (WebCore::PointerCaptureController::pointerEventWasDispatched): * page/PointerCaptureController.h: LayoutTests: Added a new test that checks that "pointerover" and "pointerenter" precede "pointerdown" and that "pointerout" and "pointerleave" follow "pointerup". * pointerevents/ios/over-enter-out-leave-expected.txt: Added. * pointerevents/ios/over-enter-out-leave.html: Added. Canonical link: https://commits.webkit.org/209158@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@241723 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-02-18 17:52:34 +00:00
void pointerEventWillBeDispatched(const PointerEvent&, EventTarget*);
void pointerEventWasDispatched(const PointerEvent&);
Deploy smart pointers in PointerCaptureController https://bugs.webkit.org/show_bug.cgi?id=227352 Reviewed by Wenson Hsieh. Deployed Ref/RefPtr in more places in PointerCaptureController. Also made PointerCaptureController::CapturingData ref counted. * page/PointerCaptureController.cpp: (WebCore::PointerCaptureController::pointerCaptureElement const): (WebCore::PointerCaptureController::setPointerCapture): (WebCore::PointerCaptureController::releasePointerCapture): (WebCore::PointerCaptureController::hasPointerCapture): (WebCore::PointerCaptureController::pointerLockWasApplied): (WebCore::PointerCaptureController::elementWasRemoved): (WebCore::PointerCaptureController::reset): (WebCore::PointerCaptureController::updateHaveAnyCapturingElement): (WebCore::PointerCaptureController::hasCancelledPointerEventForIdentifier const): (WebCore::PointerCaptureController::preventsCompatibilityMouseEventsForIdentifier const): (WebCore::hierarchyHasCapturingEventListeners): (WebCore::PointerCaptureController::dispatchEventForTouchAtIndex): (WebCore::PointerCaptureController::pointerEventForMouseEvent): (WebCore::PointerCaptureController::pointerEventWillBeDispatched): (WebCore::PointerCaptureController::ensureCapturingDataForPointerEvent): (WebCore::PointerCaptureController::pointerEventWasDispatched): (WebCore::PointerCaptureController::cancelPointer): (WebCore::PointerCaptureController::processPendingPointerCapture): * page/PointerCaptureController.h: (WebCore::PointerCaptureController::CapturingData::create): (WebCore::PointerCaptureController::CapturingData::CapturingData): Canonical link: https://commits.webkit.org/239525@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@279749 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-07-08 20:45:38 +00:00
Optimize PointerCaptureController::elementWasRemoved() https://bugs.webkit.org/show_bug.cgi?id=221316 Reviewed by Ryosuke Niwa. Speedometer profiles show HashTable iteration code under PointerCaptureController::elementWasRemoved() because we always add a hash entry for the mouse pointer. Optimize away by setting a flag that's only true if any element is referenced by pointer capture. * page/PointerCaptureController.cpp: (WebCore::PointerCaptureController::pointerCaptureElement const): (WebCore::PointerCaptureController::setPointerCapture): (WebCore::PointerCaptureController::releasePointerCapture): (WebCore::PointerCaptureController::hasPointerCapture): (WebCore::PointerCaptureController::pointerLockWasApplied): (WebCore::PointerCaptureController::elementWasRemoved): (WebCore::PointerCaptureController::reset): (WebCore::PointerCaptureController::updateHaveAnyCapturingElement): (WebCore::PointerCaptureController::touchWithIdentifierWasRemoved): (WebCore::PointerCaptureController::hasCancelledPointerEventForIdentifier const): (WebCore::PointerCaptureController::preventsCompatibilityMouseEventsForIdentifier const): (WebCore::PointerCaptureController::pointerCaptureElement): Deleted. (WebCore::PointerCaptureController::hasCancelledPointerEventForIdentifier): Deleted. (WebCore::PointerCaptureController::preventsCompatibilityMouseEventsForIdentifier): Deleted. * page/PointerCaptureController.h: Canonical link: https://commits.webkit.org/233659@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@272331 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-02-03 18:41:16 +00:00
void updateHaveAnyCapturingElement();
Dispatch pointercancel events when content is panned or zoomed on iOS https://bugs.webkit.org/show_bug.cgi?id=193962 <rdar://problem/47629134> Reviewed by Dean Jackson. Source/WebCore: Expose two new methods on PointerCaptureController so that, given a pointer id, it can be established whether this pointer has been cancelled, which is important because a cancelled pointer should no longer dispatch any further pointer events, and to cancel a pointer. Tests: pointerevents/ios/touch-action-pointercancel-pan-x.html pointerevents/ios/touch-action-pointercancel-pan-y.html pointerevents/ios/touch-action-pointercancel-pinch-zoom.html * WebCore.xcodeproj/project.pbxproj: Make PointerCaptureController.h Private so that it can be imported from WebKit. * dom/PointerEvent.h: Remove an unnecessary #if ENABLE(POINTER_EVENTS) since the entire file is already contained in one. Then we add a new create() method that takes an event type, a pointer id and a pointer type (touch vs. pen) that we use to create pointercancel events in PointerCaptureController::cancelPointer(). * page/Page.cpp: (WebCore::Page::Page): Pass the Page as a parameter when creating the PointerCaptureController. * page/PointerCaptureController.cpp: (WebCore::PointerCaptureController::PointerCaptureController): Add a Page reference to the constructor since we'll need the page to access its main frame's EventHandler to perform hit testing in case we do not have a capture target override in cancelPointer(). (WebCore::PointerCaptureController::releasePointerCapture): Drive-by, remove the the implicit parameter since on iOS we don't need to differentiate. We'll bring this back for the macOS work. (WebCore::PointerCaptureController::hasCancelledPointerEventForIdentifier): New method we'll use when dispatching pointer events to identify whether a pointer id has already been cancelled which will allow for _not_ dispatching any further pointer events for this pointer id. (WebCore::PointerCaptureController::pointerEventWillBeDispatched): Keep track of the pointer type so we can preserve it when dispatching pointercancel events for a given pointer id. (WebCore::PointerCaptureController::cancelPointer): Dispatch a pointercancel for the provided pointer id, using the capture target override as the event's target, if there is one, and otherwise hit-testing at the provided location to figure out what the target should be. * page/PointerCaptureController.h: Switch the target overrides from Element* to RefPtr<Element> to ensure it may not be deleted while we still need them. Existing code already ensures these get set to nullptr. Source/WebKit: When a user-agent-provided interaction, such as panning or zooming on iOS, uses a set of touches, we should dispatch a pointercancel event for the pointer ids of the touches involved. To facilitate this, we add a new method on WKContentView to cancel all the pointers matching active touches for a provided UIGestureRecognizer through an async IPC call into the Web process using the new method PointerCaptureController::cancelPointer(). * Platform/spi/ios/UIKitSPI.h: Add the necessary forward declaration for a necessary UIKit SPI allowing us to get the set of last-seen UITouches by the identifier generated for the matching WebKit touch. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView scrollViewWillBeginZooming:withView:]): Dispatch touchcancel events for all pointers involved in a pinch gesture on the top-level UIScrollView. (-[WKWebView _scrollView:adjustedOffsetForOffset:translation:startPoint:locationInView:horizontalVelocity:verticalVelocity:]): Dispatch touchcancel events for all pointers involved in a pan gesture on the top-level UIScrollView. We can infer this by looking at whether the adjusted content offset, after accounting for the permitted touch actions, is different from the original content offset. * UIProcess/PageClient.h: Expose a new virtual cancelPointersForGestureRecognizer() method which will allow the iOS implementation to forward the call to WKContentViewInteraction. (WebKit::PageClient::cancelPointersForGestureRecognizer): * UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h: Expose the WebPageProxy such that we may access it to cancel pointers for a given gesture recognizer from within ScrollingTreeScrollingNodeDelegateIOS. (WebKit::RemoteScrollingCoordinatorProxy::webPageProxy const): * UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.h: * UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm: (-[WKScrollingNodeScrollViewDelegate _scrollView:adjustedOffsetForOffset:translation:startPoint:locationInView:horizontalVelocity:verticalVelocity:]): Dispatch touchcancel events for all pointers involved in a pan gesture on a nested UIScrollView. We can infer this by looking at whether the adjusted content offset, after accounting for the permitted touch actions, is different from the original content offset. (-[WKScrollingNodeScrollViewDelegate scrollViewWillBeginZooming:withView:]): Dispatch touchcancel events for all pointers involved in a pinch gesture on a nested UIScrollView. (-[WKScrollingNodeScrollViewDelegate cancelPointersForGestureRecognizer:]): (WebKit::ScrollingTreeScrollingNodeDelegateIOS::cancelPointersForGestureRecognizer): * UIProcess/WebPageProxy.cpp: (WebKit::WebPageProxy::cancelPointer): * UIProcess/WebPageProxy.h: * UIProcess/ios/PageClientImplIOS.h: * UIProcess/ios/PageClientImplIOS.mm: (WebKit::PageClientImpl::cancelPointersForGestureRecognizer): * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView cancelPointersForGestureRecognizer:]): Obtain all active UITouch objects for the view and dispatch a pointercancel event, through the WebPageProxy, for all touches associated with the provided gesture recognizer. * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::cancelPointer): * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/WebPage.messages.in: LayoutTests: Adding a few tests for "pointercancel" and adding "touch-action: none" on tests that would now be affected by canceling pointers. We also unflake a few tests. * pointerevents/ios/pointer-events-implicit-capture.html: * pointerevents/ios/pointer-events-is-primary.html: * pointerevents/ios/touch-action-pan-x-pan-y.html: * pointerevents/ios/touch-action-pan-x.html: * pointerevents/ios/touch-action-pan-y-expected.txt: * pointerevents/ios/touch-action-pan-y.html: * pointerevents/ios/touch-action-pinch-zoom-allows-zooming.html: * pointerevents/ios/touch-action-pointercancel-pan-x-expected.txt: Added. * pointerevents/ios/touch-action-pointercancel-pan-x.html: Added. * pointerevents/ios/touch-action-pointercancel-pan-y-expected.txt: Added. * pointerevents/ios/touch-action-pointercancel-pan-y.html: Added. * pointerevents/ios/touch-action-pointercancel-pinch-zoom-expected.txt: Added. * pointerevents/ios/touch-action-pointercancel-pinch-zoom.html: Added. Canonical link: https://commits.webkit.org/208642@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240875 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-02-01 21:53:40 +00:00
Page& m_page;
// While PointerID is defined as int32_t, we use int64_t here so that we may use a value outside of the int32_t range to have safe
// empty and removed values, allowing any int32_t to be provided through the API for lookup in this hashmap.
Deploy smart pointers in PointerCaptureController https://bugs.webkit.org/show_bug.cgi?id=227352 Reviewed by Wenson Hsieh. Deployed Ref/RefPtr in more places in PointerCaptureController. Also made PointerCaptureController::CapturingData ref counted. * page/PointerCaptureController.cpp: (WebCore::PointerCaptureController::pointerCaptureElement const): (WebCore::PointerCaptureController::setPointerCapture): (WebCore::PointerCaptureController::releasePointerCapture): (WebCore::PointerCaptureController::hasPointerCapture): (WebCore::PointerCaptureController::pointerLockWasApplied): (WebCore::PointerCaptureController::elementWasRemoved): (WebCore::PointerCaptureController::reset): (WebCore::PointerCaptureController::updateHaveAnyCapturingElement): (WebCore::PointerCaptureController::hasCancelledPointerEventForIdentifier const): (WebCore::PointerCaptureController::preventsCompatibilityMouseEventsForIdentifier const): (WebCore::hierarchyHasCapturingEventListeners): (WebCore::PointerCaptureController::dispatchEventForTouchAtIndex): (WebCore::PointerCaptureController::pointerEventForMouseEvent): (WebCore::PointerCaptureController::pointerEventWillBeDispatched): (WebCore::PointerCaptureController::ensureCapturingDataForPointerEvent): (WebCore::PointerCaptureController::pointerEventWasDispatched): (WebCore::PointerCaptureController::cancelPointer): (WebCore::PointerCaptureController::processPendingPointerCapture): * page/PointerCaptureController.h: (WebCore::PointerCaptureController::CapturingData::create): (WebCore::PointerCaptureController::CapturingData::CapturingData): Canonical link: https://commits.webkit.org/239525@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@279749 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-07-08 20:45:38 +00:00
using PointerIdToCapturingDataMap = HashMap<int64_t, Ref<CapturingData>, WTF::IntHash<int64_t>, WTF::SignedWithZeroKeyHashTraits<int64_t>>;
PointerIdToCapturingDataMap m_activePointerIdsToCapturingData;
[Pointer Events] Respect pointer capture when dispatching mouse boundary events and updating :hover https://bugs.webkit.org/show_bug.cgi?id=198999 <rdar://problem/51979477> Reviewed by Dean Jackson. LayoutTests/imported/w3c: Mark the progressions in 3 WPT tests. * web-platform-tests/pointerevents/pointerevent_boundary_events_at_implicit_release_hoverable_pointers-expected.txt: * web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt: * web-platform-tests/pointerevents/pointerevent_setpointercapture_relatedtarget-expected.txt: Source/WebCore: Up until now, we would not account for pointer capture (see ​https://w3c.github.io/pointerevents/#pointer-capture) when dispatching mouse boundary events (mouseover, mouseout, mouseenter, mouseleave) and their counterpart pointer events. We would also not account for it when updating :hover styles. Now, when pointer capture changes for an element, we call setCapturingMouseEventsElement() on the EventHandler such that the element that would naturally hit-test is overridden by the pointer capture element when identifying which target to use for the dispatch of boundary mouse events. Additionally, when calling Document::prepareMouseEvent(), we also use the pointer capture element to pass down to Document::updateHoverActiveState() such that :hover styles are applied to the correct element. * dom/Document.cpp: (WebCore::Document::prepareMouseEvent): When a new event is going to be dispatched, we must run the Process Pending Capture Element steps as mandated by the Pointer Events spec. Calling this will dispatch the appropriate pointer capture change events and also required boundary events since EventHandler::setCapturingMouseEventsElement() calls into EventHandler::updateMouseEventTargetNode(). Since this may update the capturing mouse events element, we ensure that we call updateHoverActiveState() with a flag that indicates that. Finally, we use the capturing mouse events element instead of the hit-testing element to pass to updateHoverActiveState() to ensure that is has :hover styles applied. (WebCore::Document::updateHoverActiveState): Account for the new CaptureChange flag to force the invalidation of the :hover and :active elements chain at all times when the capturing mouse events element changed. * dom/Document.h: * dom/PointerEvent.h: Update PointerEvent::createForPointerCapture() to take specific parameters rather than a single PointerEvent to set the pointerId, isPrimary and pointerType properties of the generated event. This is required to call processPendingPointerCapture() outside of PointerEvent dispatch logic since we now call it from Document::prepareMouseEvent() where we haven't yet generated such an event. * page/EventHandler.cpp: (WebCore::EventHandler::pointerCaptureElementDidChange): When a new pointer capture element is set, call updateMouseEventTargetNode() to ensure that boundary events are fired to indicate the pointer capture state change. (WebCore::EventHandler::prepareMouseEvent): Keep track of the last PlatformMouseEvent used to prepare a mouse event so that we can use it when setCapturingMouseEventsElement() is called. * page/EventHandler.h: * page/PointerCaptureController.cpp: (WebCore::PointerCaptureController::pointerCaptureElement): Since Document::prepareMouseEvent() needs to know the current pointer capture element, add a new public method that indicates the pointer capture element if that element is contained in the provided document. We need to provide the document since PointerCaptureController is owned by the Page and may manage several documents. (WebCore::PointerCaptureController::dispatchEvent): Only run the Process Pending Capture Element steps when dealing with a touch or pen event since those steps are already ran for mouse events in Document::prepareMouseEvent(). Additionally, since the element target is already set to be the pointer capture element with the changes made to processPendingPointerCapture(), and because on iOS pointer capture is always active, we can remove the code that would retarget the event to the pointer capture element. (WebCore::PointerCaptureController::pointerEventWasDispatched): (WebCore::PointerCaptureController::cancelPointer): (WebCore::PointerCaptureController::processPendingPointerCapture): We now call into EventHandler::setCapturingMouseEventsElement() when the capture target element changes. We must be careful to call this method prior to dispatching the "gotpointercapture" event and after dispatching the "lostpointercapture" event so that boundary events are fired at the right time. * page/PointerCaptureController.h: LayoutTests: Update some WK1-specific expectations. * platform/mac-wk1/imported/w3c/web-platform-tests/pointerevents/pointerevent_boundary_events_at_implicit_release_hoverable_pointers-expected.txt: * platform/mac-wk1/imported/w3c/web-platform-tests/pointerevents/pointerevent_setpointercapture_relatedtarget-expected.txt: Canonical link: https://commits.webkit.org/213414@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@247148 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-07-05 10:25:06 +00:00
bool m_processingPendingPointerCapture { false };
Optimize PointerCaptureController::elementWasRemoved() https://bugs.webkit.org/show_bug.cgi?id=221316 Reviewed by Ryosuke Niwa. Speedometer profiles show HashTable iteration code under PointerCaptureController::elementWasRemoved() because we always add a hash entry for the mouse pointer. Optimize away by setting a flag that's only true if any element is referenced by pointer capture. * page/PointerCaptureController.cpp: (WebCore::PointerCaptureController::pointerCaptureElement const): (WebCore::PointerCaptureController::setPointerCapture): (WebCore::PointerCaptureController::releasePointerCapture): (WebCore::PointerCaptureController::hasPointerCapture): (WebCore::PointerCaptureController::pointerLockWasApplied): (WebCore::PointerCaptureController::elementWasRemoved): (WebCore::PointerCaptureController::reset): (WebCore::PointerCaptureController::updateHaveAnyCapturingElement): (WebCore::PointerCaptureController::touchWithIdentifierWasRemoved): (WebCore::PointerCaptureController::hasCancelledPointerEventForIdentifier const): (WebCore::PointerCaptureController::preventsCompatibilityMouseEventsForIdentifier const): (WebCore::PointerCaptureController::pointerCaptureElement): Deleted. (WebCore::PointerCaptureController::hasCancelledPointerEventForIdentifier): Deleted. (WebCore::PointerCaptureController::preventsCompatibilityMouseEventsForIdentifier): Deleted. * page/PointerCaptureController.h: Canonical link: https://commits.webkit.org/233659@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@272331 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-02-03 18:41:16 +00:00
bool m_haveAnyCapturingElement { false };
Implement capture for Pointer Events on iOS https://bugs.webkit.org/show_bug.cgi?id=193917 <rdar://problem/47605689> Reviewed by Dean Jackson. Source/WebCore: We add a new PointerCaptureController object which gets notified upon dispatch of pointer events to implement implicit pointer capture, dispatch the gotpointercapture and lostpointercaptiure events, and implement the Element APIs for pointer capture: hasPointerCapture(), setPointerCapture() and releasePointerCapture(). Tests: pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down.html pointerevents/ios/pointer-events-implicit-capture-release-exception.html pointerevents/ios/pointer-events-implicit-capture-release.html pointerevents/ios/pointer-events-implicit-capture.html pointerevents/ios/pointer-events-set-pointer-capture-exceptions.html * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * dom/Element.cpp: (WebCore::Element::setPointerCapture): (WebCore::Element::releasePointerCapture): (WebCore::Element::hasPointerCapture): * dom/Element.h: * dom/Element.idl: * dom/EventNames.h: * dom/PointerEvent.h: * page/Page.cpp: (WebCore::Page::Page): * page/Page.h: (WebCore::Page::pointerCaptureController const): * page/PointerCaptureController.cpp: Added. (WebCore::PointerCaptureController::PointerCaptureController): (WebCore::PointerCaptureController::setPointerCapture): (WebCore::PointerCaptureController::releasePointerCapture): (WebCore::PointerCaptureController::hasPointerCapture): (WebCore::PointerCaptureController::pointerLockWasApplied): (WebCore::PointerCaptureController::touchEndedOrWasCancelledForIdentifier): (WebCore::PointerCaptureController::pointerEventWillBeDispatched): (WebCore::PointerCaptureController::pointerEventWasDispatched): (WebCore::PointerCaptureController::processPendingPointerCapture): * page/PointerCaptureController.h: Added. * page/PointerLockController.cpp: (WebCore::PointerLockController::requestPointerLock): * page/PointerLockController.h: LayoutTests: New tests for implicit pointer capture and the Element APIs related to pointer capture. * pointerevents/ios/pointer-events-implicit-capture-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-has-pointer-capture-in-pointer-down.html: Added. * pointerevents/ios/pointer-events-implicit-capture-release-exception-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-release-exception.html: Added. * pointerevents/ios/pointer-events-implicit-capture-release-expected.txt: Added. * pointerevents/ios/pointer-events-implicit-capture-release.html: Added. * pointerevents/ios/pointer-events-implicit-capture.html: Added. * pointerevents/ios/pointer-events-set-pointer-capture-exceptions-expected.txt: Added. * pointerevents/ios/pointer-events-set-pointer-capture-exceptions.html: Added. Canonical link: https://commits.webkit.org/208432@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240634 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-29 03:15:02 +00:00
};
} // namespace WebCore