bu5hm4n pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=ca2461c28027ae1a64ec89893e459cf76bdc1269
commit ca2461c28027ae1a64ec89893e459cf76bdc1269 Author: Marcel Hollerbach <[email protected]> Date: Tue Mar 27 10:45:17 2018 +0200 efl_ui_focus_manager: move cleanup into one place ref T6793 --- src/lib/elementary/efl_ui_focus_manager_calc.c | 108 +++++++++++++++---------- 1 file changed, 65 insertions(+), 43 deletions(-) diff --git a/src/lib/elementary/efl_ui_focus_manager_calc.c b/src/lib/elementary/efl_ui_focus_manager_calc.c index 27799e51c1..70379014e6 100644 --- a/src/lib/elementary/efl_ui_focus_manager_calc.c +++ b/src/lib/elementary/efl_ui_focus_manager_calc.c @@ -81,6 +81,7 @@ typedef struct { static Node* _request_subchild(Node *node); +static void dirty_add(Eo *obj, Efl_Ui_Focus_Manager_Calc_Data *pd, Node *dirty); static void _manager_in_chain_set(Eo *obj, Efl_Ui_Focus_Manager_Calc_Data *pd) @@ -237,14 +238,46 @@ node_item_free(Node *item) { Node *n; Eina_List *l; - //free the graph items - for(int i = EFL_UI_FOCUS_DIRECTION_UP;i < EFL_UI_FOCUS_DIRECTION_LAST; i++) + Eo *obj = item->manager; + FOCUS_DATA(obj); + + /*cleanup graph parts*/ + + //add all neighbors of the node to the dirty list + for(int i = EFL_UI_FOCUS_DIRECTION_UP; i < EFL_UI_FOCUS_DIRECTION_LAST; i++) { + Node *partner; + Eina_List *n; + +#define MAKE_LIST_DIRTY(node, field) \ + EINA_LIST_FOREACH(DIRECTION_ACCESS(node, i).field, n, partner) \ + { \ + dirty_add(obj, pd, partner); \ + } + + MAKE_LIST_DIRTY(item, partners) + MAKE_LIST_DIRTY(item, one_direction) + MAKE_LIST_DIRTY(item, cleanup_nodes) + border_partners_set(item, i, NULL); border_onedirection_cleanup(item, i); border_onedirection_set(item, i, NULL); } + /*cleanup manager householdings*/ + + //remove from the focus stack + pd->focus_stack = eina_list_remove(pd->focus_stack, item); + + //if this is the entry for redirect, NULL them out! + if (pd->redirect_entry == item->focusable) + pd->redirect_entry = NULL; + + //remove from the dirty parts + pd->dirty = eina_list_remove(pd->dirty, item); + + /*merge tree items*/ + //free the tree items if (!item->tree.parent && item->tree.children) { @@ -974,11 +1007,22 @@ _efl_ui_focus_manager_calc_update_children(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Man return EINA_TRUE; } +static inline Node* +_request_subchild_except(Node *n, Node *except) +{ + do + { + n = _request_subchild(n); + } + while (n == except); + + return n; +} + EOLIAN static void _efl_ui_focus_manager_calc_unregister(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Manager_Calc_Data *pd, Efl_Ui_Focus_Object *child) { Node *node; - Eina_Bool refocus = EINA_FALSE; node = eina_hash_find(pd->node_hash, &child); @@ -988,53 +1032,31 @@ _efl_ui_focus_manager_calc_unregister(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Manager_ if (eina_list_last_data_get(pd->focus_stack) == node) { - //unfocus the current head - efl_ui_focus_object_focus_set(child, EINA_FALSE); - refocus = EINA_TRUE; - } - + if (!efl_invalidated_get(pd->root->focusable)) + { + Node *n; - //remove the object from the stack if it hasn't done that until now - //after this it's not at the top anymore - //elm_widget_focus_set(node->focusable, EINA_FALSE); - //delete again from the list, for the case it was not at the top - pd->focus_stack = eina_list_remove(pd->focus_stack, node); + n = eina_list_nth(pd->focus_stack, eina_list_count(pd->focus_stack) - 2); + if (!n) + { + n = _request_subchild_except(pd->root, node); + } + else if (n->type != NODE_TYPE_NORMAL) + { + n = _request_subchild_except(n, node); + if (!n) + { + n = _request_subchild_except(pd->root, node); + } + } - //if this is the entry for redirect, NULL them out! - if (pd->redirect_entry == node->focusable) - pd->redirect_entry = NULL; + if (n) + efl_ui_focus_manager_focus_set(obj, n->focusable); - //add all neighbors of the node to the dirty list - for(int i = EFL_UI_FOCUS_DIRECTION_UP; i < EFL_UI_FOCUS_DIRECTION_LAST; i++) - { - Node *partner; - Eina_List *n; - -#define MAKE_LIST_DIRTY(node, field) \ - EINA_LIST_FOREACH(DIRECTION_ACCESS(node, i).field, n, partner) \ - { \ - dirty_add(obj, pd, partner); \ } - - MAKE_LIST_DIRTY(node, partners) - MAKE_LIST_DIRTY(node, one_direction) - MAKE_LIST_DIRTY(node, cleanup_nodes) } - //remove from the dirty parts - pd->dirty = eina_list_remove(pd->dirty, node); - eina_hash_del_by_key(pd->node_hash, &child); - - if (refocus && !efl_invalidated_get(pd->root->focusable)) - { - Node *n = eina_list_last_data_get(pd->focus_stack); - if (!n) - n = pd->root; - - if (_request_subchild(n)) - efl_ui_focus_manager_focus_set(obj, n->focusable); - } } EOLIAN static void --
