diff --git a/frameworks/bridge/declarative_frontend/engine/functions/js_gesture_judge_function.cpp b/frameworks/bridge/declarative_frontend/engine/functions/js_gesture_judge_function.cpp index 1b5cddb8b3fc21df8f7ab3bca101049cf61941a1..1c8f20b64a02d73dfe116dbc4570bdb6e97a78fd 100644 --- a/frameworks/bridge/declarative_frontend/engine/functions/js_gesture_judge_function.cpp +++ b/frameworks/bridge/declarative_frontend/engine/functions/js_gesture_judge_function.cpp @@ -68,14 +68,14 @@ GestureJudgeResult JsGestureJudgeFunction::Execute(const std::shared_ptrSetValueAt(othersIdx++, othersObj); } - auto touchRecognizerMap = JsShouldBuiltInRecognizerParallelWithFunction::CreateTouchRecognizerMap(info, current); + auto touchRecognizerMap = CreateTouchRecognizerMap(info, current); JSRef touchRecognizers = JSRef::New(); uint32_t touchRecognizersIdx = 0; - for (auto& [item, recognizerTarget] : touchRecognizerMap) { + for (auto& [item, fingerIds] : touchRecognizerMap) { JSRef recognizerObj = JSClass::NewInstance(); auto jsRecognizer = Referenced::Claim(recognizerObj->Unwrap()); if (jsRecognizer) { - jsRecognizer->SetTouchData(item, recognizerTarget); + jsRecognizer->SetTouchData(item, fingerIds); } touchRecognizers->SetValueAt(touchRecognizersIdx++, recognizerObj); } @@ -89,6 +89,51 @@ GestureJudgeResult JsGestureJudgeFunction::Execute(const std::shared_ptr& info, const RefPtr& current) +{ + TouchRecognizerMap touchRecognizerMap; + auto frameNode = current->GetAttachedNode().Upgrade(); + CHECK_NULL_RETURN(frameNode, touchRecognizerMap); + auto pipeline = frameNode->GetContext(); + CHECK_NULL_RETURN(pipeline, touchRecognizerMap); + auto eventManager = pipeline->GetEventManager(); + CHECK_NULL_RETURN(eventManager, touchRecognizerMap); + auto& touchTestResult = eventManager->touchTestResults_; + const auto& fingerList = info->GetFingerList(); + for (const auto& finger : fingerList) { + auto& touchTargetList = touchTestResult[finger.fingerId_]; + CollectTouchEventTarget(touchRecognizerMap, touchTargetList, AceType::RawPtr(frameNode), finger.fingerId_); + } + return touchRecognizerMap; +} + +void JsGestureJudgeFunction::CollectTouchEventTarget( + TouchRecognizerMap& dict, std::list>& targets, NG::FrameNode* frameNode, int32_t fingerId) +{ + for (auto& target : targets) { + if (AceType::DynamicCast(target)) { + continue; + } + auto weakTarget = WeakPtr(target); + if (dict.find(weakTarget) != dict.end() && dict[weakTarget].count(fingerId) > 0) { + continue; + } + auto targetNode = target->GetAttachedNode().Upgrade(); + if (targetNode && targetNode == frameNode) { + dict[weakTarget].insert(fingerId); + return; + } + while (targetNode) { + if (targetNode == frameNode) { + dict[weakTarget].insert(fingerId); + break; + } + targetNode = targetNode->GetParentFrameNode(); + } + } +} + JSRef JsGestureJudgeFunction::CreateFingerInfo(const FingerInfo& fingerInfo) { JSRef fingerInfoObj = JSRef::New(); diff --git a/frameworks/bridge/declarative_frontend/engine/functions/js_gesture_judge_function.h b/frameworks/bridge/declarative_frontend/engine/functions/js_gesture_judge_function.h index 9669704753e558305d9a65e9e642974a7469b6d2..af13a716d58565fcc13761a671428025d6754947 100644 --- a/frameworks/bridge/declarative_frontend/engine/functions/js_gesture_judge_function.h +++ b/frameworks/bridge/declarative_frontend/engine/functions/js_gesture_judge_function.h @@ -26,6 +26,7 @@ #include "frameworks/bridge/declarative_frontend/engine/functions/js_function.h" namespace OHOS::Ace::Framework { +using TouchRecognizerMap = std::map, std::unordered_set>; class JsGestureJudgeFunction : public JsFunction { DECLARE_ACE_TYPE(JsGestureJudgeFunction, JsFunction) @@ -53,6 +54,10 @@ private: JSRef CreateGestureEventObject(const std::shared_ptr& info, GestureTypeName typeName); JSRef CreateFingerInfosObject(const std::shared_ptr& info, JSRef& obj); void ParsePanGestureEvent(JSRef& obj, const std::shared_ptr& info); + static TouchRecognizerMap CreateTouchRecognizerMap( + const std::shared_ptr& info, const RefPtr& current); + static void CollectTouchEventTarget(TouchRecognizerMap& dict, std::list>& targets, + NG::FrameNode* borderNode, int32_t fingerId); }; } // namespace OHOS::Ace::Framework diff --git a/frameworks/bridge/declarative_frontend/engine/functions/js_gesture_recognizer.cpp b/frameworks/bridge/declarative_frontend/engine/functions/js_gesture_recognizer.cpp index 957e4647a1573bbf5044def096ea14610feb8071..1edc39ced33abfb8adceaf0283e4b720962662b6 100644 --- a/frameworks/bridge/declarative_frontend/engine/functions/js_gesture_recognizer.cpp +++ b/frameworks/bridge/declarative_frontend/engine/functions/js_gesture_recognizer.cpp @@ -298,29 +298,46 @@ void JSSwipeRecognizer::GetSpeed(const JSCallbackInfo& args) void JSTouchRecognizer::CancelTouch(const JSCallbackInfo& args) { - if (touchRecognizerTarget_.empty()) { - TAG_LOGW(AceLogTag::ACE_GESTURE, "touchRecognizerTarget_ is empty."); + if (fingerIds_.empty()) { + TAG_LOGW(AceLogTag::ACE_GESTURE, "fingerIds_ is empty."); return; } - CHECK_NULL_VOID(target_); - auto node = target_->GetAttachedNode().Upgrade(); + auto target = target_.Upgrade(); + CHECK_NULL_VOID(target); + auto node = target->GetAttachedNode().Upgrade(); CHECK_NULL_VOID(node); auto pipeline = node->GetContext(); CHECK_NULL_VOID(pipeline); auto eventManager = pipeline->GetEventManager(); CHECK_NULL_VOID(eventManager); - - eventManager->DispatchTouchCancelToRecognizer(target_, touchRecognizerTarget_); - touchRecognizerTarget_.clear(); + auto& touchTestResult = eventManager->touchTestResults_; + std::vector> legacyTarget; + for (const auto& fingerId : fingerIds_) { + if (touchTestResult.find(fingerId) == touchTestResult.end()) { + continue; + } + + auto& targetsList = touchTestResult[fingerId]; + auto it = std::find_if(targetsList.begin(), targetsList.end(), + [&target](const RefPtr& t) { return t == target; }); + + if (it != targetsList.end()) { + legacyTarget.emplace_back(fingerId, it); + } + } + + eventManager->DispatchTouchCancelToRecognizer(RawPtr(target), legacyTarget); + fingerIds_.clear(); } void JSTouchRecognizer::GetEventTargetInfo(const JSCallbackInfo& args) { - if (!target_) { + auto target = target_.Upgrade(); + if (!target) { args.SetReturnValue(JSClass::NewInstance()); return; } - auto attachNode = target_->GetAttachedNode().Upgrade(); + auto attachNode = target->GetAttachedNode().Upgrade(); if (!attachNode) { args.SetReturnValue(JSClass::NewInstance()); return; diff --git a/frameworks/bridge/declarative_frontend/engine/functions/js_gesture_recognizer.h b/frameworks/bridge/declarative_frontend/engine/functions/js_gesture_recognizer.h index 04ca97daef06803ff64d54a468e7544911e13583..c9e2b6737e0b39118177f29ac82b5bbc18e20db4 100644 --- a/frameworks/bridge/declarative_frontend/engine/functions/js_gesture_recognizer.h +++ b/frameworks/bridge/declarative_frontend/engine/functions/js_gesture_recognizer.h @@ -40,9 +40,6 @@ enum class GestureRecognizerState { FAIL = 5, }; -using TouchRecognizerTarget = std::vector>; -using TouchRecognizerMap = std::map; - class JSEventTargetInfo : public Referenced { public: static void JSBind(BindingTarget globalObj); @@ -409,10 +406,10 @@ public: void GetEventTargetInfo(const JSCallbackInfo& args); void CancelTouch(const JSCallbackInfo& args); - void SetTouchData(TouchEventTarget* target, TouchRecognizerTarget& touchRecognizerTarget) + void SetTouchData(const WeakPtr& target, const std::unordered_set& fingerIds) { - target_ = target; - touchRecognizerTarget_ = touchRecognizerTarget; + target_ = std::move(target); + fingerIds_ = std::move(fingerIds); } private: @@ -430,8 +427,8 @@ private: } } - TouchEventTarget* target_; - TouchRecognizerTarget touchRecognizerTarget_; + WeakPtr target_; + std::unordered_set fingerIds_; }; } // namespace OHOS::Ace::Framework #endif // FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_ENGINE_FUNCTION_JS_GESTURE_RECOGNIZER_H \ No newline at end of file diff --git a/frameworks/bridge/declarative_frontend/engine/functions/js_should_built_in_recognizer_parallel_with_function.cpp b/frameworks/bridge/declarative_frontend/engine/functions/js_should_built_in_recognizer_parallel_with_function.cpp index b815954f27b965fd4074ce7d1b73d4b4ee689125..2cdfe1cb830fb65fbc39302da21847fd23cf30c0 100644 --- a/frameworks/bridge/declarative_frontend/engine/functions/js_should_built_in_recognizer_parallel_with_function.cpp +++ b/frameworks/bridge/declarative_frontend/engine/functions/js_should_built_in_recognizer_parallel_with_function.cpp @@ -94,56 +94,4 @@ JSRef JsShouldBuiltInRecognizerParallelWithFunction::CreateRecognizerO currentRecognizer->Update(target); return recognizerObj; } - -TouchRecognizerMap JsShouldBuiltInRecognizerParallelWithFunction::CreateTouchRecognizerMap( - const std::shared_ptr& info, const RefPtr& current) -{ - TouchRecognizerMap touchRecognizerMap; - auto frameNode = current->GetAttachedNode().Upgrade(); - CHECK_NULL_RETURN(frameNode, touchRecognizerMap); - auto pipeline = frameNode->GetContext(); - CHECK_NULL_RETURN(pipeline, touchRecognizerMap); - auto eventManager = pipeline->GetEventManager(); - CHECK_NULL_RETURN(eventManager, touchRecognizerMap); - auto& touchTestResult = eventManager->touchTestResults_; - const auto& fingerList = info->GetFingerList(); - for (const auto& finger : fingerList) { - auto& touchTargetList = touchTestResult[finger.fingerId_]; - CollectTouchEventTarget(touchRecognizerMap, touchTargetList, AceType::RawPtr(frameNode), finger.fingerId_); - } - return touchRecognizerMap; -} - -void JsShouldBuiltInRecognizerParallelWithFunction::CollectTouchEventTarget( - TouchRecognizerMap& dict, std::list>& targets, NG::FrameNode* borderNode, int32_t fingerId) -{ - for (auto iter = targets.begin(); iter != targets.end(); ++iter) { - auto& target = *iter; - if (AceType::DynamicCast(target)) { - continue; - } - auto targetPtr = AceType::RawPtr(target); - if (dict.find(targetPtr) != dict.end() && IsFingerCollectedByTarget(dict[targetPtr], fingerId)) { - continue; - } - auto targetNode = target->GetAttachedNode().Upgrade(); - if (targetNode && targetNode == borderNode) { - dict[targetPtr].emplace_back(fingerId, iter); - return; - } - while (targetNode) { - if (targetNode == borderNode) { - dict[targetPtr].emplace_back(fingerId, iter); - break; - } - targetNode = targetNode->GetParentFrameNode(); - } - } -} - -bool JsShouldBuiltInRecognizerParallelWithFunction::IsFingerCollectedByTarget( - const TouchRecognizerTarget& target, int32_t fingerId) -{ - return std::any_of(target.begin(), target.end(), [fingerId](const auto& item) { return item.first == fingerId; }); -} } // namespace OHOS::Ace::Framework diff --git a/frameworks/bridge/declarative_frontend/engine/functions/js_should_built_in_recognizer_parallel_with_function.h b/frameworks/bridge/declarative_frontend/engine/functions/js_should_built_in_recognizer_parallel_with_function.h index c362b231652353fa9d6727ccce1a75038f6dd4ed..a0d758bf608c5ae478448af2759b6ae06d70cc40 100644 --- a/frameworks/bridge/declarative_frontend/engine/functions/js_should_built_in_recognizer_parallel_with_function.h +++ b/frameworks/bridge/declarative_frontend/engine/functions/js_should_built_in_recognizer_parallel_with_function.h @@ -37,13 +37,6 @@ public: RefPtr Execute( const RefPtr& current, const std::vector>& others); static JSRef CreateRecognizerObject(const RefPtr& target); - static TouchRecognizerMap CreateTouchRecognizerMap( - const std::shared_ptr& info, const RefPtr& current); - static void CollectTouchEventTarget(TouchRecognizerMap& dict, std::list>& targets, - NG::FrameNode* borderNode, int32_t fingerId); - -private: - static bool IsFingerCollectedByTarget(const TouchRecognizerTarget& target, int32_t fingerId); }; } // namespace OHOS::Ace::Framework diff --git a/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_common_bridge.cpp b/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_common_bridge.cpp index 08c08276366247b6e3685467e11ba0a336aed6f1..f6a28466b1940e6df04d5e3c209939cee215ab5a 100644 --- a/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_common_bridge.cpp +++ b/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_common_bridge.cpp @@ -7107,21 +7107,65 @@ Local CommonBridge::CreateTouchRecognizersObject( const auto& fingerList = info->GetFingerList(); for (const auto& finger : fingerList) { auto& touchTargetList = touchTestResult[finger.fingerId_]; - JsShouldBuiltInRecognizerParallelWithFunction::CollectTouchEventTarget( - touchRecognizerMap, touchTargetList, AceType::RawPtr(frameNode), finger.fingerId_); + CollectTouchEventTarget(touchRecognizerMap, touchTargetList, AceType::RawPtr(frameNode), finger.fingerId_); } uint32_t touchRecognizersIdx = 0; - for (auto& [item, recognizerTarget] : touchRecognizerMap) { + for (auto& [item, fingerIds] : touchRecognizerMap) { JSRef recognizerObj = JSClass::NewInstance(); auto jsRecognizer = Referenced::Claim(recognizerObj->Unwrap()); if (jsRecognizer) { - jsRecognizer->SetTouchData(item, recognizerTarget); + jsRecognizer->SetTouchData(item, fingerIds); } touchRecognizers->SetValueAt(vm, touchRecognizers, touchRecognizersIdx++, recognizerObj->GetLocalHandle()); } return touchRecognizers; } +TouchRecognizerMap CommonBridge::CreateTouchRecognizerMap( + const std::shared_ptr& info, const RefPtr& current) +{ + TouchRecognizerMap touchRecognizerMap; + auto frameNode = current->GetAttachedNode().Upgrade(); + CHECK_NULL_RETURN(frameNode, touchRecognizerMap); + auto pipeline = frameNode->GetContext(); + CHECK_NULL_RETURN(pipeline, touchRecognizerMap); + auto eventManager = pipeline->GetEventManager(); + CHECK_NULL_RETURN(eventManager, touchRecognizerMap); + auto& touchTestResult = eventManager->touchTestResults_; + const auto& fingerList = info->GetFingerList(); + for (const auto& finger : fingerList) { + auto& touchTargetList = touchTestResult[finger.fingerId_]; + CollectTouchEventTarget(touchRecognizerMap, touchTargetList, AceType::RawPtr(frameNode), finger.fingerId_); + } + return touchRecognizerMap; +} + +void CommonBridge::CollectTouchEventTarget( + TouchRecognizerMap& dict, std::list>& targets, NG::FrameNode* frameNode, int32_t fingerId) +{ + for (auto& target : targets) { + if (AceType::DynamicCast(target)) { + continue; + } + auto weakTarget = WeakPtr(target); + if (dict.find(weakTarget) != dict.end() && dict[weakTarget].count(fingerId) > 0) { + continue; + } + auto targetNode = target->GetAttachedNode().Upgrade(); + if (targetNode && targetNode == frameNode) { + dict[weakTarget].insert(fingerId); + return; + } + while (targetNode) { + if (targetNode == frameNode) { + dict[weakTarget].insert(fingerId); + break; + } + targetNode = targetNode->GetParentFrameNode(); + } + } +} + Local CommonBridge::CreateFingerInfo(EcmaVM* vm, const FingerInfo& fingerInfo) { const OHOS::Ace::Offset& globalLocation = fingerInfo.globalLocation_; diff --git a/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_common_bridge.h b/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_common_bridge.h index 6fe39abcc0719d2b5c9401b9ff984093f8939a78..3ed39998081b5445a06f992f8f274fcb1bbee71d 100644 --- a/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_common_bridge.h +++ b/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_common_bridge.h @@ -21,6 +21,7 @@ #include "core/event/focus_axis_event.h" namespace OHOS::Ace::NG { +using TouchRecognizerMap = std::map, std::unordered_set>; class CommonBridge { public: static ArkUINativeModuleValue SetBackgroundColor(ArkUIRuntimeCallInfo* runtimeCallInfo); @@ -297,6 +298,10 @@ public: static Local CreateRecognizerObject(EcmaVM* vm, const RefPtr& target); static Local CreateTouchRecognizersObject( EcmaVM* vm, const std::shared_ptr& info, const RefPtr& target); + static TouchRecognizerMap CreateTouchRecognizerMap( + const std::shared_ptr& info, const RefPtr& current); + static void CollectTouchEventTarget(TouchRecognizerMap& dict, std::list>& targets, + NG::FrameNode* borderNode, int32_t fingerId); static Local CreateFingerInfo(EcmaVM* vm, const FingerInfo& fingerInfo); static Local CreateEventTargetObject(EcmaVM* vm, const std::shared_ptr& info); static Local CreateAreaObject(EcmaVM* vm, const RectF& rect, const OffsetF& origin);