forked from enlightenment/efl
efl_ui_focus_manager_calc: store node data before the node is freed
Summary: we can consider that the node is freed during focus_manager routine. for example, efl_ui_focus_manager_redirect_set call edje event callbacks, and a application can delete a object in the edje callback. if the object is the focusable object of a node, focus_manager make the node freed. the focus_manager is able to use freed node. (a good example is test_popup.c) this prevent reusing freed pointers. Test Plan: 1. elementary_test -to popup 2. popup-center-text + 1 button 3. Click the Close button 4. check that there is no erroe message Reviewers: bu5hm4n Reviewed By: bu5hm4n Subscribers: cedric, woohyun, jpeg, Jaehyun_Cho Differential Revision: https://phab.enlightenment.org/D5729
This commit is contained in:
parent
af681a1091
commit
1b4f330c9c
|
@ -1487,8 +1487,9 @@ EOLIAN static void
|
|||
_efl_ui_focus_manager_calc_efl_ui_focus_manager_manager_focus_set(Eo *obj, Efl_Ui_Focus_Manager_Calc_Data *pd, Efl_Ui_Focus_Object *focus)
|
||||
{
|
||||
Node *node, *last;
|
||||
Efl_Ui_Focus_Object *last_focusable = NULL;
|
||||
Efl_Ui_Focus_Object *last_focusable = NULL, *new_focusable;
|
||||
Efl_Ui_Focus_Manager *redirect_manager;
|
||||
Node_Type node_type;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(focus);
|
||||
|
||||
|
@ -1531,6 +1532,19 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_manager_focus_set(Eo *obj, Efl_U
|
|||
return;
|
||||
}
|
||||
|
||||
node_type = node->type;
|
||||
new_focusable = node->focusable;
|
||||
|
||||
redirect_manager = node->redirect_manager;
|
||||
|
||||
last = eina_list_last_data_get(pd->focus_stack);
|
||||
if (last)
|
||||
last_focusable = last->focusable;
|
||||
|
||||
//remove the object from the list and add it again
|
||||
pd->focus_stack = eina_list_remove(pd->focus_stack, node);
|
||||
pd->focus_stack = eina_list_append(pd->focus_stack, node);
|
||||
|
||||
if (pd->redirect)
|
||||
{
|
||||
Efl_Ui_Focus_Manager *m = obj;
|
||||
|
@ -1545,31 +1559,21 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_manager_focus_set(Eo *obj, Efl_U
|
|||
}
|
||||
}
|
||||
|
||||
redirect_manager = node->redirect_manager;
|
||||
|
||||
last = eina_list_last_data_get(pd->focus_stack);
|
||||
if (last)
|
||||
last_focusable = last->focusable;
|
||||
|
||||
//remove the object from the list and add it again
|
||||
pd->focus_stack = eina_list_remove(pd->focus_stack, node);
|
||||
pd->focus_stack = eina_list_append(pd->focus_stack, node);
|
||||
//set to NULL here, from the event earlier this pointer could be dead.
|
||||
node = NULL;
|
||||
|
||||
/*
|
||||
Only emit those signals if we are already at the top of the focus stack.
|
||||
Otherwise focus_get in the callback to that signal might return false.
|
||||
*/
|
||||
if (node->type == NODE_TYPE_NORMAL)
|
||||
if (node_type == NODE_TYPE_NORMAL)
|
||||
{
|
||||
//populate the new change
|
||||
efl_ui_focus_object_focus_set(last_focusable, EINA_FALSE);
|
||||
efl_ui_focus_object_focus_set(node->focusable, EINA_TRUE);
|
||||
efl_ui_focus_object_focus_set(new_focusable, EINA_TRUE);
|
||||
efl_event_callback_call(obj, EFL_UI_FOCUS_MANAGER_EVENT_FOCUSED, last_focusable);
|
||||
}
|
||||
|
||||
//set to NULL here, from the event earlier this pointer could be dead.
|
||||
node = NULL;
|
||||
|
||||
//now check if this is also a listener object
|
||||
if (redirect_manager)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue