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 <cedric.bail@free.fr>
Differential Revision: https://phab.enlightenment.org/D9645
This commit is contained in:
Marcel Hollerbach 2019-08-20 09:32:33 +02:00 committed by Cedric BAIL
parent 2dd596084b
commit 56752e0b3b
3 changed files with 21 additions and 4 deletions

View File

@ -269,7 +269,7 @@ _efl_ui_widget_focus_highlight_object_get(const Evas_Object *obj)
} }
static Eina_Bool static Eina_Bool
_candidacy_exam(Eo *obj) _legacy_focus_eval(Eo *obj)
{ {
Eina_List *lst; Eina_List *lst;
Efl_Ui_Widget *wid = obj, *top; Efl_Ui_Widget *wid = obj, *top;
@ -278,8 +278,6 @@ _candidacy_exam(Eo *obj)
wid_pd = efl_data_scope_get(wid, MY_CLASS); wid_pd = efl_data_scope_get(wid, MY_CLASS);
do { do {
if (wid_pd->disabled) return EINA_TRUE;
if (wid_pd->tree_unfocusable) return EINA_TRUE;
top = wid; top = wid;
wid = elm_widget_parent_get(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 //can focus can be overridden by the following properties
if ((!pd->parent_obj) || if ((!pd->parent_obj) ||
(!evas_object_visible_get(obj)) || (!evas_object_visible_get(obj)) ||
(_candidacy_exam(obj))) pd->disabled > 0 ||
pd->tree_unfocusable > 0)
return; 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) if (pd->can_focus)
{ {
*should = *want_full = EINA_TRUE; *should = *want_full = EINA_TRUE;

View File

@ -21,6 +21,9 @@
ELM_WIDGET_DATA_GET_OR_RETURN(obj, pd, val); \ ELM_WIDGET_DATA_GET_OR_RETURN(obj, pd, val); \
EINA_SAFETY_ON_FALSE_RETURN_VAL(elm_widget_is_legacy(obj), 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() \ #define MAPPING() \
MAP(PREVIOUS, prev) \ MAP(PREVIOUS, prev) \
MAP(NEXT, next) \ MAP(NEXT, next) \
@ -106,6 +109,7 @@ elm_object_focus_next_object_set(Evas_Object *obj,
API_ENTRY() API_ENTRY()
EINA_SAFETY_ON_FALSE_RETURN(efl_isa(next, EFL_UI_WIDGET_CLASS)); EINA_SAFETY_ON_FALSE_RETURN(efl_isa(next, EFL_UI_WIDGET_CLASS));
ELM_WIDGET_DATA_GET_OR_RETURN(next, next_pd); 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; #define MAP(direction, field) if ((Efl_Ui_Focus_Direction)dir == EFL_UI_FOCUS_DIRECTION_ ##direction) pd->legacy_focus.field = next;
MAPPING() MAPPING()
@ -121,6 +125,8 @@ elm_object_focus_custom_chain_set(Evas_Object *obj,
Eina_List *objs) Eina_List *objs)
{ {
API_ENTRY() API_ENTRY()
MARK_WINDOW_LEGACY_USAGE()
_custom_chain_set(obj, objs); _custom_chain_set(obj, objs);
} }
@ -128,6 +134,7 @@ EAPI void
elm_object_focus_custom_chain_unset(Evas_Object *obj) elm_object_focus_custom_chain_unset(Evas_Object *obj)
{ {
API_ENTRY() API_ENTRY()
MARK_WINDOW_LEGACY_USAGE()
_custom_chain_set(obj, NULL); _custom_chain_set(obj, NULL);
} }
@ -146,6 +153,7 @@ elm_object_focus_custom_chain_append(Evas_Object *obj,
Evas_Object *relative_child) Evas_Object *relative_child)
{ {
API_ENTRY() API_ENTRY()
MARK_WINDOW_LEGACY_USAGE()
Eina_List *tmp; Eina_List *tmp;
tmp = eina_list_clone(pd->legacy_focus.custom_chain); 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) Evas_Object *relative_child)
{ {
API_ENTRY() API_ENTRY()
MARK_WINDOW_LEGACY_USAGE()
Eina_List *tmp; Eina_List *tmp;
tmp = eina_list_clone(pd->legacy_focus.custom_chain); 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) Elm_Focus_Direction dir EINA_UNUSED)
{ {
API_ENTRY_VAL(NULL) 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; #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() MAPPING()
@ -316,6 +326,7 @@ elm_object_focus_next_item_set(Evas_Object *obj,
Elm_Focus_Direction dir EINA_UNUSED) Elm_Focus_Direction dir EINA_UNUSED)
{ {
API_ENTRY() 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; #define MAP(direction, field) if ((Efl_Ui_Focus_Direction)dir == EFL_UI_FOCUS_DIRECTION_ ##direction) pd->legacy_focus.item_ ##field = next_item;
MAPPING() MAPPING()

View File

@ -1044,6 +1044,7 @@ void efl_ui_scroll_connector_unbind(Eo *obj);
typedef struct typedef struct
{ {
Eina_Bool custom_parent_provider; Eina_Bool custom_parent_provider;
Eina_Bool legacy_focus_api_used;
} Efl_Ui_Shared_Win_Data; } Efl_Ui_Shared_Win_Data;
Efl_Ui_Shared_Win_Data* efl_ui_win_shared_data_get(Efl_Ui_Win *win); Efl_Ui_Shared_Win_Data* efl_ui_win_shared_data_get(Efl_Ui_Win *win);