From 56752e0b3bc49dc7a48a17c699413ea907343010 Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Tue, 20 Aug 2019 09:32:33 +0200 Subject: [PATCH] efl_ui_widget: do not walk parent chain for none legacy cases walking here the parent chain can be very costly, esp. if you make a lot of widgets visible or hide them. With this commit we ensure that we only walk the parent chain when there is a custom chain, which is only the case in legacy. This gets us about 2-3 FPS on the rpi with the item_container benchmark. With earlier commits, tree_unfocusable and disabled is honoring the whole parent chain, so checking that alone, without the parent chain, is fine. Reviewed-by: Cedric BAIL Differential Revision: https://phab.enlightenment.org/D9645 --- src/lib/elementary/efl_ui_widget.c | 13 +++++++++---- src/lib/elementary/elm_focus_legacy.c | 11 +++++++++++ src/lib/elementary/elm_priv.h | 1 + 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/lib/elementary/efl_ui_widget.c b/src/lib/elementary/efl_ui_widget.c index 5913fd6430..ca968e1e29 100644 --- a/src/lib/elementary/efl_ui_widget.c +++ b/src/lib/elementary/efl_ui_widget.c @@ -269,7 +269,7 @@ _efl_ui_widget_focus_highlight_object_get(const Evas_Object *obj) } static Eina_Bool -_candidacy_exam(Eo *obj) +_legacy_focus_eval(Eo *obj) { Eina_List *lst; Efl_Ui_Widget *wid = obj, *top; @@ -278,8 +278,6 @@ _candidacy_exam(Eo *obj) wid_pd = efl_data_scope_get(wid, MY_CLASS); do { - if (wid_pd->disabled) return EINA_TRUE; - if (wid_pd->tree_unfocusable) return EINA_TRUE; top = wid; wid = elm_widget_parent_get(wid); @@ -394,9 +392,16 @@ _eval_registration_candidate(Eo *obj, Elm_Widget_Smart_Data *pd, Eina_Bool *shou //can focus can be overridden by the following properties if ((!pd->parent_obj) || (!evas_object_visible_get(obj)) || - (_candidacy_exam(obj))) + pd->disabled > 0 || + pd->tree_unfocusable > 0) return; + if (((Efl_Ui_Shared_Win_Data*)pd->shared_win_data)->legacy_focus_api_used) + { + if (_legacy_focus_eval(obj)) + return; + } + if (pd->can_focus) { *should = *want_full = EINA_TRUE; diff --git a/src/lib/elementary/elm_focus_legacy.c b/src/lib/elementary/elm_focus_legacy.c index 5108f04c40..b815b8417d 100644 --- a/src/lib/elementary/elm_focus_legacy.c +++ b/src/lib/elementary/elm_focus_legacy.c @@ -21,6 +21,9 @@ ELM_WIDGET_DATA_GET_OR_RETURN(obj, pd, val); \ EINA_SAFETY_ON_FALSE_RETURN_VAL(elm_widget_is_legacy(obj), val); +#define MARK_WINDOW_LEGACY_USAGE() \ + ((Efl_Ui_Shared_Win_Data*)pd->shared_win_data)->legacy_focus_api_used = EINA_TRUE; + #define MAPPING() \ MAP(PREVIOUS, prev) \ MAP(NEXT, next) \ @@ -106,6 +109,7 @@ elm_object_focus_next_object_set(Evas_Object *obj, API_ENTRY() EINA_SAFETY_ON_FALSE_RETURN(efl_isa(next, EFL_UI_WIDGET_CLASS)); ELM_WIDGET_DATA_GET_OR_RETURN(next, next_pd); + MARK_WINDOW_LEGACY_USAGE() #define MAP(direction, field) if ((Efl_Ui_Focus_Direction)dir == EFL_UI_FOCUS_DIRECTION_ ##direction) pd->legacy_focus.field = next; MAPPING() @@ -121,6 +125,8 @@ elm_object_focus_custom_chain_set(Evas_Object *obj, Eina_List *objs) { API_ENTRY() + MARK_WINDOW_LEGACY_USAGE() + _custom_chain_set(obj, objs); } @@ -128,6 +134,7 @@ EAPI void elm_object_focus_custom_chain_unset(Evas_Object *obj) { API_ENTRY() + MARK_WINDOW_LEGACY_USAGE() _custom_chain_set(obj, NULL); } @@ -146,6 +153,7 @@ elm_object_focus_custom_chain_append(Evas_Object *obj, Evas_Object *relative_child) { API_ENTRY() + MARK_WINDOW_LEGACY_USAGE() Eina_List *tmp; tmp = eina_list_clone(pd->legacy_focus.custom_chain); @@ -159,6 +167,7 @@ elm_object_focus_custom_chain_prepend(Evas_Object *obj, Evas_Object *relative_child) { API_ENTRY() + MARK_WINDOW_LEGACY_USAGE() Eina_List *tmp; tmp = eina_list_clone(pd->legacy_focus.custom_chain); @@ -302,6 +311,7 @@ elm_object_focus_next_item_get(const Evas_Object *obj, Elm_Focus_Direction dir EINA_UNUSED) { API_ENTRY_VAL(NULL) + MARK_WINDOW_LEGACY_USAGE() #define MAP(direction, field) if ((Efl_Ui_Focus_Direction)dir == EFL_UI_FOCUS_DIRECTION_ ##direction && pd->legacy_focus.item_ ##field) return pd->legacy_focus.item_ ##field; MAPPING() @@ -316,6 +326,7 @@ elm_object_focus_next_item_set(Evas_Object *obj, Elm_Focus_Direction dir EINA_UNUSED) { API_ENTRY() + MARK_WINDOW_LEGACY_USAGE() #define MAP(direction, field) if ((Efl_Ui_Focus_Direction)dir == EFL_UI_FOCUS_DIRECTION_ ##direction) pd->legacy_focus.item_ ##field = next_item; MAPPING() diff --git a/src/lib/elementary/elm_priv.h b/src/lib/elementary/elm_priv.h index b2315e3f11..f621576d2a 100644 --- a/src/lib/elementary/elm_priv.h +++ b/src/lib/elementary/elm_priv.h @@ -1044,6 +1044,7 @@ void efl_ui_scroll_connector_unbind(Eo *obj); typedef struct { Eina_Bool custom_parent_provider; + Eina_Bool legacy_focus_api_used; } Efl_Ui_Shared_Win_Data; Efl_Ui_Shared_Win_Data* efl_ui_win_shared_data_get(Efl_Ui_Win *win);