return 1;
}
+/* The target cannot be a parent of root */
+static Eina_Bool _target_validation_check(Eo *target, Eo *root)
+{
+ //TIZEN_ONLY(20181024): Fix parent-children incosistencies in atspi tree
+ Eo *parent = _get_accessible_parent(root);
+ //
+
+ while (parent)
+ {
+ if (parent == target) return EINA_FALSE;
+ //TIZEN_ONLY(20181024): Fix parent-children incosistencies in atspi tree
+ parent = _get_accessible_parent(parent);
+ //
+ }
+
+ return EINA_TRUE;
+}
+
//TIZEN_ONLY(20190729): [ATSPI] get_at_point and neighbor navigation unified
static void *_calculate_navigable_accessible_at_point_impl(accessibility_navigation_pointer_table *table,
- void *root, int x, int y, unsigned char coordinates_are_screen_based, Eina_Hash *used)
+ void *root, int x, int y, unsigned char coordinates_are_screen_based)
{
if (!root) return NULL;
- uintptr_t found = (uintptr_t)eina_hash_find(used, &root);
- if (found) return NULL;
- eina_hash_set(used, &root, (const void *)(uintptr_t)1);
-
+ void *prev_root = root;
void *return_value = NULL;
- Eina_List *children = efl_access_object_access_children_get(root), *iter;
- void *obj;
+ while(1)
+ {
- EINA_LIST_REVERSE_FOREACH(children, iter, obj)
- {
- if (efl_isa(obj, ELM_ATSPI_PROXY_CLASS))
- return obj;
+ void *target = CALL(get_object_at_point, root, x, y, coordinates_are_screen_based);
+ if (!target) break;
+ if (target == root || target == prev_root) break;
+ if (!_target_validation_check(target, root)) break;
- void *relation_obj = CALL(get_object_in_relation_by_type, obj, ATSPI_RELATION_CONTROLLED_BY);
+ // always return proxy, so atspi lib can call on it again
+ if (CALL(object_is_proxy, target)) return target;
+
+ root = target;
+ void *relation_obj = CALL(get_object_in_relation_by_type, root, ATSPI_RELATION_CONTROLLED_BY);
+ unsigned char contains = 0;
if (relation_obj)
{
- unsigned char c = CALL(object_contains, relation_obj, x, y, coordinates_are_screen_based);
- if (c) obj = relation_obj;
+ contains = CALL(object_contains, relation_obj, x, y, coordinates_are_screen_based);
+ if (contains) root = relation_obj;
}
- unsigned char contains = CALL(object_contains, obj, x, y, coordinates_are_screen_based);
- if (contains)
- {
- return_value = _calculate_navigable_accessible_at_point_impl(table, obj, x, y, coordinates_are_screen_based, used);
- if (return_value)
- break;
- if (_accept_object(table, obj))
+
+ if (_accept_object(table, root))
{
- return_value = obj;
- break;
- }
+ return_value = root;
+ if (contains) break;
}
}
+
if (return_value && _object_has_modal_state(table, return_value))
return_value = NULL;
return return_value;
static Eo *_calculate_navigable_accessible_at_point(Eo *bridge, Eo *root, Eina_Bool coord_type, int x, int y)
{
accessibility_navigation_pointer_table_impl table = construct_accessibility_navigation_pointer_table(bridge);
-//TIZEN_ONLY(20190729): [ATSPI] get_at_point and neighbor navigation unified
- Eina_Hash *used = eina_hash_pointer_new(NULL);
- Eo *result = (Eo*)_calculate_navigable_accessible_at_point_impl(&table.ptrs, root, x, y, coord_type ? 1 : 0, used);
- eina_hash_free(used);
-//
+ Eo *result = (Eo*)_calculate_navigable_accessible_at_point_impl(&table.ptrs, root, x, y, coord_type ? 1 : 0);
+
return result;
}