Compare commits

...

13 Commits

Author SHA1 Message Date
Marcel Hollerbach cdd9bb7fb5 efl_ui_focus_layer: correctly dismantle redirect chain
when a redirect manager is unset, all focus managers in the chain upper
to the set manager must be unset. The code uses redirect manager == NULL
as an check for the manager to be active or not.

ref D11667
2020-04-09 10:24:02 +02:00
Marcel Hollerbach dcd88ab233 efl_ui_focus_manager: do not magically set focus to new elements
otherwise this focus manager might get activated again.

ref D11667
2020-04-09 10:24:02 +02:00
Marcel Hollerbach 343dfcad25 efl_ui_focus_manager: do not fallback to the same object
when redirect gets unset, we shound search for a fallback. However, we
should never fallback to the value we have unset.

ref D11667
2020-04-09 10:23:58 +02:00
Marcel Hollerbach 4c9e380b89 efl_ui_focus_manager: refactor _request_subchild_except
this is more usefull with a focusable and not a node, since the node can
be already freed in some cases.

ref D11667
2020-04-09 10:16:04 +02:00
Marcel Hollerbach ca6ce538b5 efl_ui_focus_manager: correct check
this check was checking for focus_manager to be window_root. This is not
correct, it should check for the root element.

ref D11667
2020-04-09 10:15:55 +02:00
Mike Blumenkrantz b0fd22fffe efl/wl: fix namespacing conflict in rotation enum
Differential Revision: https://phab.enlightenment.org/D11667
2020-04-08 12:37:46 -04:00
Mike Blumenkrantz 4009ffb4d2 tests/elm: add hoversel test to verify edge of canvas positioning
ensure that T8642 doesn't reoccur

Differential Revision: https://phab.enlightenment.org/D11647
2020-04-08 12:37:46 -04:00
Mike Blumenkrantz 3dd751fdd4 elm/hoversel: force calc on internal hover object during activate
hoversel can't accurately determine its location until the hover object
has been calculated, so this needs to always happen before the hoversel
is made visible in order to correctly position the hover

fix T8642

Differential Revision: https://phab.enlightenment.org/D11646
2020-04-08 12:37:46 -04:00
Mike Blumenkrantz 1e766c2757 elm/hoversel: reduce sizing_eval calcs
this doesn't need to be emitting signals or recalculating the box on
every sizing eval; signals are emitted naturally during the eval, and
the box (and its items) can be calculated only during activation since there
will be no post-activation changes there, as hoversel lacks a group_calc
implementation to handle such things anyway

Differential Revision: https://phab.enlightenment.org/D11645
2020-04-08 12:37:46 -04:00
Mike Blumenkrantz 6231c47319 tests/elm: add hoversel behavior tests
this verifies all smart callbacks for a hoversel to ensure they're triggered
as expected

Differential Revision: https://phab.enlightenment.org/D11644
2020-04-08 12:37:46 -04:00
Mike Blumenkrantz dffb64f95d elm/hoversel: remove unnecessary internal callback deletion
this already happens automatically on every item destruction and passes
the item data through there to ensure the correct callback is removed

Differential Revision: https://phab.enlightenment.org/D11643
2020-04-08 12:37:46 -04:00
Mike Blumenkrantz 31679839cd elm/hoversel: use a wref to accurately track internal hover object
this pointer is never unset, which can cause errors when attempting to
access it after the hoversel has been deactivated

Differential Revision: https://phab.enlightenment.org/D11642
2020-04-08 12:37:46 -04:00
Mike Blumenkrantz 71ef715816 tests/elm: add image tests to verify internal object size is clamped to object size
ensure that this doesn't break again

ref 11587

Differential Revision: https://phab.enlightenment.org/D11599
2020-04-08 12:37:46 -04:00
7 changed files with 192 additions and 30 deletions

View File

