From d469a0f932c3ea128e4ff2a799a254e7ab38fc7e Mon Sep 17 00:00:00 2001 From: Eric Rozell Date: Mon, 31 Jul 2023 07:58:45 -0700 Subject: [PATCH] Allow out-of-tree platforms to extend Touch fields (#38681) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/38681 Desktop platforms send additional information with onTouch(Start|Move|End|Cancel) events, including modifier keys and mouse button information. This information has not historically been available for mobile platforms, so rather than blindly adding the fields, this change adds a hook for out-of-tree platforms to extend the data in nativeEvent payload for Fabric Touch events. ## Changelog: [General] [Added] - Support customization of underlying Touch event representation in out-of-tree platforms Reviewed By: christophpurrer Differential Revision: D47896016 fbshipit-source-id: 1e40f1f633387d368c5f642290b192174d53551a --- .../view/{Touch.cpp => BaseTouch.cpp} | 20 +++- .../renderer/components/view/BaseTouch.h | 91 +++++++++++++++++++ .../react/renderer/components/view/Touch.h | 76 +--------------- .../components/view/TouchEventEmitter.cpp | 16 ---- .../components/view/HostPlatformTouch.h | 14 +++ .../components/view/HostPlatformTouch.h | 14 +++ 6 files changed, 139 insertions(+), 92 deletions(-) rename packages/react-native/ReactCommon/react/renderer/components/view/{Touch.cpp => BaseTouch.cpp} (53%) create mode 100644 packages/react-native/ReactCommon/react/renderer/components/view/BaseTouch.h create mode 100644 packages/react-native/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/HostPlatformTouch.h create mode 100644 packages/react-native/ReactCommon/react/renderer/components/view/platform/cxx/react/renderer/components/view/HostPlatformTouch.h diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/Touch.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/BaseTouch.cpp similarity index 53% rename from packages/react-native/ReactCommon/react/renderer/components/view/Touch.cpp rename to packages/react-native/ReactCommon/react/renderer/components/view/BaseTouch.cpp index ee3fc314e713cb..9c3f444c150b7d 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/Touch.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/BaseTouch.cpp @@ -9,14 +9,30 @@ namespace facebook::react { +void setTouchPayloadOnObject( + jsi::Object &object, + jsi::Runtime &runtime, + BaseTouch const &touch) { + object.setProperty(runtime, "locationX", touch.offsetPoint.x); + object.setProperty(runtime, "locationY", touch.offsetPoint.y); + object.setProperty(runtime, "pageX", touch.pagePoint.x); + object.setProperty(runtime, "pageY", touch.pagePoint.y); + object.setProperty(runtime, "screenX", touch.screenPoint.x); + object.setProperty(runtime, "screenY", touch.screenPoint.y); + object.setProperty(runtime, "identifier", touch.identifier); + object.setProperty(runtime, "target", touch.target); + object.setProperty(runtime, "timestamp", touch.timestamp * 1000); + object.setProperty(runtime, "force", touch.force); +} + #if RN_DEBUG_STRING_CONVERTIBLE -std::string getDebugName(Touch const & /*touch*/) { +std::string getDebugName(BaseTouch const & /*touch*/) { return "Touch"; } std::vector getDebugProps( - Touch const &touch, + BaseTouch const &touch, DebugStringConvertibleOptions options) { return { {"pagePoint", getDebugDescription(touch.pagePoint, options)}, diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/BaseTouch.h b/packages/react-native/ReactCommon/react/renderer/components/view/BaseTouch.h new file mode 100644 index 00000000000000..8e867c205e9600 --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/components/view/BaseTouch.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include +#include + +namespace facebook::react { + +/* + * Describes an individual touch point for a touch event. + * See https://www.w3.org/TR/touch-events/ for more details. + */ +struct BaseTouch { + /* + * The coordinate of point relative to the root component in points. + */ + Point pagePoint; + + /* + * The coordinate of point relative to the target component in points. + */ + Point offsetPoint; + + /* + * The coordinate of point relative to the screen component in points. + */ + Point screenPoint; + + /* + * An identification number for each touch point. + */ + int identifier; + + /* + * The tag of a component on which the touch point started when it was first + * placed on the surface, even if the touch point has since moved outside the + * interactive area of that element. + */ + Tag target; + + /* + * The force of the touch. + */ + Float force; + + /* + * The time in seconds when the touch occurred or when it was last mutated. + */ + Float timestamp; + + /* + * The particular implementation of `Hasher` and (especially) `Comparator` + * make sense only when `Touch` object is used as a *key* in indexed + * collections. Because of that they are expressed as separate classes. + */ + struct Hasher { + size_t operator()(BaseTouch const &touch) const { + return std::hash()(touch.identifier); + } + }; + + struct Comparator { + bool operator()(BaseTouch const &lhs, BaseTouch const &rhs) const { + return lhs.identifier == rhs.identifier; + } + }; +}; + +void setTouchPayloadOnObject( + jsi::Object &object, + jsi::Runtime &runtime, + BaseTouch const &touch); + +#if RN_DEBUG_STRING_CONVERTIBLE + +std::string getDebugName(BaseTouch const &touch); +std::vector getDebugProps( + BaseTouch const &touch, + DebugStringConvertibleOptions options); + +#endif + +} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/Touch.h b/packages/react-native/ReactCommon/react/renderer/components/view/Touch.h index cf540f2407117f..98089756363a8e 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/Touch.h +++ b/packages/react-native/ReactCommon/react/renderer/components/view/Touch.h @@ -7,81 +7,9 @@ #pragma once -#include -#include -#include +#include namespace facebook::react { - -/* - * Describes an individual touch point for a touch event. - * See https://www.w3.org/TR/touch-events/ for more details. - */ -struct Touch { - /* - * The coordinate of point relative to the root component in points. - */ - Point pagePoint; - - /* - * The coordinate of point relative to the target component in points. - */ - Point offsetPoint; - - /* - * The coordinate of point relative to the screen component in points. - */ - Point screenPoint; - - /* - * An identification number for each touch point. - */ - int identifier; - - /* - * The tag of a component on which the touch point started when it was first - * placed on the surface, even if the touch point has since moved outside the - * interactive area of that element. - */ - Tag target; - - /* - * The force of the touch. - */ - Float force; - - /* - * The time in seconds when the touch occurred or when it was last mutated. - */ - Float timestamp; - - /* - * The particular implementation of `Hasher` and (especially) `Comparator` - * make sense only when `Touch` object is used as a *key* in indexed - * collections. Because of that they are expressed as separate classes. - */ - struct Hasher { - size_t operator()(Touch const &touch) const { - return std::hash()(touch.identifier); - } - }; - - struct Comparator { - bool operator()(Touch const &lhs, Touch const &rhs) const { - return lhs.identifier == rhs.identifier; - } - }; -}; - +using Touch = HostPlatformTouch; using Touches = std::unordered_set; - -#if RN_DEBUG_STRING_CONVERTIBLE - -std::string getDebugName(Touch const &touch); -std::vector getDebugProps( - Touch const &touch, - DebugStringConvertibleOptions options); - -#endif - } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/TouchEventEmitter.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/TouchEventEmitter.cpp index 661d9ac5073002..dcfe9aa58e4763 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/TouchEventEmitter.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/TouchEventEmitter.cpp @@ -11,22 +11,6 @@ namespace facebook::react { #pragma mark - Touches -static void setTouchPayloadOnObject( - jsi::Object &object, - jsi::Runtime &runtime, - Touch const &touch) { - object.setProperty(runtime, "locationX", touch.offsetPoint.x); - object.setProperty(runtime, "locationY", touch.offsetPoint.y); - object.setProperty(runtime, "pageX", touch.pagePoint.x); - object.setProperty(runtime, "pageY", touch.pagePoint.y); - object.setProperty(runtime, "screenX", touch.screenPoint.x); - object.setProperty(runtime, "screenY", touch.screenPoint.y); - object.setProperty(runtime, "identifier", touch.identifier); - object.setProperty(runtime, "target", touch.target); - object.setProperty(runtime, "timestamp", touch.timestamp * 1000); - object.setProperty(runtime, "force", touch.force); -} - static jsi::Value touchesPayload( jsi::Runtime &runtime, Touches const &touches) { diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/HostPlatformTouch.h b/packages/react-native/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/HostPlatformTouch.h new file mode 100644 index 00000000000000..0d441117751c89 --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/HostPlatformTouch.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include + +namespace facebook::react { +using HostPlatformTouch = BaseTouch; +} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/platform/cxx/react/renderer/components/view/HostPlatformTouch.h b/packages/react-native/ReactCommon/react/renderer/components/view/platform/cxx/react/renderer/components/view/HostPlatformTouch.h new file mode 100644 index 00000000000000..0d441117751c89 --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/components/view/platform/cxx/react/renderer/components/view/HostPlatformTouch.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include + +namespace facebook::react { +using HostPlatformTouch = BaseTouch; +} // namespace facebook::react