efl_ui_focus_manager: ensure the manager is in focus when focus is set

this makes handling of focus easier in elementary
This commit is contained in:
Marcel Hollerbach 2017-11-14 19:46:29 +01:00
parent 07cb2d2dcd
commit df81e2f492
5 changed files with 75 additions and 1 deletions

View File

@ -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

View File

@ -2,6 +2,8 @@
# include "elementary_config.h"
#endif
#define EFL_UI_FOCUS_OBJECT_PROTECTED
#include <Elementary.h>
#include "elm_priv.h"

View File

@ -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);
}

View File

@ -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"

View File

@ -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; }
}
}