diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index adcb41b066..4a60167953 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -26,7 +26,7 @@ Code must be portable, memory-efficient, and bare-metal safe. ## Embedded Performance (flag in hot paths) - No heap allocation in draw loops, event handlers, timer callbacks -- Avoid `lv_obj_belongs_to_display()` in internal callbacks — walks parent chain plus scans display screen lists +- Avoid `lv_obj_is_in_widget_tree()` in internal callbacks — walks parent chain plus scans display screen lists - `lv_free(NULL)` is safe — no redundant NULL check before it ## Naming & Style diff --git a/.github/instructions/c-code.instructions.md b/.github/instructions/c-code.instructions.md index c88ac2932c..03a4e76c0a 100644 --- a/.github/instructions/c-code.instructions.md +++ b/.github/instructions/c-code.instructions.md @@ -24,7 +24,7 @@ applyTo: "src/**/*.c,src/**/*.h" - No heap allocation in hot paths (draw loops, event handlers, timer callbacks) - Prefer stack allocation for small temporary buffers -- Avoid `lv_obj_belongs_to_display()` in internal callbacks — it walks up the parent chain and scans every display's screen list +- Avoid `lv_obj_is_in_widget_tree()` in internal callbacks — it walks up the parent chain and scans every display's screen list - Cache-friendly access: sequential over random - Struct member ordering: pointers first, then int32_t, then smaller types/bitfields — minimizes padding diff --git a/Kconfig b/Kconfig index ca51a6bfe5..1ab96f9472 100644 --- a/Kconfig +++ b/Kconfig @@ -881,16 +881,16 @@ menu "LVGL configuration" depends on LV_USE_CHECK_ARG help When enabled, LV_CHECK_OBJ also verifies that the object is - still part of the widget tree (lv_obj_belongs_to_display). When + still part of the widget tree (lv_obj_is_in_widget_tree). When disabled, the validity check is skipped (only the class/NULL check remains). config LV_USE_CHECK_OBJ_PARENT_LINK - bool "Enable parent-link consistency check in lv_obj_belongs_to_display" + bool "Enable parent-link consistency check in lv_obj_is_in_widget_tree" default n depends on LV_USE_CHECK_OBJ_VALIDITY help - When enabled, lv_obj_belongs_to_display verifies — while walking + When enabled, lv_obj_is_in_widget_tree verifies — while walking up the parent chain — that each parent's children array actually contains the child. This catches corruption where a child's parent pointer disagrees with the parent's children list. Slower diff --git a/include/lvgl/config/lv_conf_internal.h b/include/lvgl/config/lv_conf_internal.h index 9f81902b81..1b077c6112 100644 --- a/include/lvgl/config/lv_conf_internal.h +++ b/include/lvgl/config/lv_conf_internal.h @@ -1582,7 +1582,7 @@ #endif /** If enabled, LV_CHECK_OBJ will also verify that the object is still part of the - * widget tree (lv_obj_belongs_to_display). When disabled the validity check is skipped + * widget tree (lv_obj_is_in_widget_tree). When disabled the validity check is skipped * (only the class/NULL check remains). * Requires LV_USE_CHECK_ARG to be enabled. */ #ifndef LV_USE_CHECK_OBJ_VALIDITY @@ -1593,7 +1593,7 @@ #endif #endif -/** If enabled, lv_obj_belongs_to_display will verify — while walking up the parent chain — +/** If enabled, lv_obj_is_in_widget_tree will verify — while walking up the parent chain — * that each parent's children array actually contains the child. * This catches corruption where a child's parent pointer disagrees with the * parent's children list. Slower than the basic reachability check (O(siblings) diff --git a/include/lvgl/core/lv_obj.h b/include/lvgl/core/lv_obj.h index 56ccb376d5..020eaf728b 100644 --- a/include/lvgl/core/lv_obj.h +++ b/include/lvgl/core/lv_obj.h @@ -702,12 +702,12 @@ const lv_obj_class_t * lv_obj_get_class(const lv_obj_t * obj); * @param obj pointer to an object * @return true if the root of `obj`'s parent chain is a registered screen */ -bool lv_obj_belongs_to_display(const lv_obj_t * obj); +bool lv_obj_is_in_widget_tree(const lv_obj_t * obj); /** - * @deprecated Use `lv_obj_belongs_to_display` instead. + * @deprecated Use `lv_obj_is_in_widget_tree` instead. */ -LV_DEPRECATED("Use lv_obj_belongs_to_display instead") +LV_DEPRECATED("Use lv_obj_is_in_widget_tree instead") bool lv_obj_is_valid(const lv_obj_t * obj); /** @@ -880,7 +880,7 @@ void lv_objid_builtin_destroy(void); LV_DEPRECATED_MACRO_WARN("LV_ASSERT_OBJ is deprecated. Use LV_CHECK_OBJ instead."); \ LV_ASSERT_MSG(obj_p != NULL, "The object is NULL"); \ LV_ASSERT_MSG(lv_obj_has_class(obj_p, obj_class) == true, "Incompatible object type."); \ - LV_ASSERT_MSG(lv_obj_belongs_to_display(obj_p) == true, "The object is invalid, deleted or corrupted?"); \ + LV_ASSERT_MSG(lv_obj_is_in_widget_tree(obj_p) == true, "The object is invalid, deleted or corrupted?"); \ } while(0) # else /** diff --git a/include/lvgl/debugging/lv_check_obj.h b/include/lvgl/debugging/lv_check_obj.h index 9e64a14c98..930fc177e9 100644 --- a/include/lvgl/debugging/lv_check_obj.h +++ b/include/lvgl/debugging/lv_check_obj.h @@ -63,7 +63,7 @@ extern "C" { */ #define LV_CHECK_OBJ_VALID(obj, cls, action) \ LV_CHECK_OBJ_CLASS(obj, cls, action); \ - LV_CHECK_ARG(lv_obj_belongs_to_display(obj), action); + LV_CHECK_ARG(lv_obj_is_in_widget_tree(obj), action); #else #define LV_CHECK_OBJ_VALID(obj, cls, action) LV_CHECK_OBJ_CLASS(obj, cls, action); #endif diff --git a/lv_conf_template.h b/lv_conf_template.h index a850109a43..9efeb279a2 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -555,12 +555,12 @@ #define LV_USE_CHECK_OBJ_CLASSTYPE 0 /** If enabled, LV_CHECK_OBJ will also verify that the object is still part of the - * widget tree (lv_obj_belongs_to_display). When disabled the validity check is skipped + * widget tree (lv_obj_is_in_widget_tree). When disabled the validity check is skipped * (only the class/NULL check remains). * Requires LV_USE_CHECK_ARG to be enabled. */ #define LV_USE_CHECK_OBJ_VALIDITY 0 -/** If enabled, lv_obj_belongs_to_display will verify — while walking up the parent chain — +/** If enabled, lv_obj_is_in_widget_tree will verify — while walking up the parent chain — * that each parent's children array actually contains the child. * This catches corruption where a child's parent pointer disagrees with the * parent's children list. Slower than the basic reachability check (O(siblings) diff --git a/src/core/lv_obj.c b/src/core/lv_obj.c index 8bf225ad65..a97897b519 100644 --- a/src/core/lv_obj.c +++ b/src/core/lv_obj.c @@ -1125,7 +1125,7 @@ const lv_obj_class_t * lv_obj_get_class(const lv_obj_t * obj) return obj->class_p; } -bool lv_obj_belongs_to_display(const lv_obj_t * obj) +bool lv_obj_is_in_widget_tree(const lv_obj_t * obj) { LV_CHECK_ARG(obj != NULL, return false); /* Can't use LV_CHECK_OBJ here, it could cause an infinite recursion loop. */ @@ -1151,7 +1151,7 @@ bool lv_obj_belongs_to_display(const lv_obj_t * obj) bool lv_obj_is_valid(const lv_obj_t * obj) { - return lv_obj_belongs_to_display(obj); + return lv_obj_is_in_widget_tree(obj); } void lv_obj_null_on_delete(lv_obj_t ** obj_ptr) diff --git a/src/core/lv_obj_tree.c b/src/core/lv_obj_tree.c index 2ccb8d2037..13906263ec 100644 --- a/src/core/lv_obj_tree.c +++ b/src/core/lv_obj_tree.c @@ -738,7 +738,7 @@ static void obj_delete_core(lv_obj_t * obj) } /*Clear the parent pointer so that, if the freed memory happens to still be - *readable, lv_obj_belongs_to_display has a better chance of rejecting it + *readable, lv_obj_is_in_widget_tree has a better chance of rejecting it *(the chain will terminate at NULL and miss every display's screen list). * *WARNING: reading any field of a freed object is use-after-free and diff --git a/src/widgets/ime/lv_ime_pinyin.c b/src/widgets/ime/lv_ime_pinyin.c index 1f07ab5378..6534f9913a 100644 --- a/src/widgets/ime/lv_ime_pinyin.c +++ b/src/widgets/ime/lv_ime_pinyin.c @@ -597,11 +597,11 @@ static void lv_ime_pinyin_destructor(const lv_obj_class_t * class_p, lv_obj_t * lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj; - if(pinyin_ime->kb != NULL) - lv_obj_delete(pinyin_ime->kb); + lv_obj_delete(pinyin_ime->kb); + pinyin_ime->kb = NULL; - if(pinyin_ime->cand_panel != NULL) - lv_obj_delete(pinyin_ime->cand_panel); + lv_obj_delete(pinyin_ime->cand_panel); + pinyin_ime->cand_panel = NULL; #if LV_IME_PINYIN_USE_K9_MODE lv_ll_clear(&pinyin_ime->k9_legal_py_ll); diff --git a/tests/src/test_cases/test_screen_load.c b/tests/src/test_cases/test_screen_load.c index 78e06360a6..401691e7dc 100644 --- a/tests/src/test_cases/test_screen_load.c +++ b/tests/src/test_cases/test_screen_load.c @@ -51,7 +51,7 @@ void test_screen_load_with_delete_no_crash(void) /*Check for the screens status after the transition*/ TEST_ASSERT_NULL(screen_with_anim_1); TEST_ASSERT_NULL(screen_with_anim_2); - TEST_ASSERT_TRUE(lv_obj_belongs_to_display(screen_with_anim_3)); + TEST_ASSERT_TRUE(lv_obj_is_in_widget_tree(screen_with_anim_3)); } void test_screen_load_with_delete_no_crash2(void) @@ -90,7 +90,7 @@ void test_screen_load_with_delete_no_crash2(void) TEST_ASSERT_NULL(screen_with_anim_1); TEST_ASSERT_NULL(screen_with_anim_2); TEST_ASSERT_NULL(screen_with_anim_3); - TEST_ASSERT_TRUE(lv_obj_belongs_to_display(screen_with_anim_4)); + TEST_ASSERT_TRUE(lv_obj_is_in_widget_tree(screen_with_anim_4)); } static bool screen_1_unloaded_called = false; @@ -140,7 +140,7 @@ void test_screen_load_with_delete_event(void) TEST_ASSERT_NULL(screen_with_anim_1); TEST_ASSERT_NULL(screen_with_anim_2); TEST_ASSERT_NULL(screen_with_anim_3); - TEST_ASSERT_TRUE(lv_obj_belongs_to_display(screen_with_anim_4)); + TEST_ASSERT_TRUE(lv_obj_is_in_widget_tree(screen_with_anim_4)); } static size_t display_screen_load_start = 0; diff --git a/tests/src/test_cases/widgets/test_ime_pinyin.c b/tests/src/test_cases/widgets/test_ime_pinyin.c index c35259f6f2..3d162e6745 100644 --- a/tests/src/test_cases/widgets/test_ime_pinyin.c +++ b/tests/src/test_cases/widgets/test_ime_pinyin.c @@ -391,14 +391,14 @@ void test_ime_pinyin_kb_validity(void) lv_ime_pinyin_set_keyboard(g_pinyin_ime, g_kb); lv_obj_t * retrieved = lv_ime_pinyin_get_kb(g_pinyin_ime); - TEST_ASSERT_TRUE(lv_obj_belongs_to_display(retrieved)); + TEST_ASSERT_TRUE(lv_obj_is_in_widget_tree(retrieved)); } /* Test cand_panel object validity */ void test_ime_pinyin_cand_panel_validity(void) { lv_obj_t * cand_panel = lv_ime_pinyin_get_cand_panel(g_pinyin_ime); - TEST_ASSERT_TRUE(lv_obj_belongs_to_display(cand_panel)); + TEST_ASSERT_TRUE(lv_obj_is_in_widget_tree(cand_panel)); } /* Test getter functions */ @@ -414,7 +414,7 @@ void test_ime_pinyin_getters(void) /* Test get_cand_panel */ lv_obj_t * cand_panel = lv_ime_pinyin_get_cand_panel(g_pinyin_ime); TEST_ASSERT_NOT_NULL(cand_panel); - TEST_ASSERT_TRUE(lv_obj_belongs_to_display(cand_panel)); + TEST_ASSERT_TRUE(lv_obj_is_in_widget_tree(cand_panel)); /* Test get_dict (should return default dict) */ const lv_pinyin_dict_t * dict = lv_ime_pinyin_get_dict(g_pinyin_ime); @@ -431,7 +431,7 @@ void test_ime_pinyin_edge_cases(void) /* Verify cand_panel is valid */ lv_obj_t * cand_panel = lv_ime_pinyin_get_cand_panel(g_pinyin_ime); - TEST_ASSERT_TRUE(lv_obj_belongs_to_display(cand_panel)); + TEST_ASSERT_TRUE(lv_obj_is_in_widget_tree(cand_panel)); } /* Test rendering with default dictionary */