efl_ui_focus_manager: make logical_end work better
authorMarcel Hollerbach <marcel-hollerbach@t-online.de>
Wed, 30 Aug 2017 20:33:04 +0000 (22:33 +0200)
committerMarcel Hollerbach <marcel-hollerbach@t-online.de>
Wed, 30 Aug 2017 20:39:52 +0000 (22:39 +0200)
it turns out that we should also repsect logical elements that are
having a redirect_manager, since they are more at the "end" then a
potential regular node.

The user now needs to handle the logical_end call on this manager, or
handle at all what he wants to do with this information.

efl_ui_win now handles it in the way that it just focuses that logical
node, (which results in the redirect manager beeing set, then calling
again logical_end on that manager. Repeating this until we have finally
found a regular node that does fit out needs.

src/lib/elementary/efl_ui_focus_manager.eo
src/lib/elementary/efl_ui_focus_manager_calc.c
src/lib/elementary/efl_ui_focus_manager_root_focus.c
src/lib/elementary/efl_ui_win.c

index 546f9c3..cbfcfed 100644 (file)
@@ -29,6 +29,11 @@ struct Efl.Ui.Focus.Relations {
     redirect : Efl.Ui.Focus.Manager; [[Redirect manager]]
 }
 
+struct Efl.Ui.Focus.Manager.Logical_End_Detail {
+    is_regular_end : bool;
+    element : Efl.Ui.Focus.Object;
+}
+
 interface Efl.Ui.Focus.Manager {
     [[Calculates the directions of Efl.Ui.Focus.Direction
 
@@ -123,7 +128,7 @@ interface Efl.Ui.Focus.Manager {
 
               The returned object is the last object that would be returned if you start at the root and move the direction into next.
             ]]
-            return : Efl.Ui.Focus.Object; [[Last object]]
+            return : Efl.Ui.Focus.Manager.Logical_End_Detail; [[Last object]]
         }
         reset_history {
             [[Reset the history stack of this manager object.
index e0b33cd..dbd64c5 100644 (file)
@@ -1460,21 +1460,23 @@ _efl_ui_focus_manager_calc_class_destructor(Efl_Class *c EINA_UNUSED)
    _focus_log_domain = -1;
 }
 
-EOLIAN static Efl_Ui_Focus_Object*
+EOLIAN static Efl_Ui_Focus_Manager_Logical_End_Detail
 _efl_ui_focus_manager_calc_efl_ui_focus_manager_logical_end(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Manager_Calc_Data *pd)
 {
    Node *child = pd->root;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(child, NULL);
+   Efl_Ui_Focus_Manager_Logical_End_Detail ret = { 0, NULL};
+   EINA_SAFETY_ON_NULL_RETURN_VAL(child, ret);
 
    //we need to return the most lower right element
 
-   while(T(child).children)
+   while(T(child).children && !child->redirect_manager)
      child = eina_list_last_data_get(T(child).children);
-   while (child->type != NODE_TYPE_NORMAL)
+   while (child->type != NODE_TYPE_NORMAL && !child->redirect_manager)
      child = _prev(child);
 
-  return child ? child->focusable : NULL;
+   ret.is_regular_end = child->type == NODE_TYPE_NORMAL;
+   ret.element = child ? child->focusable : NULL;
+   return ret;
 }
 
 EOLIAN static void
index cdb78fb..4736f4a 100644 (file)
@@ -85,10 +85,15 @@ _efl_ui_focus_manager_root_focus_efl_ui_focus_manager_fetch(Eo *obj, Efl_Ui_Focu
 }
 
 
-EOLIAN static Efl_Ui_Focus_Object *
+EOLIAN static Efl_Ui_Focus_Manager_Logical_End_Detail
 _efl_ui_focus_manager_root_focus_efl_ui_focus_manager_logical_end(Eo *obj, Efl_Ui_Focus_Manager_Root_Focus_Data *pd)
 {
-   return _trap(pd, efl_ui_focus_manager_logical_end(efl_super(obj, MY_CLASS)));
+   Efl_Ui_Focus_Manager_Logical_End_Detail res;
+
+   res = efl_ui_focus_manager_logical_end(efl_super(obj, MY_CLASS));
+
+   res.element = _trap(pd, res.element);
+   return res;
 }
 
 EOLIAN static Eina_Iterator *
index b5a64dd..1b2bb36 100644 (file)
@@ -1755,10 +1755,15 @@ _key_action_move(Evas_Object *obj, const char *params)
 
    if (!o && focus_dir == EFL_UI_FOCUS_DIRECTION_PREV)
      {
-        Efl_Ui_Focus_Object *last;
+        Efl_Ui_Focus_Manager_Logical_End_Detail last;
+        Efl_Ui_Focus_Manager *rec_manager = obj;
 
-        last = efl_ui_focus_manager_logical_end(obj);
-        efl_ui_focus_manager_focus_set(obj, last);
+        do {
+          last = efl_ui_focus_manager_logical_end(rec_manager);
+          efl_ui_focus_manager_focus_set(obj, last.element);
+
+          rec_manager = efl_ui_focus_manager_redirect_get(rec_manager);
+        } while (!last.is_regular_end);
      }
 
    return EINA_TRUE;