@ -11,7 +11,7 @@ struct @beta @extern Efl.Canvas.Wl_Xkb_State; [[ struct xkb_state. @since 1.24 ]
struct @beta @extern Efl.Canvas.Wl_Wl_Array; [[ struct wl_array. @since 1.24 ]]
enum @beta Efl.Canvas.Wl.Rotation
enum @beta Efl.Canvas.Wl_Rotation
{
[[Orientation of the internal compositor object in degrees. These values are COUNTER-CLOCKWISE.
]]
@ -122,7 +122,7 @@ class @beta Efl.Canvas.Wl extends Efl.Canvas.Group
Note that the rotation provided here is counter-clockwise.
]]
values {
rotation: Efl.Canvas.Wl.Rotation; [[The rotation to apply to the internal output.]]
rotation: Efl.Canvas.Wl_Rotation; [[The rotation to apply to the internal output.]]
rtl: bool; [[The horizontal flip to apply to the internal output.]]
}
}

View File

@ -147,7 +147,17 @@ _efl_ui_focus_layer_enable_set(Eo *obj, Efl_Ui_Focus_Layer_Data *pd, Eina_Bool v
pd->old_focus = NULL;
if (fallback && efl_ui_focus_manager_redirect_get(pd->registered_manager) == obj)
efl_ui_focus_manager_redirect_set(pd->registered_manager, NULL);
{
Efl_Ui_Focus_Manager *m = pd->registered_manager;
while (efl_ui_focus_manager_redirect_get(m))
{
Efl_Ui_Focus_Manager *old = m;
m = efl_ui_focus_manager_redirect_get(m);
efl_ui_focus_manager_redirect_set(old, NULL);
}
}
efl_ui_focus_manager_calc_unregister(pd->registered_manager, obj);
pd->registered_manager = NULL;

View File

@ -111,11 +111,11 @@ _focus_manager_active_get(Eo *obj)
{
Eo *root, *manager, *comp_parent, *redirect;
if (efl_isa(obj, EFL_UI_FOCUS_MANAGER_WINDOW_ROOT_INTERFACE) ||
(efl_composite_part_is(obj) && efl_isa(efl_parent_get(obj), EFL_UI_FOCUS_MANAGER_WINDOW_ROOT_INTERFACE)))
root = efl_ui_focus_manager_root_get(obj);
if (efl_isa(root, EFL_UI_FOCUS_MANAGER_WINDOW_ROOT_INTERFACE))
return EINA_TRUE;
root = efl_ui_focus_manager_root_get(obj);
manager = efl_ui_focus_object_focus_manager_get(root);
if (!manager) return EINA_FALSE;
@ -776,10 +776,10 @@ _efl_ui_focus_manager_calc_update_children(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Man
}
static inline Node*
_request_subchild_except(Node *n, Node *except)
_request_subchild_except(Node *n, Eo *except)
{
n = _request_subchild(n);
while (n == except)
while (n && n->focusable == except)
{
n = _next(n);
}
@ -788,7 +788,7 @@ _request_subchild_except(Node *n, Node *except)
}
EOLIAN static void
_efl_ui_focus_manager_calc_unregister(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Manager_Calc_Data *pd, Efl_Ui_Focus_Object *child)
_efl_ui_focus_manager_calc_unregister(Eo *obj, Efl_Ui_Focus_Manager_Calc_Data *pd, Efl_Ui_Focus_Object *child)
{
Node *node;
@ -800,7 +800,7 @@ _efl_ui_focus_manager_calc_unregister(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Manager_
if (eina_list_last_data_get(pd->focus_stack) == node)
{
if (!efl_invalidated_get(pd->root->focusable))
if (!efl_invalidated_get(pd->root->focusable) && _focus_manager_active_get(obj))
{
Node *n = NULL;
@ -810,7 +810,7 @@ _efl_ui_focus_manager_calc_unregister(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Manager_
{
n = eina_list_nth(pd->focus_stack, eina_list_count(pd->focus_stack) - 2);
if (!n)
n = _request_subchild_except(pd->root, node);
n = _request_subchild_except(pd->root, node->focusable);
if (n)
efl_ui_focus_manager_focus_set(obj, n->focusable);
@ -869,7 +869,7 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_redirect_set(Eo *obj, Efl_Ui_Foc
}
else
{
n = _request_subchild(pd->root);
n = _request_subchild_except(pd->root, pd->redirect_entry);
if (n)
efl_ui_focus_manager_focus_set(obj, n->focusable);
}
@ -1998,7 +1998,7 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_pop_history_stack(Eo *obj EINA_U
}
else
{
last = _request_subchild_except(pd->root, node_get(obj, pd, last_focusable));
last = _request_subchild_except(pd->root, last_focusable);
if (last)
efl_ui_focus_manager_focus_set(obj, last->focusable);
}

View File

@ -238,8 +238,6 @@ static void
_sizing_eval(void *data)
{
Evas_Object *obj = data;
Elm_Object_Item *eo_item;
const Eina_List *l;
const char *max_size_str;
int max_size = 0;
char buf[128];
@ -254,16 +252,6 @@ _sizing_eval(void *data)
if ((!sd->expanded) || (!sd->bx)) return;
elm_layout_signal_emit(sd->hover, "elm,state,align,default", "elm");
edje_object_message_signal_process(elm_layout_edje_get(sd->hover));
EINA_LIST_FOREACH(sd->items, l, eo_item)
{
ELM_HOVERSEL_ITEM_DATA_GET(eo_item, item);
efl_canvas_group_calculate(VIEW(item));
}
elm_box_recalculate(sd->bx);
evas_object_size_hint_combined_min_get(sd->bx, &box_w, &box_h);
max_size_str = elm_layout_data_get(sd->hover, "max_size");
@ -283,8 +271,6 @@ _sizing_eval(void *data)
adjusted.w = box_w;
adjusted.h = (max_size > 0) ? MIN(box_h, max_size) : box_h ;
}
evas_object_size_hint_min_set(sd->spacer, adjusted.w, adjusted.h);
if (!sd->last_location)
sd->last_location = elm_hover_best_content_location_get(sd->hover, !sd->horizontal + 1);
@ -478,7 +464,7 @@ _activate(Evas_Object *obj)
sd->expanded = EINA_TRUE;
sd->hover = elm_hover_add(sd->hover_parent);
efl_wref_add(elm_hover_add(sd->hover_parent), &sd->hover);
efl_event_callback_add(sd->hover, EFL_EVENT_KEY_DOWN, _hover_key_down, obj);
elm_widget_sub_object_add(obj, sd->hover);
@ -510,7 +496,10 @@ _activate(Evas_Object *obj)
ELM_HOVERSEL_ITEM_DATA_GET(eo_item, item);
evas_object_show(VIEW(item));
elm_box_pack_end(sd->bx, VIEW(item));
if (efl_canvas_group_need_recalculate_get(VIEW(item)))
efl_canvas_group_calculate(VIEW(item));
}
elm_box_recalculate(sd->bx);
_create_scroller(obj, sd);
elm_object_content_set(sd->scr, sd->bx);
@ -523,6 +512,8 @@ _activate(Evas_Object *obj)
if (_elm_config->access_mode) _access_widget_item_register(sd);
efl_event_callback_legacy_call(obj, ELM_HOVERSEL_EVENT_EXPANDED, NULL);
efl_canvas_group_calculate(sd->hover);
_sizing_eval(obj);
evas_object_show(sd->hover);
}
@ -667,7 +658,6 @@ _elm_hoversel_efl_canvas_group_group_del(Eo *obj, Elm_Hoversel_Data *sd)
{
Elm_Object_Item *eo_item;
evas_object_event_callback_del(sd->hover, EVAS_CALLBACK_DEL, _auto_update);
EINA_LIST_FREE(sd->items, eo_item)
{
ELM_HOVERSEL_ITEM_DATA_GET(eo_item, it);
@ -820,7 +810,6 @@ _elm_hoversel_clear(Eo *obj EINA_UNUSED, Elm_Hoversel_Data *sd)
{
Elm_Object_Item *it;
evas_object_event_callback_del(sd->hover, EVAS_CALLBACK_DEL, _auto_update);
EINA_LIST_FREE(sd->items, it)
{
efl_del(it);

View File

@ -30,7 +30,34 @@ EFL_START_TEST(efl_ui_image_test_icon)
}
EFL_END_TEST
extern Eo *elm_image_object_get(Eo*);
EFL_START_TEST(efl_ui_image_test_scale_method)
{
Eo *win, *image;
Eina_Size2D sz;
win = win_add(NULL, "image", EFL_UI_WIN_TYPE_BASIC);
efl_gfx_entity_size_set(win, EINA_SIZE2D(100, 100));
image = efl_add(EFL_UI_IMAGE_CLASS, win,
efl_file_set(efl_added, ELM_IMAGE_DATA_DIR"/images/logo.png"),
efl_gfx_arrangement_content_align_set(efl_added, 0.5, 0.0),
efl_gfx_image_scale_method_set(efl_added, EFL_GFX_IMAGE_SCALE_METHOD_FIT_WIDTH)
);
efl_gfx_entity_size_set(image, EINA_SIZE2D(100, 100));
get_me_to_those_events(win);
sz = efl_gfx_entity_size_get(image);
ck_assert_int_eq(sz.w, 100);
ck_assert_int_eq(sz.h, 100);
/* legacy operation on eo object: very illegal */
sz = efl_gfx_entity_size_get(elm_image_object_get(image));
ck_assert_int_eq(sz.w, 100);
ck_assert_int_eq(sz.h, 100);
}
EFL_END_TEST
void efl_ui_test_image(TCase *tc)
{
tcase_add_test(tc, efl_ui_image_test_icon);
tcase_add_test(tc, efl_ui_image_test_scale_method);
}

View File

@ -6,6 +6,9 @@
#include <Elementary.h>
#include "elm_suite.h"
#include "elm_priv.h"
#include "elm_widget_hoversel.h"
EFL_START_TEST(elm_hoversel_legacy_type_check)
{
Evas_Object *win, *hoversel;
@ -41,8 +44,115 @@ EFL_START_TEST(elm_atspi_role_get)
}
EFL_END_TEST
EFL_START_TEST(elm_test_hoversel_behavior)
{
Eo *hoversel, *win = win_add();
unsigned int i;
const char *callbacks[] =
{
"expanded",
"clicked",
"selected",
"item,focused",
"item,unfocused",
"dismissed",
};
int count[EINA_C_ARRAY_LENGTH(callbacks)] = {0};
evas_object_resize(win, 500, 500);
hoversel = elm_hoversel_add(win);
evas_object_geometry_set(hoversel, 25, 25, 50, 50);
elm_hoversel_hover_parent_set(hoversel, win);
elm_object_text_set(hoversel, "Vertical");
elm_hoversel_item_add(hoversel, "Item 1", NULL, ELM_ICON_NONE, NULL, NULL);
elm_hoversel_item_add(hoversel, "Item 2", NULL, ELM_ICON_NONE, NULL, NULL);
elm_hoversel_item_add(hoversel, "Item 3", NULL, ELM_ICON_NONE, NULL, NULL);
elm_hoversel_item_add(hoversel, "Item 4 - Long Label Here", "close", ELM_ICON_STANDARD, NULL, NULL);
evas_object_show(win);
evas_object_show(hoversel);
elm_object_focus_set(hoversel, EINA_TRUE);
for (i = 0; i < EINA_C_ARRAY_LENGTH(count); i++)
{
evas_object_smart_callback_add(hoversel, callbacks[i],
(void*)event_callback_single_call_int_data, &count[i]);
}
evas_object_smart_callback_add(hoversel, "dismissed",
(void*)event_callback_that_quits_the_main_loop_when_called, NULL);
get_me_to_those_events(win);
assert_object_size_eq(hoversel, 50, 50);
click_object(hoversel);
get_me_to_those_events(win);
/* expanded */
ck_assert_int_eq(count[0], 1);
wait_timer(0.6); // from default theme
ecore_main_loop_iterate();
ELM_HOVERSEL_DATA_GET(hoversel, sd);
click_object(eina_list_data_get(elm_box_children_get(sd->bx)));
get_me_to_those_events(win);
/* clicked */
ck_assert_int_eq(count[1], 1);
/* selected */
ck_assert_int_eq(count[2], 1);
/* item,focused */
ck_assert_int_eq(count[3], 1);
/* item,focused */
ck_assert_int_eq(count[4], 1);
ecore_main_loop_begin();
/* dismissed */
ck_assert_int_eq(count[5], 1);
}
EFL_END_TEST
EFL_START_TEST(elm_test_hoversel_position)
{
Eo *hoversel, *win = win_add();
evas_object_resize(win, 500, 500);
hoversel = elm_hoversel_add(win);
evas_object_geometry_set(hoversel, 450, 450, 50, 50);
elm_hoversel_hover_parent_set(hoversel, win);
elm_object_text_set(hoversel, "Vertical");
elm_hoversel_item_add(hoversel, "Item 1", NULL, ELM_ICON_NONE, NULL, NULL);
elm_hoversel_item_add(hoversel, "Item 2", NULL, ELM_ICON_NONE, NULL, NULL);
elm_hoversel_item_add(hoversel, "Item 3", NULL, ELM_ICON_NONE, NULL, NULL);
elm_hoversel_item_add(hoversel, "Item 4 - Long Label Here", "close", ELM_ICON_STANDARD, NULL, NULL);
evas_object_show(win);
evas_object_show(hoversel);
elm_object_focus_set(hoversel, EINA_TRUE);
get_me_to_those_events(win);
assert_object_size_eq(hoversel, 50, 50);
click_object(hoversel);
get_me_to_those_events(win);
wait_timer(0.6); // from default theme
ecore_main_loop_iterate();
ELM_HOVERSEL_DATA_GET(hoversel, sd);
{
int x, y, w, h;
Eo *item = eina_list_data_get(elm_box_children_get(sd->bx));
evas_object_geometry_get(item, &x, &y, &w, &h);
/* verify that all buttons are in-canvas */
ck_assert_int_le(x + w, 500);
ck_assert_int_le(y + h, 500);
}
evas_object_del(hoversel);
}
EFL_END_TEST
void elm_test_hoversel(TCase *tc)
{
tcase_add_test(tc, elm_hoversel_legacy_type_check);
tcase_add_test(tc, elm_atspi_role_get);
tcase_add_test(tc, elm_test_hoversel_behavior);
tcase_add_test(tc, elm_test_hoversel_position);
}

View File

@ -277,6 +277,31 @@ EFL_START_TEST(elm_image_test_memfile_set)
}
EFL_END_TEST
EFL_START_TEST(elm_image_test_scale_method)
{
Evas_Object *win, *image;
int w, h;
win = win_add(NULL, "image", ELM_WIN_BASIC);
evas_object_resize(win, 100, 100);
image = elm_image_add(win);
ck_assert(elm_image_file_set(image, ELM_IMAGE_DATA_DIR"/images/logo.png", NULL));
evas_object_size_hint_align_set(image, 0.5, 0.0);
efl_gfx_image_scale_method_set(image, EFL_GFX_IMAGE_SCALE_METHOD_FIT_WIDTH);
evas_object_resize(image, 100, 100);
evas_object_show(image);
evas_object_show(win);
get_me_to_those_events(win);
evas_object_geometry_get(image, NULL, NULL, &w, &h);
ck_assert_int_eq(w, 100);
ck_assert_int_eq(h, 100);
evas_object_geometry_get(elm_image_object_get(image), NULL, NULL, &w, &h);
ck_assert_int_eq(w, 100);
ck_assert_int_eq(h, 100);
}
EFL_END_TEST
#ifdef BUILD_LOADER_GIF
static void
_test_render(void *data, Evas *e EINA_UNUSED, void *event_info)
@ -332,6 +357,7 @@ void elm_test_image(TCase *tc)
tcase_add_test(tc, elm_image_evas_object_color_set);
tcase_add_test(tc, elm_image_evas_image_get);
tcase_add_test(tc, elm_image_test_memfile_set);
tcase_add_test(tc, elm_image_test_scale_method);
#ifdef BUILD_LOADER_GIF
tcase_add_test(tc, elm_image_test_gif);
#endif