bu5hm4n pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=37ce83cc047254984b206a896c7bd8d424693a05

commit 37ce83cc047254984b206a896c7bd8d424693a05
Author: Marcel Hollerbach <[email protected]>
Date:   Wed Nov 16 19:01:30 2016 +0100

    elm_widget: enhance focus handling of the widget
    
    widgets will now use there widget parent as logical parent.
---
 src/lib/elementary/elm_widget.c | 84 +++++++++++++++++++++++++++++++++++++----
 src/lib/elementary/elm_widget.h |  5 +++
 2 files changed, 82 insertions(+), 7 deletions(-)

diff --git a/src/lib/elementary/elm_widget.c b/src/lib/elementary/elm_widget.c
index ed1dbc5..62c0f70 100644
--- a/src/lib/elementary/elm_widget.c
+++ b/src/lib/elementary/elm_widget.c
@@ -199,22 +199,92 @@ elm_widget_focus_highlight_enabled_get(const Evas_Object 
*obj)
    return EINA_FALSE;
 }
 
+static Eina_Bool
+_tree_unfocusable(Eo *obj)
+{
+   Elm_Widget *wid = obj;
+
+   do {
+     ELM_WIDGET_DATA_GET(obj, wid_pd);
+
+     if (wid_pd->tree_unfocusable) return EINA_TRUE;
+   } while((wid = elm_widget_parent_widget_get(wid)));
+
+   return EINA_FALSE;
+}
+
 static void
 _focus_state_eval(Eo *obj, Elm_Widget_Smart_Data *pd)
 {
-   if (pd->can_focus && !pd->focus.manager)
+   Eina_Bool should = EINA_FALSE;
+   Eina_Bool want_full = EINA_FALSE;
+
+   //there are two reasons to be registered, the child count is bigger than 0, 
or the widget is flagged to be able to handle focus
+   if (pd->can_focus)
+     {
+        should = EINA_TRUE;
+        want_full = EINA_TRUE;
+        //can focus can be overridden by the following properties
+        if (pd->disabled)
+          should = EINA_FALSE;
+
+        if (_tree_unfocusable(obj))
+          should = EINA_FALSE;
+     }
+
+   if (pd->logical.child_count > 0)
+     should = EINA_TRUE;
+
+   //if we should register, make sure that the logical parent is up to date 
and setted up correctly
+   if (should)
+     {
+        Elm_Widget *parent;
+        parent = elm_widget_parent_widget_get(obj);
+        if (pd->logical.parent != parent)
+          {
+             //update old logical parent;
+             if (pd->logical.parent)
+               {
+                  ELM_WIDGET_DATA_GET(pd->logical.parent, logical_wd);
+                  logical_wd->logical.child_count --;
+                  _focus_state_eval(pd->logical.parent, logical_wd);
+                  pd->logical.parent = NULL;
+               }
+              if (parent)
+               {
+                  ELM_WIDGET_DATA_GET(parent, logical_wd);
+                  logical_wd->logical.child_count ++;
+                  _focus_state_eval(parent, logical_wd);
+                  pd->logical.parent = parent;
+               }
+          }
+     }
+
+   //now register in the manager
+   if (should && !pd->focus.manager)
      {
         pd->focus.manager = efl_ui_focus_user_manager_get(obj);
+        pd->focus.logical = !want_full;
+
         if (pd->focus.manager != obj)
-          efl_ui_focus_manager_register(pd->focus.manager, obj, 
pd->focus.manager, NULL);
-        else
-          pd->focus.manager = NULL;
+          {
+             if (want_full)
+               efl_ui_focus_manager_register(pd->focus.manager, obj, 
pd->logical.parent, NULL);
+             else
+               efl_ui_focus_manager_register_logical(pd->focus.manager, obj, 
pd->logical.parent);
+          }
      }
-   else if (!pd->can_focus && pd->focus.manager)
+   else if (!should && pd->focus.manager)
      {
         efl_ui_focus_manager_unregister(pd->focus.manager, obj);
         pd->focus.manager = NULL;
      }
+   else if (should && pd->focus.manager && pd->focus.logical && want_full)
+     {
+        //the case when we before registered as logical, but now wanted to be 
a normal node
+        efl_ui_focus_manager_unregister(pd->focus.manager, obj);
+        efl_ui_focus_manager_register(pd->focus.manager, obj, 
pd->focus.manager, NULL);
+     }
 }
 
 /**
@@ -6187,7 +6257,7 @@ _elm_widget_efl_object_provider_find(Eo *obj, 
Elm_Widget_Smart_Data *pd, const E
 
 
 EOLIAN static Efl_Ui_Focus_Manager*
-_elm_widget_efl_ui_focus_user_manager_get(Eo *obj, Elm_Widget_Smart_Data *pd)
+_elm_widget_efl_ui_focus_user_manager_get(Eo *obj, Elm_Widget_Smart_Data *pd 
EINA_UNUSED)
 {
    Evas_Object *parent = obj;
 
@@ -6203,7 +6273,7 @@ _elm_widget_efl_ui_focus_user_manager_get(Eo *obj, 
Elm_Widget_Smart_Data *pd)
 }
 
 EOLIAN static void
-_elm_widget_efl_ui_focus_object_geometry_get(Eo *obj, Elm_Widget_Smart_Data 
*pd, Eina_Rectangle *rect)
+_elm_widget_efl_ui_focus_object_geometry_get(Eo *obj, Elm_Widget_Smart_Data 
*pd EINA_UNUSED, Eina_Rectangle *rect)
 {
    if (!rect) return;
 
diff --git a/src/lib/elementary/elm_widget.h b/src/lib/elementary/elm_widget.h
index 3d14e88..bd04b0d 100644
--- a/src/lib/elementary/elm_widget.h
+++ b/src/lib/elementary/elm_widget.h
@@ -458,7 +458,12 @@ typedef struct _Elm_Widget_Smart_Data
    Eina_Bool                     provider_lookup : 1; /**< This is true when 
efl_provider_find is currently walking the tree */
    struct {
      Efl_Ui_Focus_Manager *manager;
+     Eina_Bool logical;
    } focus;
+   struct {
+      int child_count;
+      Efl_Ui_Focus_Object *parent;
+   } logical;
 } Elm_Widget_Smart_Data;
 
 /**

-- 


Reply via email to