diff --git a/src/lib/elementary/efl_ui_focus_manager_calc.c b/src/lib/elementary/efl_ui_focus_manager_calc.c index ce08129f1a..851feebba3 100644 --- a/src/lib/elementary/efl_ui_focus_manager_calc.c +++ b/src/lib/elementary/efl_ui_focus_manager_calc.c @@ -77,6 +77,13 @@ typedef struct { Node *root; } Efl_Ui_Focus_Manager_Calc_Data; +static void +_manager_in_chain_set(Efl_Ui_Focus_Manager_Calc_Data *pd) +{ + EINA_SAFETY_ON_NULL_RETURN(pd->root); + efl_ui_focus_manager_focus_set(efl_ui_focus_user_manager_get(pd->root->focusable), pd->root->focusable); +} + static Efl_Ui_Focus_Direction _complement(Efl_Ui_Focus_Direction dir) { @@ -1346,6 +1353,9 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_focus_set(Eo *obj, Efl_Ui_Focus_ F_DBG("Manager: %p focusing object %p %s", obj, node->focusable, efl_class_name_get(node->focusable)); + //make sure this manager is in the chain of redirects + _manager_in_chain_set(pd); + if (eina_list_last_data_get(pd->focus_stack) == node) { //the correct one is focused diff --git a/src/lib/elementary/efl_ui_focus_object.c b/src/lib/elementary/efl_ui_focus_object.c index 4579b9f561..990837f33f 100644 --- a/src/lib/elementary/efl_ui_focus_object.c +++ b/src/lib/elementary/efl_ui_focus_object.c @@ -2,6 +2,8 @@ # include "elementary_config.h" #endif +#define EFL_UI_FOCUS_OBJECT_PROTECTED + #include #include "elm_priv.h" diff --git a/src/tests/elementary/elm_test_focus.c b/src/tests/elementary/elm_test_focus.c index c4e08361b6..e7b4676342 100644 --- a/src/tests/elementary/elm_test_focus.c +++ b/src/tests/elementary/elm_test_focus.c @@ -366,6 +366,36 @@ START_TEST(logical_shift) } END_TEST +START_TEST(root_redirect_chain) +{ + Efl_Ui_Focus_Manager *m, *m2; + + elm_init(1, NULL); + + TEST_OBJ_NEW(root, 0, 20, 20, 20); + TEST_OBJ_NEW(root2, 0, 20, 20, 20); + TEST_OBJ_NEW(child, 0, 20, 20, 20); + + m = efl_add(EFL_UI_FOCUS_MANAGER_CALC_CLASS, NULL, + efl_ui_focus_manager_root_set(efl_added, root) + ); + + focus_test_manager_set(root2, m); + + m2 = efl_add(EFL_UI_FOCUS_MANAGER_CALC_CLASS, NULL, + efl_ui_focus_manager_root_set(efl_added, root2) + ); + + efl_ui_focus_manager_calc_register(m, root2, root, m2); + efl_ui_focus_manager_calc_register(m2, child, root2, NULL); + efl_ui_focus_manager_focus_set(m2, child); + + ck_assert_ptr_eq(efl_ui_focus_manager_redirect_get(m), m2); + + elm_shutdown(); +} +END_TEST + void elm_test_focus(TCase *tc) { tcase_add_test(tc, focus_register_twice); @@ -379,4 +409,5 @@ void elm_test_focus(TCase *tc) tcase_add_test(tc, invalid_args_check); tcase_add_test(tc, order_check); tcase_add_test(tc, logical_shift); + tcase_add_test(tc, root_redirect_chain); } diff --git a/src/tests/elementary/elm_test_focus_common.c b/src/tests/elementary/elm_test_focus_common.c index 896d86dd54..3ac6397c75 100644 --- a/src/tests/elementary/elm_test_focus_common.c +++ b/src/tests/elementary/elm_test_focus_common.c @@ -1,3 +1,5 @@ +#define EFL_UI_FOCUS_OBJECT_PROTECTED + #include "elm_test_focus_common.h" #define Q(o,_x,_y,_w,_h) \ @@ -60,6 +62,7 @@ elm_focus_test_manager_new(Efl_Ui_Focus_Object **middle) typedef struct { Eina_Rect rect; Eina_Bool focus; + Eo *manager; } Focus_Test_Data; EOLIAN static Efl_Object* @@ -97,5 +100,23 @@ _focus_test_efl_gfx_geometry_get(Eo *obj EINA_UNUSED, Focus_Test_Data *pd) return pd->rect; } +EOLIAN static Efl_Ui_Focus_Manager* +_focus_test_efl_ui_focus_user_manager_get(Eo *obj EINA_UNUSED, Focus_Test_Data *pd) +{ + return pd->manager; +} + +EOLIAN static Efl_Ui_Focus_Object* +_focus_test_efl_ui_focus_user_parent_get(Eo *obj, Focus_Test_Data *pd EINA_UNUSED) +{ + return efl_parent_get(obj); +} + +EOLIAN static void +_focus_test_manager_set(Eo *obj EINA_UNUSED, Focus_Test_Data *pd, Efl_Ui_Focus_Manager *manager) +{ + pd->manager = manager; +} + #include "focus_test.eo.c" diff --git a/src/tests/elementary/focus_test.eo b/src/tests/elementary/focus_test.eo index 5227241306..93ce9989b6 100644 --- a/src/tests/elementary/focus_test.eo +++ b/src/tests/elementary/focus_test.eo @@ -1,15 +1,25 @@ -class Focus.Test(Efl.Object, Efl.Ui.Focus.Object, Efl.Gfx) { +class Focus.Test(Efl.Object, Efl.Ui.Focus.Object, Efl.Ui.Focus.User, Efl.Gfx) { methods { size { params { rect : Eina.Rect; } } + @property manager { + set { + + } + values { + manager : Efl.Ui.Focus.Manager; + } + } } implements { Efl.Object.constructor; Efl.Ui.Focus.Object.focus_geometry { get; } Efl.Ui.Focus.Object.focus { set; } + Efl.Ui.Focus.User.manager { get; } + Efl.Ui.Focus.User.parent {get; } Efl.Gfx.geometry { get; } } }