diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/FrameNode.ts b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/FrameNode.ts index f11c2daafd2139190c095516f16cfcefe581d324..1a0e246b5a1a1a60c5655b53271d9df4daa53671 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/FrameNode.ts +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/FrameNode.ts @@ -902,6 +902,12 @@ export class FrameNode implements MaterializedBase { } } return ArkUIAniModule._Common_getCustomProperty(this!.peer!.ptr, name_casted); + } + public invalidateAttributes(): void { + this.applyAttributesFinish_serialize(); + } + private applyAttributesFinish_serialize(): void { + ArkUIGeneratedNativeModule._FrameNode_applyAttributesFinish(this.peer!.ptr) } } class ImmutableFrameNode extends FrameNode { diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/arkts/ArkUIGeneratedNativeModule.ts b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/arkts/ArkUIGeneratedNativeModule.ts index 94735e2587abb1da36e32fa18544d373b3bb353f..a0250b6a9a47546e711ddb7fe0a412748f1d9647 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/arkts/ArkUIGeneratedNativeModule.ts +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/arkts/ArkUIGeneratedNativeModule.ts @@ -4360,6 +4360,8 @@ export class ArkUIGeneratedNativeModule { @ani.unsafe.Quick native static _FrameNode_unWrapRawPtr(ptr: KPointer): KPointer @ani.unsafe.Direct + native static _FrameNode_applyAttributesFinish(ptr: KPointer): void + @ani.unsafe.Direct native static _LengthMetrics_ctor(): KPointer @ani.unsafe.Direct native static _LengthMetrics_getFinalizer(): KPointer diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala/framework/native/src/generated/arkoala_api_generated.h b/frameworks/bridge/arkts_frontend/koala_projects/arkoala/framework/native/src/generated/arkoala_api_generated.h index a7791d265653ddd639c423d7f820f6244cefb651..c88c4ed7407c07b312ee2d90091e1caffbe6169d 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala/framework/native/src/generated/arkoala_api_generated.h +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala/framework/native/src/generated/arkoala_api_generated.h @@ -25084,6 +25084,7 @@ typedef struct GENERATED_ArkUIFrameNodeAccessor { Ark_Boolean (*getCrossLanguageOptions)(Ark_FrameNode peer); Ark_FrameNode (*createByRawPtr)(void* rawPtr); void* (*unWrapRawPtr)(Ark_FrameNode rawPtr); + void (*applyAttributesFinish)(Ark_FrameNode peer); } GENERATED_ArkUIFrameNodeAccessor; typedef struct GENERATED_ArkUILengthMetricsAccessor { diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala/framework/native/src/generated/bridge_generated.cc b/frameworks/bridge/arkts_frontend/koala_projects/arkoala/framework/native/src/generated/bridge_generated.cc index c6add0708bda724d52151acaa98dee34eeb8b442..08cfa32a0d2b8c478ee111416ad8ac54c92e8fde 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala/framework/native/src/generated/bridge_generated.cc +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala/framework/native/src/generated/bridge_generated.cc @@ -34375,6 +34375,11 @@ Ark_String impl_FrameNode_getNodeType(Ark_NativePointer thisPtr) { return GetAccessors()->getFrameNodeAccessor()->getNodeType(self); } KOALA_INTEROP_1(FrameNode_getNodeType, KStringPtr, Ark_NativePointer) +void impl_FrameNode_applyAttributesFinish(Ark_NativePointer thisPtr) { + Ark_FrameNode self = reinterpret_cast(thisPtr); + return GetAccessors()->getFrameNodeAccessor()->applyAttributesFinish(self); +} +KOALA_INTEROP_DIRECT_V1(FrameNode_applyAttributesFinish, Ark_NativePointer) Ark_NativePointer impl_LengthMetrics_getFinalizer() { return GetAccessors()->getLengthMetricsAccessor()->getFinalizer(); } diff --git a/frameworks/bridge/declarative_frontend/engine/jsXNode.js b/frameworks/bridge/declarative_frontend/engine/jsXNode.js index c9d13436d8f10cb878fce72471235e882435186a..6c006966d64bb9f9b5fba69e9f5f50ebb700ec1c 100644 --- a/frameworks/bridge/declarative_frontend/engine/jsXNode.js +++ b/frameworks/bridge/declarative_frontend/engine/jsXNode.js @@ -1498,6 +1498,12 @@ class FrameNode extends Disposable { getUINativeModule().frameNode.removeSupportedStates(this.getNodePtr(), uiStates); __JSScopeUtil__.restoreInstanceId(); } + invalidateAttributes() { + if (this.nodePtr_ === undefined || this.nodePtr_ === null) { + return; + } + getUINativeModule().frameNode.applyAttributesFinish(this.nodePtr_); + } } class ImmutableFrameNode extends FrameNode { isModifiable() { diff --git a/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_api_impl_bridge.cpp b/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_api_impl_bridge.cpp index 89938682b701a2faf9630a23a9c23bf2b2460a5c..892028325df4fb73ea82a5a41945d5ca52562de0 100644 --- a/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_api_impl_bridge.cpp +++ b/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_api_impl_bridge.cpp @@ -4598,6 +4598,8 @@ void ArkUINativeModule::RegisterFrameNodeAttributes(Local obje panda::FunctionRef::New(const_cast(vm), FrameNodeBridge::UpdateConfiguration)); frameNode->Set(vm, panda::StringRef::NewFromUtf8(vm, "fireArkUIObjectLifecycleCallback"), panda::FunctionRef::New(const_cast(vm), FrameNodeBridge::FireArkUIObjectLifecycleCallback)); + frameNode->Set(vm, panda::StringRef::NewFromUtf8(vm, "applyAttributesFinish"), + panda::FunctionRef::New(const_cast(vm), FrameNodeBridge::ApplyAttributesFinish)); object->Set(vm, panda::StringRef::NewFromUtf8(vm, "frameNode"), frameNode); } diff --git a/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_frame_node_bridge.cpp b/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_frame_node_bridge.cpp index ad9d8fd037f1fa9c16bcff0cecb828bc78d4f7f2..c4162e6e5b58940bcd570ce9396786ad688e074a 100644 --- a/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_frame_node_bridge.cpp +++ b/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_frame_node_bridge.cpp @@ -541,6 +541,15 @@ ArkUINativeModuleValue FrameNodeBridge::Invalidate(ArkUIRuntimeCallInfo* runtime return panda::JSValueRef::Undefined(vm); } +ArkUINativeModuleValue FrameNodeBridge::ApplyAttributesFinish(ArkUIRuntimeCallInfo* runtimeCallInfo) +{ + EcmaVM* vm = runtimeCallInfo->GetVM(); + Local firstArg = runtimeCallInfo->GetCallArgRef(0); + auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value()); + GetArkUINodeModifiers()->getFrameNodeModifier()->applyAttributesFinish(nativeNode); + return panda::JSValueRef::Undefined(vm); +} + void FrameNodeBridge::SetDrawFunc(const RefPtr& frameNode, ArkUIRuntimeCallInfo* runtimeCallInfo) { CHECK_NULL_VOID(frameNode); diff --git a/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_frame_node_bridge.h b/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_frame_node_bridge.h index 619a934007a7c811cf4cf6620b38e8fd776a2d71..633d062697fcfa30d9a85bfb26d7a1397081dcee 100644 --- a/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_frame_node_bridge.h +++ b/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_frame_node_bridge.h @@ -149,6 +149,7 @@ public: static ArkUINativeModuleValue GetInteractionEventBindingInfo(ArkUIRuntimeCallInfo* runtimeCallInfo); static ArkUINativeModuleValue UpdateConfiguration(ArkUIRuntimeCallInfo* runtimeCallInfo); static ArkUINativeModuleValue FireArkUIObjectLifecycleCallback(ArkUIRuntimeCallInfo* runtimeCallInfo); + static ArkUINativeModuleValue ApplyAttributesFinish(ArkUIRuntimeCallInfo* runtimeCallInfo); }; } // namespace OHOS::Ace::NG diff --git a/frameworks/core/interfaces/arkoala/arkoala_api.h b/frameworks/core/interfaces/arkoala/arkoala_api.h index f0da788dfc49bbc9cc8130b498570e087dbc3e4a..955fe5e8b70004fe95b1cff0de366e41f4d53613 100644 --- a/frameworks/core/interfaces/arkoala/arkoala_api.h +++ b/frameworks/core/interfaces/arkoala/arkoala_api.h @@ -6746,6 +6746,7 @@ struct ArkUIFrameNodeModifier { void (*removeSupportedUIStates)(ArkUINodeHandle node, int32_t state); ArkUI_Int32 (*setForceDarkConfig)( ArkUI_Int32 instanceId, bool forceDark, ArkUI_CharPtr nodeTag, uint32_t (*colorInvertFunc)(uint32_t color)); + void (*applyAttributesFinish)(ArkUINodeHandle node); }; struct ArkUINodeContentEvent { diff --git a/frameworks/core/interfaces/native/generated/interface/arkoala_api_generated.h b/frameworks/core/interfaces/native/generated/interface/arkoala_api_generated.h index 8abb4fba3076ad2b81111d13e406872a44fdf839..6e7ca91d8b1688715bb5e685daee500ee51a5841 100644 --- a/frameworks/core/interfaces/native/generated/interface/arkoala_api_generated.h +++ b/frameworks/core/interfaces/native/generated/interface/arkoala_api_generated.h @@ -25070,6 +25070,7 @@ typedef struct GENERATED_ArkUIFrameNodeAccessor { Ark_Boolean (*getCrossLanguageOptions)(Ark_FrameNode peer); Ark_FrameNode (*createByRawPtr)(void* rawPtr); void* (*unWrapRawPtr)(Ark_FrameNode rawPtr); + void (*applyAttributesFinish)(Ark_FrameNode peer); } GENERATED_ArkUIFrameNodeAccessor; typedef struct GENERATED_ArkUILengthMetricsAccessor { diff --git a/frameworks/core/interfaces/native/implementation/frame_node_accessor.cpp b/frameworks/core/interfaces/native/implementation/frame_node_accessor.cpp index 8b0c9358fe95a65142995209f1f07149c2227e53..6d0a789b2e382ec798e5efc088ce9184e396d5a2 100644 --- a/frameworks/core/interfaces/native/implementation/frame_node_accessor.cpp +++ b/frameworks/core/interfaces/native/implementation/frame_node_accessor.cpp @@ -949,6 +949,12 @@ void SetNeedsLayoutImpl(Ark_FrameNode peer) CHECK_NULL_VOID(peerNode); peerNode->MarkDirtyNode(ARKUI_DIRTY_FLAG_MEASURE_SELF_AND_PARENT); } +void ApplyAttributesFinishImpl(Ark_FrameNode peer) +{ + auto frameNode = FrameNodePeer::GetFrameNodeByPeer(peer); + CHECK_NULL_VOID(frameNode); + frameNode->MarkModifyDone(); +} } // FrameNodeAccessor const GENERATED_ArkUIFrameNodeAccessor* GetFrameNodeAccessor() { diff --git a/frameworks/core/interfaces/native/node/frame_node_modifier.cpp b/frameworks/core/interfaces/native/node/frame_node_modifier.cpp index 44c505912a27362f608815e454fc6d056939e364..57352776c21eba67570d01335d378c54420abfc5 100644 --- a/frameworks/core/interfaces/native/node/frame_node_modifier.cpp +++ b/frameworks/core/interfaces/native/node/frame_node_modifier.cpp @@ -73,6 +73,13 @@ void InvalidateInFrameNode(ArkUINodeHandle node) renderContext->RequestNextFrame(); } +void ApplyAttributesFinish(ArkUINodeHandle node) +{ + auto* frameNode = reinterpret_cast(node); + CHECK_NULL_VOID(frameNode); + frameNode->MarkModifyDone(); +} + RefPtr GetParentNode(UINode* node) { auto uiNode = AceType::Claim(node); @@ -1136,6 +1143,7 @@ const ArkUIFrameNodeModifier* GetFrameNodeModifier() .addSupportedUIStates = AddSupportedUIStates, .removeSupportedUIStates = RemoveSupportedUIStates, .setForceDarkConfig = SetForceDarkConfig, + .applyAttributesFinish = ApplyAttributesFinish, }; CHECK_INITIALIZED_FIELDS_END(modifier, 0, 0, 0); // don't move this line return &modifier; diff --git a/interfaces/native/libace.ndk.json b/interfaces/native/libace.ndk.json index ddd60634b877e4a99b813ffa7a0ac404df943f38..e14ab3dda97ae976e1029919b6a0e5c14e66f6ed 100644 --- a/interfaces/native/libace.ndk.json +++ b/interfaces/native/libace.ndk.json @@ -1551,6 +1551,10 @@ "first_introduced": "16", "name": "OH_ArkUI_NodeUtils_MoveTo" }, + { + "first_introduced": "21", + "name": "OH_ArkUI_NativeModule_InvalidateAttributes" + }, { "first_introduced": "15", "name": "OH_ArkUI_NodeUtils_SetCrossLanguageOption" diff --git a/interfaces/native/native_node.h b/interfaces/native/native_node.h index 2790d2ff624d6851e08d686d3bc7b520b9a3caee..0f91f154229754185dd3d21c341876fcfcb93f29 100644 --- a/interfaces/native/native_node.h +++ b/interfaces/native/native_node.h @@ -9439,6 +9439,22 @@ int32_t OH_ArkUI_NodeUtils_GetWindowInfo(ArkUI_NodeHandle node, ArkUI_HostWindow */ int32_t OH_ArkUI_NodeUtils_MoveTo(ArkUI_NodeHandle node, ArkUI_NodeHandle target_parent, int32_t index); +/** + * @brief Triggers node updates in the current frame. + * + * When node attributes are modified after the current frame's build phase (i.e., after + * the unified processing of dirty nodes), the node updates will be deferred to the next + * frame. This function forces immediate node updates within the current frame to + * ensure rendering effects are applied synchronously. + * + * @param node ArkUI_NodeHandle pointer. + * @return Error code. + * {@link ARKUI_ERROR_CODE_NO_ERROR} Success. + * {@link ARKUI_ERROR_CODE_PARAM_INVALID} Function parameter exception. + * @since 21 + */ +int32_t OH_ArkUI_NativeModule_InvalidateAttributes(ArkUI_NodeHandle node); + /** * @brief The event called when the sliding operation offset changes. * diff --git a/interfaces/native/node/node_utils.cpp b/interfaces/native/node/node_utils.cpp index 586d52f170e7355718f56e0ffad31f764edfebeb..96e7132b2374754f6acdf3657498e05d2b16c822 100644 --- a/interfaces/native/node/node_utils.cpp +++ b/interfaces/native/node/node_utils.cpp @@ -504,6 +504,17 @@ int32_t OH_ArkUI_NodeUtils_MoveTo(ArkUI_NodeHandle node, ArkUI_NodeHandle target return errorCode; } +int32_t OH_ArkUI_NativeModule_InvalidateAttributes(ArkUI_NodeHandle node) +{ + if (node == nullptr || !OHOS::Ace::NodeModel::CheckIsCNode(node)) { + return ARKUI_ERROR_CODE_PARAM_INVALID; + } + const auto* impl = OHOS::Ace::NodeModel::GetFullImpl(); + CHECK_NULL_RETURN(impl, ARKUI_ERROR_CODE_CAPI_INIT_ERROR); + impl->getNodeModifiers()->getFrameNodeModifier()->applyAttributesFinish(node->uiNodeHandle); + return ARKUI_ERROR_CODE_NO_ERROR; +} + int32_t OH_ArkUI_NodeUtils_GetFirstChildIndexWithoutExpand(ArkUI_NodeHandle node, uint32_t* index) { if (node == nullptr) {