atspi: enhance finding the first,last obj 65/167165/4
authorJunsuChoi <jsuya.choi@samsung.com>
Tue, 16 Jan 2018 03:31:55 +0000 (12:31 +0900)
committerGerrit Code Review <gerrit@review.ap-northeast-2.compute.internal>
Tue, 16 Jan 2018 06:08:33 +0000 (06:08 +0000)
   There are two kind of first(or last) object.
   (1) The first object in viewport of its scrollable parent.
   (2) The first object in accessibilty tree regardless of scrollable parent.

   Looping navigation should use the first object of type (2)
   Other cases should use the first object of type (1)

   If view is changed, then there is no highlight. In this case the first object
   of type (1) should be used. For example, if view is changed to 1 depth from
   2 depth, then the highlight should use the first object of type (1).
   If the following is 1 depth view after 2 depth view disapears, then there is
   not currently highlighted object. In this case the item 4 should grab highlight
   for next object, and the item 6 should grab highlight for the previous object.

   +--------+
   | item 4 |
   |--------|
   | item 5 |
   |--------|
   | item 6 |
   +--------+

Change-Id: Ie4b4e8599232ef614d9dbe5921220af3578f54c1

src/lib/elementary/efl_ui_widget.c
src/lib/elementary/elm_atspi_bridge.c

index 3890c48..436a894 100644 (file)
@@ -4274,7 +4274,11 @@ _elm_widget_item_highlightable(Elm_Object_Item *item)
 Eina_Bool
 _accessible_object_on_scroll_is(Eo* obj)
 {
-   if(!obj) return EINA_FALSE;
+   /* in case of genlist item, the item->view is NULL if item is unrealized.
+      this function is used to check if obj could have HIGHLIGHTABLE or not.
+      the unrealized genlist item should have HIGHLIGHTABLE state.
+      so if obj is NULL return EINA_TRUE */
+   if(!obj) return EINA_TRUE;
 
    Evas_Object *target = obj;
    Evas_Object *parent = NULL;
@@ -4349,7 +4353,9 @@ _elm_widget_item_efl_access_state_set_get(Eo *eo_item, Elm_Widget_Item_Data *ite
      STATE_TYPE_SET(states, EFL_ACCESS_STATE_SHOWING);
 
    //TIZEN_ONLY(20170207) : [ATSPI] enhance expose highlight information on atspi
-   if (evas_object_visible_get(item->view))
+   /* unrealized genlist item does not have item->view,
+      and item cannot change its visibility, only widget can change the visibility */
+   if (evas_object_visible_get(item->widget))
      STATE_TYPE_SET(states, EFL_ACCESS_STATE_VISIBLE);
    //
 
index 7983ad3..0226768 100644 (file)
@@ -4454,8 +4454,15 @@ _new_scrollable_parent_viewport_geometry_get(Eo *node, Eo *start,
    return ret;
 }
 
-static Eina_List *_valid_children_get(Eina_List *children, Eo *start)
+static Eina_List *_valid_children_get(Eina_List *children, Eo *start, Eo *root)
 {
+   /* condition to find first(last) object regardless of scrollable parent.
+      looping navigation does not care scrollable parent.
+      1. currently highlighted object exists
+      2. both start and root are same */
+   Eo *current = _elm_object_accessibility_currently_highlighted_get();
+   if (current && start == root) return children;
+
    Eo *child = NULL;
    child = eina_list_nth(children, 0);
 
@@ -4485,7 +4492,7 @@ static Eina_List *_valid_children_get(Eina_List *children, Eo *start)
 }
 
 static void *_get_next_non_defunct_sibling(accessibility_navigation_pointer_table *table,
-            void *obj, void *start, unsigned char forward)
+            void *obj, void *start, void *root, unsigned char forward)
 {
    if (!obj) return NULL;
    void *parent = CALL(get_parent, obj);
@@ -4493,7 +4500,7 @@ static void *_get_next_non_defunct_sibling(accessibility_navigation_pointer_tabl
 
    Eina_List *children;
    children = efl_access_children_get(parent);
-   children = _valid_children_get(children, start);
+   children = _valid_children_get(children, start, root);
 
    unsigned int children_count = eina_list_count(children);
    if (children_count == 0)
@@ -4522,7 +4529,7 @@ _directional_depth_first_search_try_non_defunct_sibling(accessibility_navigation
 {
    while(1)
      {
-       void *sibling = _get_next_non_defunct_sibling(table, node, start, forward);
+       void *sibling = _get_next_non_defunct_sibling(table, node, start, root, forward);
        if (sibling != NULL)
          {
            node = sibling;
@@ -4606,7 +4613,7 @@ static void *_calculate_neighbor_impl(accessibility_navigation_pointer_table *ta
 
        Eina_List *children;
        children = efl_access_children_get(node);
-       children = _valid_children_get(children, start);
+       children = _valid_children_get(children, start, root);
 
        // do accept:
        // 1. not start node
@@ -4614,8 +4621,7 @@ static void *_calculate_neighbor_impl(accessibility_navigation_pointer_table *ta
        // 3. Nodes with roles: ATSPI_ROLE_PAGE_TAB, ATSPI_ROLE_POPUP_MENU and ATSPI_ROLE_DIALOG, only when looking for first or last element.
        //    Objects with those roles shouldnt be reachable, when navigating next / prev.
        unsigned char all_children_visited_or_moving_forward = (eina_list_count(children) == 0 || forward || all_children_visited);
-       if (!force_next && node != start && all_children_visited_or_moving_forward &&
-           _accept_object(table, node))
+       if (!force_next && node != start && all_children_visited_or_moving_forward && _accept_object(table, node))
          {
            if (start == NULL || _object_role_is_acceptable_when_navigating_next_prev(table, node))
              {