From 4c82b324e48cd19f94f64cfadd945efc0d88dd2f Mon Sep 17 00:00:00 2001 From: Shinwoo Kim Date: Tue, 5 Sep 2017 20:53:29 +0900 Subject: [PATCH] atspi: find valid child of list item This patch set is solving following case. If genlist item uses evas_object_image_source_set to show item itself, then evas_tree_objects_at_xy_get does not return below objects of image source. So content objects of genlist item could not become cadicdates for elm_interface_atspi_component_accessible_at_point_get. @tizen_fix Change-Id: I44e52b48054cf80fd102131c7f199a6b62a0464d --- src/lib/elm_atspi_bridge.c | 30 +----------- src/lib/elm_widget.c | 96 +++++++++++++++++++++++++++++++++++++- src/lib/elm_widget.h | 3 ++ 3 files changed, 99 insertions(+), 30 deletions(-) diff --git a/src/lib/elm_atspi_bridge.c b/src/lib/elm_atspi_bridge.c index 6d5dca651..2e671dece 100644 --- a/src/lib/elm_atspi_bridge.c +++ b/src/lib/elm_atspi_bridge.c @@ -4154,35 +4154,9 @@ typedef struct accessibility_navigation_pointer_table { } accessibility_navigation_pointer_table; #define CALL(fncname, ...) table->fncname(table, __VA_ARGS__) -static unsigned char _accept_object_check_role(accessibility_navigation_pointer_table *table, void *obj) +static unsigned char _accept_object_check_role(accessibility_navigation_pointer_table *table EINA_UNUSED, void *obj) { - AtspiRole role = CALL(object_get_role, obj); - switch (role) - { - case ATSPI_ROLE_APPLICATION: - case ATSPI_ROLE_FILLER: - case ATSPI_ROLE_SCROLL_PANE: - case ATSPI_ROLE_SPLIT_PANE: - case ATSPI_ROLE_WINDOW: - case ATSPI_ROLE_IMAGE: - case ATSPI_ROLE_LIST: - case ATSPI_ROLE_ICON: - case ATSPI_ROLE_TOOL_BAR: - case ATSPI_ROLE_REDUNDANT_OBJECT: - case ATSPI_ROLE_COLOR_CHOOSER: - case ATSPI_ROLE_TREE_TABLE: - case ATSPI_ROLE_PAGE_TAB_LIST: - case ATSPI_ROLE_PAGE_TAB: - case ATSPI_ROLE_SPIN_BUTTON: - case ATSPI_ROLE_INPUT_METHOD_WINDOW: - case ATSPI_ROLE_EMBEDDED: - case ATSPI_ROLE_INVALID: - case ATSPI_ROLE_NOTIFICATION: - return 0; - default: - break; - } - return 1; + return _elm_widget_atspi_role_acceptable_check(obj); } static unsigned char _state_set_is_set(uint64_t state_set, AtspiStateType state) diff --git a/src/lib/elm_widget.c b/src/lib/elm_widget.c index a67225d6e..f09f8dab6 100644 --- a/src/lib/elm_widget.c +++ b/src/lib/elm_widget.c @@ -7219,6 +7219,91 @@ _is_ancestor_of(Evas_Object *smart_parent, Evas_Object *obj) return ret; } +static int _sort_by_size(const void *data1, const void *data2) +{ + Evas_Coord w, h; + Evas_Coord w2, h2; + + evas_object_geometry_get(data1, NULL, NULL, &w, &h); + evas_object_geometry_get(data2, NULL, NULL, &w2, &h2); + + if ((w * h) > (w2 * h2)) return 1; + return -1; +} + +Eina_Bool +_elm_widget_atspi_role_acceptable_check(Eo *obj) +{ + Elm_Atspi_Role role; + eo_do(obj, role = elm_interface_atspi_accessible_role_get()); + + switch (role) + { + case ELM_ATSPI_ROLE_APPLICATION: + case ELM_ATSPI_ROLE_FILLER: + case ELM_ATSPI_ROLE_SCROLL_PANE: + case ELM_ATSPI_ROLE_SPLIT_PANE: + case ELM_ATSPI_ROLE_WINDOW: + case ELM_ATSPI_ROLE_IMAGE: + case ELM_ATSPI_ROLE_LIST: + case ELM_ATSPI_ROLE_ICON: + case ELM_ATSPI_ROLE_TOOL_BAR: + case ELM_ATSPI_ROLE_REDUNDANT_OBJECT: + case ELM_ATSPI_ROLE_COLOR_CHOOSER: + case ELM_ATSPI_ROLE_TREE_TABLE: + case ELM_ATSPI_ROLE_PAGE_TAB_LIST: + case ELM_ATSPI_ROLE_PAGE_TAB: + case ELM_ATSPI_ROLE_SPIN_BUTTON: + case ELM_ATSPI_ROLE_INPUT_METHOD_WINDOW: + case ELM_ATSPI_ROLE_EMBEDDED: + case ELM_ATSPI_ROLE_INVALID: + case ELM_ATSPI_ROLE_NOTIFICATION: + return EINA_FALSE; + default: + break; + } + + return EINA_TRUE; +} + +static Eo * +_child_object_at_point_get(Eo *obj, int x, int y) +{ + Eina_List *l, *l_next, *children, *valid_children = NULL; + Eo *child; + Eo *target; + int count; + + eo_do(obj, children = elm_interface_atspi_accessible_children_get()); + + EINA_LIST_FOREACH(children, l, child) + { + if (_is_inside(child, x, y)) + valid_children = eina_list_append(valid_children, child); + } + + EINA_LIST_FOREACH_SAFE(valid_children, l, l_next, child) + { + eo_do(child, children = elm_interface_atspi_accessible_children_get()); + + /* do not use unacceptable leaf node */ + if (!_elm_widget_atspi_role_acceptable_check(child) && + eina_list_count(children) == 0) + valid_children = eina_list_remove_list(valid_children, l); + } + + count = eina_list_count(valid_children); + if (count > 0) + { + valid_children = eina_list_sort(valid_children, -1, _sort_by_size); + target = eina_list_nth(valid_children, 0); + + return _child_object_at_point_get(target, x, y); + } + + return obj; +} + static Eo * _accessible_at_point_top_down_get(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eina_Bool screen_coords, int x, int y) { @@ -7397,7 +7482,7 @@ _elm_widget_elm_interface_atspi_component_accessible_at_point_get(Eo *obj, Elm_W if (eo_isa(smart_parent, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN)) { Eina_Bool acceptable = EINA_FALSE; - + Eo *item_child; Elm_Atspi_Role role; eo_do(smart_parent, role = elm_interface_atspi_accessible_role_get()); switch (role) @@ -7411,7 +7496,14 @@ _elm_widget_elm_interface_atspi_component_accessible_at_point_get(Eo *obj, Elm_W break; case ELM_ATSPI_ROLE_LIST: - return _item_at_point_get(smart_parent, x, y); + item_child = _item_at_point_get(smart_parent, x, y); +#ifdef TIZEN_PROFILE_WEARABLE + { + item_child = _child_object_at_point_get(item_child, x, y); + return item_child; + } +#endif + return item_child; break; default: diff --git a/src/lib/elm_widget.h b/src/lib/elm_widget.h index da289e9e1..b88e2f575 100644 --- a/src/lib/elm_widget.h +++ b/src/lib/elm_widget.h @@ -892,6 +892,9 @@ EAPI Eina_Bool _elm_widget_item_onscreen_is(Elm_Object_Item *item); EAPI Eina_Bool _elm_widget_highlightable(Evas_Object *widget); EAPI Eina_Bool _elm_widget_item_highlightable(Elm_Object_Item *item); // +//TIZEN_ONLY(20170905): find valid child of list item +Eina_Bool _elm_widget_atspi_role_acceptable_check(Eo *obj); +// #define ELM_WIDGET_DATA_GET_OR_RETURN(o, ptr, ...) \ Elm_Widget_Smart_Data *ptr; \ -- 2.34.1