From 0d506bf346bf0815fe4ce2b1d7a6471187d1e4bf Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Sat, 8 Sep 2018 14:19:04 +0200 Subject: [PATCH] efl_ui_focus_util: refactor the util for focusing objects the previous code had the problem that we moved focus onto logical objects which were not having any children, thus we saw errors from the focus manager. Now we are checking if we are able to deliver focus onto a child of the passed user. Differential Revision: https://phab.enlightenment.org/D7009 --- src/lib/elementary/efl_ui_focus_util.c | 52 ++++++++++++++------------ 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/src/lib/elementary/efl_ui_focus_util.c b/src/lib/elementary/efl_ui_focus_util.c index b0b5bedd8c..f422266101 100644 --- a/src/lib/elementary/efl_ui_focus_util.c +++ b/src/lib/elementary/efl_ui_focus_util.c @@ -15,6 +15,15 @@ _manager_changed(void *data, const Efl_Event *event EINA_UNUSED) efl_ui_focus_util_focus(EFL_UI_FOCUS_UTIL_CLASS, data); } +static Eina_Bool +_can_take_focus(Efl_Ui_Focus_Manager *m, Efl_Ui_Focus_Object *user) +{ + if (efl_isa(user, EFL_UI_FOCUS_MANAGER_INTERFACE)) + return !!efl_ui_focus_manager_request_subchild(user, efl_ui_focus_manager_root_get(user)); + else + return !!efl_ui_focus_manager_request_subchild(m, user); +} + EOLIAN static void _efl_ui_focus_util_focus(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, Efl_Ui_Focus_Object *user) { @@ -31,32 +40,27 @@ _efl_ui_focus_util_focus(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, Efl_Ui_Focus registered_manager = m = efl_ui_focus_object_focus_manager_get(user); entry = user; - do - { - if (m) - { - //check if the root of a manager is the window root, set focus to this object in the manager than - entry = efl_ui_focus_manager_root_get(m); - if (efl_isa(m, EFL_UI_WIN_CLASS)) - { - //we are at the root of the window, we can set the focus to the object - efl_ui_focus_manager_focus_set(registered_manager, user); - return; - } - } + if (m && !efl_ui_widget_focus_allow_get(user) && !_can_take_focus(m, user)) + return; - //if there is no manager yet, delay the focus setting until this entity gets registered for one chain + //move up the manager chain and see if we can end at a winow or a NULL m + while (m && !efl_isa(m, EFL_UI_WIN_CLASS)) + { + entry = efl_ui_focus_manager_root_get(m); m = efl_ui_focus_object_focus_manager_get(entry); - if (!m) - { - //delayed focusung - efl_key_data_set(top, "__delayed_focus_set", entry); - efl_event_callback_add(entry, - EFL_UI_FOCUS_OBJECT_EVENT_MANAGER_CHANGED, - _manager_changed, user); - return; - } - } while (m); + } + + if (!m) + { + efl_key_data_set(top, "__delayed_focus_set", entry); + efl_event_callback_add(entry, + EFL_UI_FOCUS_OBJECT_EVENT_MANAGER_CHANGED, + _manager_changed, user); + } + else if (efl_isa(m, EFL_UI_WIN_CLASS)) + { + efl_ui_focus_manager_focus_set(registered_manager, user); + } } EOLIAN static Efl_Ui_Focus_Manager*