From 1e4fd8fdfb8e93d52118b8b2781639103e6bfd52 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sun, 28 Apr 2019 17:26:18 +0200 Subject: [PATCH] event fixes: crashed when the obj was deleted in nested events --- src/lv_core/lv_obj.c | 21 +++++++++++++++------ src/lv_core/lv_obj.h | 9 +++++++++ src/lv_objx/lv_btnm.c | 12 +++++++----- src/lv_objx/lv_kb.c | 4 ++-- src/lv_objx/lv_ta.c | 1 + 5 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index eaf6f0e05..ef920d07d 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -377,8 +377,6 @@ lv_res_t lv_obj_del(lv_obj_t * obj) { lv_obj_invalidate(obj); - if(event_act_obj == obj && event_act_obj_deleted == false) event_act_obj_deleted = true; - /*Delete from the group*/ #if LV_USE_GROUP bool was_focused = false; @@ -410,9 +408,12 @@ lv_res_t lv_obj_del(lv_obj_t * obj) i = i_next; } - /*Let the suer free the resources used in `LV_EVENT_DELETE`*/ + /*Let the user free the resources used in `LV_EVENT_DELETE`*/ lv_event_send(obj, LV_EVENT_DELETE, NULL); + if(event_act_obj == obj && event_act_obj_deleted == false) event_act_obj_deleted = true; + + /*Remove the object from parent's children list*/ lv_obj_t * par = lv_obj_get_parent(obj); if(par == NULL) { /*It is a screen*/ @@ -1277,6 +1278,9 @@ lv_res_t lv_event_send(lv_obj_t * obj, lv_event_t event, const void * data) { if(obj == NULL) return LV_RES_OK; + /*In case of nested events the object might be already deleted. */ + if(event_act_obj == obj && event_act_obj_deleted) return LV_RES_INV; + /*If the event was send from an other event save the current states to restore it at the end*/ lv_obj_t * prev_obj_act = event_act_obj; bool prev_obj_act_deleted = event_act_obj_deleted; @@ -1290,6 +1294,13 @@ lv_res_t lv_event_send(lv_obj_t * obj, lv_event_t event, const void * data) bool deleted = event_act_obj_deleted; + /* If the object was deleted here and the previous object is the same like this + * restore deleted state (because this object was deleted)*/ + if(event_act_obj == prev_obj_act && event_act_obj_deleted) { + prev_obj_act_deleted = true; + deleted = true; + } + /*Restore the previous states*/ event_act_obj = prev_obj_act; event_act_obj_deleted = prev_obj_act_deleted; @@ -2176,9 +2187,6 @@ static void refresh_children_style(lv_obj_t * obj) */ static void delete_children(lv_obj_t * obj) { - - if(event_act_obj == obj && event_act_obj_deleted == false) event_act_obj_deleted = true; - lv_obj_t * i; lv_obj_t * i_next; i = lv_ll_get_head(&(obj->child_ll)); @@ -2209,6 +2217,7 @@ static void delete_children(lv_obj_t * obj) /*Let the suer free the resources used in `LV_EVENT_DELETE`*/ lv_event_send(obj, LV_EVENT_DELETE, NULL); + if(event_act_obj == obj && event_act_obj_deleted == false) event_act_obj_deleted = true; /*Remove the animations from this object*/ #if LV_USE_ANIMATION diff --git a/src/lv_core/lv_obj.h b/src/lv_core/lv_obj.h index 2280a1c64..59d5ad8d9 100644 --- a/src/lv_core/lv_obj.h +++ b/src/lv_core/lv_obj.h @@ -571,6 +571,15 @@ lv_res_t lv_event_send(lv_obj_t * obj, lv_event_t event, const void * data); */ const void * lv_event_get_data(void); +/** + * Mark the current object in the event as deleted. + * It not required in the general cases because the library will take care of it. + * However if an event is sent manually to an other object from an event where the object is deleted + * the library will not know about the deletion (because it happened in an other object's event). + * In this specific case the object need to be marked as deleted manually. + */ +void lv_event_mark_as_deleted(void); + /** * Set the a signal function of an object. Used internally by the library. * Always call the previous signal function in the new. diff --git a/src/lv_objx/lv_btnm.c b/src/lv_objx/lv_btnm.c index e91d7434e..6f284e92a 100644 --- a/src/lv_objx/lv_btnm.c +++ b/src/lv_objx/lv_btnm.c @@ -721,7 +721,7 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param) button_is_inactive(ext->ctrl_bits[ext->btn_id_act]) == false && button_is_hidden(ext->ctrl_bits[ext->btn_id_act]) == false) { uint32_t b = ext->btn_id_act; - lv_event_send(btnm, LV_EVENT_SELECTED, &b); + res = lv_event_send(btnm, LV_EVENT_SELECTED, &b); } } } else if(sign == LV_SIGNAL_PRESSING) { @@ -737,8 +737,10 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param) } if(btn_pr != LV_BTNM_BTN_NONE) { uint32_t b = ext->btn_id_act; - lv_event_send(btnm, LV_EVENT_SELECTED, &b); - invalidate_button_area(btnm, btn_pr); + res = lv_event_send(btnm, LV_EVENT_SELECTED, &b); + if(res == LV_RES_OK) { + invalidate_button_area(btnm, btn_pr); + } } } @@ -773,7 +775,7 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param) button_is_inactive(ext->ctrl_bits[ext->btn_id_act]) == false && button_is_hidden(ext->ctrl_bits[ext->btn_id_act]) == false) { uint32_t b = ext->btn_id_act; - lv_event_send(btnm, LV_EVENT_SELECTED, &b); + res = lv_event_send(btnm, LV_EVENT_SELECTED, &b); } } } else if(sign == LV_SIGNAL_LONG_PRESS_REP) { @@ -782,7 +784,7 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param) button_is_inactive(ext->ctrl_bits[ext->btn_id_act]) == false && button_is_hidden(ext->ctrl_bits[ext->btn_id_act]) == false) { uint32_t b = ext->btn_id_act; - lv_event_send(btnm, LV_EVENT_SELECTED, &b); + res = lv_event_send(btnm, LV_EVENT_SELECTED, &b); } } } else if(sign == LV_SIGNAL_PRESS_LOST || sign == LV_SIGNAL_DEFOCUS) { diff --git a/src/lv_objx/lv_kb.c b/src/lv_objx/lv_kb.c index 18975aad2..c1135fb2d 100644 --- a/src/lv_objx/lv_kb.c +++ b/src/lv_objx/lv_kb.c @@ -41,7 +41,7 @@ static const lv_btnm_ctrl_t kb_ctrl_lc_map[] = { LV_KB_CTRL_BTN_FLAGS | 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7, LV_KB_CTRL_BTN_FLAGS | 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 6, 2, 2}; + LV_KB_CTRL_BTN_FLAGS | 2, 2, 6, 2, LV_KB_CTRL_BTN_FLAGS | 2}; static const char * kb_map_uc[] = {"1#", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "Bksp", "\n", "abc", "A", "S", "D", "F", "G", "H", "J", "K", "L", "Enter", "\n", @@ -52,7 +52,7 @@ static const lv_btnm_ctrl_t kb_ctrl_uc_map[] = { LV_KB_CTRL_BTN_FLAGS | 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7, LV_KB_CTRL_BTN_FLAGS | 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 6, 2, 2}; + LV_KB_CTRL_BTN_FLAGS | 2, 2, 6, 2, LV_KB_CTRL_BTN_FLAGS | 2}; static const char * kb_map_spec[] = {"0", "1", "2", "3", "4" ,"5", "6", "7", "8", "9", "Bksp", "\n", "abc", "+", "-", "/", "*", "=", "%", "!", "?", "#", "<", ">", "\n", diff --git a/src/lv_objx/lv_ta.c b/src/lv_objx/lv_ta.c index 48e1d91eb..28090c62b 100644 --- a/src/lv_objx/lv_ta.c +++ b/src/lv_objx/lv_ta.c @@ -108,6 +108,7 @@ lv_obj_t * lv_ta_create(lv_obj_t * par, const lv_obj_t * copy) ext->cursor.type = LV_CURSOR_LINE; ext->cursor.valid_x = 0; ext->one_line = 0; + ext->text_sel_en = 0; ext->label = NULL; ext->placeholder = NULL;