woohyun pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=1c6f3fd966fb64ed0ea9601e8fea71779e743566

commit 1c6f3fd966fb64ed0ea9601e8fea71779e743566
Author: WooHyun Jung <wh0705.j...@samsung.com>
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

-- 


Reply via email to