woohyun pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=1c6f3fd966fb64ed0ea9601e8fea71779e743566
commit 1c6f3fd966fb64ed0ea9601e8fea71779e743566 Author: WooHyun Jung <[email protected]> Date: Sat Apr 16 13:47:13 2016 +0900 elm_focus: keep all focused states to be consistent when win loses and gets focus Since focus_clear removed all the focused traces, focus was not reverted well whenever win lost and got focus repeatedly. For instance, 1. set focus to button1 2. set focus to button2 3. win focus out and in 4. remove button2 5. focus is on win not on button1 So, focus logic changes to not clear focused states when win loses focus. @fix --- src/lib/elementary/elm_widget.c | 67 ++++++++++++++++++++++++++--------------- src/lib/elementary/elm_win.c | 8 ++--- 2 files changed, 45 insertions(+), 30 deletions(-) diff --git a/src/lib/elementary/elm_widget.c b/src/lib/elementary/elm_widget.c index 1746844..b3096c9 100644 --- a/src/lib/elementary/elm_widget.c +++ b/src/lib/elementary/elm_widget.c @@ -78,6 +78,13 @@ _is_focusable(Evas_Object *obj) } static inline Eina_Bool +_is_focused(Evas_Object *obj) +{ + API_ENTRY return EINA_FALSE; + return sd->focused; +} + +static inline Eina_Bool _elm_scrollable_is(const Evas_Object *obj) { INTERNAL_ENTRY EINA_FALSE; @@ -246,7 +253,7 @@ _on_sub_obj_del(void *data, const Eo_Event *event) if (_elm_widget_is(event->obj)) { - if (elm_widget_focus_get(event->obj)) _parents_unfocus(sd->obj); + if (_is_focused(event->obj)) _parents_unfocus(sd->obj); } if (event->obj == sd->resize_obj) { @@ -383,11 +390,11 @@ _if_focused_revert(Evas_Object *obj, ELM_WIDGET_DATA_GET(newest, sd2); if (!sd2) return; - if (!elm_widget_focus_get(newest)) + if (!_is_focused(newest)) elm_widget_focus_steal(newest, NULL); else { - if (sd2->resize_obj && elm_widget_focus_get(sd2->resize_obj)) + if (sd2->resize_obj && _is_focused(sd2->resize_obj)) elm_widget_focused_object_clear(sd2->resize_obj); else { @@ -396,7 +403,7 @@ _if_focused_revert(Evas_Object *obj, EINA_LIST_FOREACH(sd2->subobjs, l, child) { if (!_elm_widget_is(child)) continue; - if (elm_widget_focus_get(child)) + if (_is_focused(child)) { elm_widget_focused_object_clear(child); break; @@ -826,12 +833,10 @@ _parent_focus(Evas_Object *obj, Elm_Object_Item *item) focus_order++; sd->focus_order = focus_order; + sd->focused = EINA_TRUE; if (sd->top_win_focused) - { - sd->focused = EINA_TRUE; - elm_obj_widget_on_focus(obj, item); - } + elm_obj_widget_on_focus(obj, item); sd->focus_order_on_calc = EINA_FALSE; if (_elm_config->access_mode == ELM_ACCESS_MODE_ON) @@ -1194,7 +1199,7 @@ _elm_widget_sub_object_add(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Object *sobj elm_widget_theme(sobj); } - if (elm_widget_focus_get(sobj)) _parents_focus(obj); + if (_is_focused(sobj)) _parents_focus(obj); elm_widget_display_mode_set(sobj, evas_object_size_hint_display_mode_get(obj)); @@ -1242,7 +1247,7 @@ _elm_widget_sub_object_del(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Object *sobj if (_elm_widget_is(sobj)) { - if (elm_widget_focus_get(sobj)) + if (_is_focused(sobj)) { elm_widget_tree_unfocusable_set(sobj, EINA_TRUE); elm_widget_tree_unfocusable_set(sobj, EINA_FALSE); @@ -1320,7 +1325,7 @@ _elm_widget_resize_object_set(Eo *obj, Elm_Widget_Smart_Data *sd, if (_elm_widget_is(sd->resize_obj)) { - if (elm_widget_focus_get(sd->resize_obj)) _parents_unfocus(obj); + if (_is_focused(sd->resize_obj)) _parents_unfocus(obj); } elm_widget_sub_object_del(obj, sd->resize_obj); } @@ -1568,7 +1573,7 @@ _elm_widget_access_highlight_in_theme_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_ EOLIAN static Eina_Bool _elm_widget_focus_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd) { - return sd->focused; + return (sd->focused && sd->top_win_focused); } EOLIAN static Eina_Bool @@ -1583,7 +1588,7 @@ _elm_widget_focused_object_get(Eo *obj, Elm_Widget_Smart_Data *sd) const Evas_Object *subobj; const Eina_List *l; - if (!sd->focused) return NULL; + if (!sd->focused || !sd->top_win_focused) return NULL; EINA_LIST_FOREACH(sd->subobjs, l, subobj) { Evas_Object *fobj; @@ -1921,7 +1926,7 @@ _elm_widget_focus_direction_go(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, double weight = 0.0; if (!_elm_widget_is(obj)) return EINA_FALSE; - if (!elm_widget_focus_get(obj)) return EINA_FALSE; + if (!_is_focused(obj)) return EINA_FALSE; current_focused = elm_widget_focused_object_get(obj); @@ -2300,7 +2305,7 @@ _elm_widget_focus_direction_get(const Eo *obj, Elm_Widget_Smart_Data *sd, const return int_ret; } - if (!elm_widget_can_focus_get(obj) || elm_widget_focus_get(obj)) + if (!elm_widget_can_focus_get(obj) || _is_focused((Eo *)obj)) return EINA_FALSE; c_weight = _elm_widget_focus_direction_weight_get(base, obj, degree); @@ -2416,7 +2421,7 @@ _elm_widget_focus_next_get(const Eo *obj, Elm_Widget_Smart_Data *sd, Elm_Focus_D { Eina_Bool int_ret = EINA_FALSE; int_ret = elm_obj_widget_focus_next((Eo *)obj, dir, next, next_item); - if (!int_ret && elm_widget_focus_get(obj)) + if (!int_ret && _is_focused((Eo *)obj)) { Evas_Object *o = NULL; if (dir == ELM_FOCUS_PREVIOUS) @@ -2473,7 +2478,7 @@ _elm_widget_focus_next_get(const Eo *obj, Elm_Widget_Smart_Data *sd, Elm_Focus_D else if (!elm_widget_can_focus_get(obj)) return EINA_FALSE; - if (elm_widget_focus_get(obj)) + if (_is_focused((Eo *)obj)) { if (dir == ELM_FOCUS_PREVIOUS) *next_item = sd->item_focus_previous; @@ -2647,7 +2652,7 @@ _elm_widget_focus_list_next_get(const Eo *obj, Elm_Widget_Smart_Data *_pd EINA_U || (dir == ELM_FOCUS_RIGHT) || (dir == ELM_FOCUS_LEFT)) { - if (tmp && elm_widget_focus_get(cur)) + if (tmp && _is_focused(cur)) { *next = tmp; *next_item = tmp_item; @@ -2917,7 +2922,7 @@ static void _focused_object_clear(Elm_Widget_Smart_Data *sd) { if (sd->resize_obj && elm_widget_is(sd->resize_obj) && - elm_widget_focus_get(sd->resize_obj)) + _is_focused(sd->resize_obj)) { elm_obj_widget_focused_object_clear(sd->resize_obj); } @@ -2927,7 +2932,7 @@ _focused_object_clear(Elm_Widget_Smart_Data *sd) Evas_Object *child; EINA_LIST_FOREACH(sd->subobjs, l, child) { - if (_elm_widget_is(child) && elm_widget_focus_get(child)) + if (_elm_widget_is(child) && _is_focused(child)) { elm_obj_widget_focused_object_clear(child); break; @@ -2942,7 +2947,8 @@ _elm_widget_focused_object_clear(Eo *obj, Elm_Widget_Smart_Data *sd) if (!sd->focused) return; _focused_object_clear(sd); sd->focused = EINA_FALSE; - elm_obj_widget_on_focus(obj, NULL); + if (sd->top_win_focused) + elm_obj_widget_on_focus(obj, NULL); } EOLIAN static void @@ -2980,6 +2986,17 @@ _elm_widget_focus_steal(Eo *obj, Elm_Widget_Smart_Data *sd, Elm_Object_Item *ite return; } +static void +_parents_on_focus(Evas_Object *obj) +{ + API_ENTRY return; + if (!sd->focused || !sd->top_win_focused) return; + + Evas_Object *o = elm_widget_parent_get(obj); + if (o) _parents_on_focus(o); + elm_obj_widget_on_focus(obj, NULL); +} + EOLIAN static void _elm_widget_focus_restore(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED) { @@ -2988,10 +3005,7 @@ _elm_widget_focus_restore(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED) newest = elm_widget_newest_focus_order_get(obj, &newest_focus_order, EINA_TRUE); if (newest) - { - elm_object_focus_set(newest, EINA_FALSE); - elm_object_focus_set(newest, EINA_TRUE); - } + _parents_on_focus(newest); } void @@ -3016,6 +3030,9 @@ _elm_widget_top_win_focused_set(Evas_Object *obj, _elm_widget_top_win_focused_set(child, top_win_focused); } sd->top_win_focused = top_win_focused; + + if (sd->focused && !sd->top_win_focused) + elm_obj_widget_on_focus(obj, NULL); } Eina_Bool diff --git a/src/lib/elementary/elm_win.c b/src/lib/elementary/elm_win.c index ba8089b..8576cb4 100644 --- a/src/lib/elementary/elm_win.c +++ b/src/lib/elementary/elm_win.c @@ -1086,7 +1086,6 @@ _elm_win_focus_in(Ecore_Evas *ee) { Elm_Win_Data *sd = _elm_win_associate_get(ee); Evas_Object *obj; - unsigned int order = 0; if ((!sd) || (sd->modal_count)) return; @@ -1095,8 +1094,7 @@ _elm_win_focus_in(Ecore_Evas *ee) _elm_widget_top_win_focused_set(obj, EINA_TRUE); if (sd->type != ELM_WIN_FAKE) { - if (!elm_widget_focus_order_get(obj) - || (obj == elm_widget_newest_focus_order_get(obj, &order, EINA_TRUE))) + if (!elm_widget_focus_order_get(obj)) { elm_widget_focus_steal(obj, NULL); } @@ -1107,7 +1105,8 @@ _elm_win_focus_in(Ecore_Evas *ee) newest = elm_widget_newest_focus_order_get (obj, &newest_focus_order, EINA_TRUE); - if (newest && _elm_widget_onscreen_is(newest)) + if (newest && + (_elm_widget_onscreen_is(newest) || (newest == obj))) elm_widget_focus_restore(obj); else evas_object_focus_set(obj, EINA_TRUE); @@ -1145,7 +1144,6 @@ _elm_win_focus_out(Ecore_Evas *ee) obj = sd->obj; - elm_object_focus_set(obj, EINA_FALSE); _elm_widget_top_win_focused_set(obj, EINA_FALSE); // FIXME: the event is deprecated but still in use. // Has to be removed in EFL2.0 --
