atspi: get_at_point and neighbor navigation unified 36/211136/6
authorRadoslaw Cybulski <r.cybulski@partner.samsung.com>
Mon, 29 Jul 2019 12:40:18 +0000 (14:40 +0200)
committerRadoslaw Cybulski <r.cybulski@partner.samsung.com>
Fri, 2 Aug 2019 08:14:34 +0000 (08:14 +0000)
Get at point navigation used different object hierarchy, then neighbor
navigation, which could produced inconsistent results. This patch unifies
object hierarchy used by both methods.

@tizen_only

Change-Id: Ic598c053771134d8814d59968475e54cd95f2910

src/lib/elementary/elm_atspi_bridge.c

index 757231a..4e531de 100644 (file)
@@ -4514,42 +4514,45 @@ static Eina_Bool _target_validation_check(Eo *target, Eo *root)
    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)
+          void *root, int x, int y, unsigned char coordinates_are_screen_based, Eina_Hash *used)
 {
    if (!root) return NULL;
-   void *prev_root = root;
+   int found = (int)(uintptr_t)eina_hash_find(used, &root);
+   if (found) return NULL;
+   eina_hash_set(used, &root, (const void *)(uintptr_t)1);
 
    void *return_value = NULL;
-   while (1)
-     {
-       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;
-
-       // always return proxy, so atspi lib can call on it again
-       if (CALL(object_is_proxy, target)) return target;
+   Eina_List *children = efl_access_object_access_children_get(root), *iter;
+   void *obj;
 
-       root = target;
-       void *relation_obj = CALL(get_object_in_relation_by_type, root, ATSPI_RELATION_CONTROLLED_BY);
-       unsigned char contains = 0;
+   EINA_LIST_REVERSE_FOREACH(children, iter, obj)
+     {
+       void *relation_obj = CALL(get_object_in_relation_by_type, obj, ATSPI_RELATION_CONTROLLED_BY);
        if (relation_obj)
          {
-           contains = CALL(object_contains, relation_obj, x, y, coordinates_are_screen_based);
-           if (contains) root = relation_obj;
+           unsigned char c = CALL(object_contains, relation_obj, x, y, coordinates_are_screen_based);
+           if (c) obj = relation_obj;
          }
-
-       if (_accept_object(table, root))
+       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))
          {
-           return_value = root;
-           if (contains) break;
+               return_value = obj;
+               break;
+             }
          }
      }
-
-   if (return_value && _object_has_modal_state(table, return_value)) return_value = NULL;
+   if (return_value && _object_has_modal_state(table, return_value))
+     return_value = NULL;
    return return_value;
 }
+//
 
 static void *_find_non_defunct_child(accessibility_navigation_pointer_table *table,
             Eina_List *children, unsigned int current_index, unsigned char forward)
@@ -5111,8 +5114,11 @@ static unsigned char accept_object(Eo *obj)
 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);
-   Eo *result = (Eo*)_calculate_navigable_accessible_at_point_impl(&table.ptrs, root, x, y, coord_type ? 1 : 0);
-
+//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);
+//
    return result;
 }