1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-14 06:42:58 +08:00

event fixes: crashed when the obj was deleted in nested events

This commit is contained in:
Gabor Kiss-Vamosi 2019-04-28 17:26:18 +02:00
parent 12ee3b3504
commit 1e4fd8fdfb
5 changed files with 34 additions and 13 deletions

View File

@ -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

View File

@ -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.

View File

@ -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) {

View File

@ -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",

View File

@ -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;