atspi: Handle default label object on toolkit side
authorShinwoo Kim <cinoo.kim@samsung.com>
Tue, 12 Dec 2017 07:45:07 +0000 (13:15 +0530)
committerJiyoun Park <jy0703.park@samsung.com>
Thu, 21 Dec 2017 13:06:33 +0000 (22:06 +0900)
There are unexpected difficult cases to make default label work correctly.

The following would be the case.
(top of accessible tree) - (bottom side)
PageTab1 - Panel1 - PageTab2 - Panel2 - PageTab3 - Panel3(currently showing)
Application could make as below: PageTab1 - Panel1 - PageTab3 - Panel3 - PageTab2 - Panel2(currently showing) or
following tree would normally be possilbe: PageTab1 - Panel1 - PageTab2 - Panel2(currently showing)
There are much of complicated case over there.
So we are handling the default label object stack on toolkit(Elementary) side.
Please refer to following patch set: https://review.tizen.org/gerrit/#/c/151025/ (at-spi2-core)
https://review.tizen.org/gerrit/#/c/151030/ (screen-reader)

Change-Id: Ibc0918ad925066a7cbe0e8888edc4d3431d8c154
orig: a981fc78abdb4bb61fc76deb8d15016d63bc3da9
Signed-off-by: Shilpa Singh <shilpa.singh@samsung.com>
src/lib/elementary/efl_ui_win.c
src/lib/elementary/elc_ctxpopup.c
src/lib/elementary/elc_naviframe.c
src/lib/elementary/elc_popup.c
src/lib/elementary/elm_atspi_bridge.c
src/lib/elementary/elm_panel.c
src/lib/elementary/elm_widget.h

index 12770f3..82774d8 100644 (file)
@@ -186,7 +186,9 @@ struct _Efl_Ui_Win_Data
 
    } accessibility_highlight;
    //
-
+   //TIZEN_ONLY(20170919): Handle default label object
+   Eina_List *default_label_objs;
+   //
    Evas_Object *icon;
    const char  *title;
    const char  *icon_name;
@@ -8748,6 +8750,103 @@ _elm_win_object_set_accessibility_highlight(Evas_Object *win, Evas_Object *obj,
 }
 //
 
+//TIZEN_ONLY(20170919): Handle default label object
+static void
+_default_label_obj_del_cb (void *data,
+                           Evas *e EINA_UNUSED,
+                           Evas_Object *obj,
+                           void *event_info EINA_UNUSED)
+{
+   ELM_WIN_DATA_GET(data, sd);
+   if (!sd) return;
+
+   sd->default_label_objs = eina_list_remove(sd->default_label_objs, obj);
+}
+
+static int _sort_parent_child_order(const void *data1, const void *data2)
+{
+   if (data1)
+     {
+        Eo *parent;
+        parent = efl_access_parent_get(data1);
+        while (parent)
+          {
+             if (parent == data2) return 1;
+             parent = efl_access_parent_get(parent);
+          }
+     }
+   return -1;
+}
+
+void
+_elm_win_default_label_obj_append(Evas_Object *default_label_obj)
+{
+   if (!default_label_obj) return;
+
+   Evas_Object *win = elm_widget_top_get(default_label_obj);
+   if (!win || !efl_isa(win, EFL_UI_WIN_CLASS))
+     {
+        WRN("The top object of %s is not a window.",
+            efl_class_name_get(efl_class_get(default_label_obj)));
+        return;
+     }
+
+   ELM_WIN_DATA_GET(win, sd);
+   if (!sd) return;
+
+   if (eina_list_data_find(sd->default_label_objs, default_label_obj))
+     {
+        sd->default_label_objs =
+          eina_list_remove(sd->default_label_objs, default_label_obj);
+        evas_object_event_callback_del_full(default_label_obj, EVAS_CALLBACK_DEL,
+                                            _default_label_obj_del_cb, win);
+     }
+
+   evas_object_event_callback_add(default_label_obj, EVAS_CALLBACK_DEL,
+                                  _default_label_obj_del_cb, win);
+   sd->default_label_objs =
+     eina_list_append(sd->default_label_objs, default_label_obj);
+
+   sd->default_label_objs =
+     eina_list_sort(sd->default_label_objs, -1, _sort_parent_child_order);
+}
+
+void
+_elm_win_default_label_obj_remove(Evas_Object *default_label_obj)
+{
+   if (!default_label_obj) return;
+
+   Evas_Object *win = elm_widget_top_get(default_label_obj);
+   if (!win || !efl_isa(win, EFL_UI_WIN_CLASS))
+     {
+        WRN("The top object of %s is not a window.",
+            efl_class_name_get(efl_class_get(default_label_obj)));
+        return;
+     }
+
+   ELM_WIN_DATA_GET(win, sd);
+   if (!sd) return;
+
+   if (eina_list_data_find(sd->default_label_objs, default_label_obj))
+     {
+        sd->default_label_objs =
+          eina_list_remove(sd->default_label_objs, default_label_obj);
+        evas_object_event_callback_del_full(default_label_obj, EVAS_CALLBACK_DEL,
+                                            _default_label_obj_del_cb, win);
+     }
+}
+
+Evas_Object *
+_elm_win_default_label_obj_get(Evas_Object *obj)
+{
+   if (!obj) return NULL;
+   ELM_WIN_DATA_GET(obj, sd);
+   if (!sd) return NULL;
+
+   return eina_list_last_data_get(sd->default_label_objs);
+}
+//
+
 static Ecore_Window
 _elm_win_window_id_get(Efl_Ui_Win_Data *sd)
 {
index 833555e..280a803 100644 (file)
@@ -916,6 +916,9 @@ _on_show(void *data EINA_UNUSED,
          void *event_info EINA_UNUSED)
 {
    ELM_CTXPOPUP_DATA_GET(obj, sd);
+   //TIZEN_ONLY(20170919): Handle default label object
+   _elm_win_default_label_obj_append(obj);
+   //
 
    if (sd->list)
      {
@@ -960,6 +963,9 @@ _on_hide(void *data EINA_UNUSED,
 
    sd->visible = EINA_FALSE;
    sd->list_visible = EINA_FALSE;
+   //TIZEN_ONLY(20170919): Handle default label object
+   _elm_win_default_label_obj_remove(obj);
+   //
 }
 
 static void
index 18f5a06..fb2c5c5 100644 (file)
@@ -1220,12 +1220,14 @@ _on_item_pop_finished(void *data,
    elm_wdg_item_del(EO_OBJ(it));
 
    //TIZEN_ONLY(20161122): add state_notify api
-   if (_elm_atspi_enabled())
+   Eo *eo_top = elm_naviframe_top_item_get(widget);
+   if (eo_top)
      {
-        Eo *eo_top = elm_naviframe_top_item_get(widget);
-        if (eo_top)
+        ELM_NAVIFRAME_ITEM_DATA_GET(eo_top, top);
+        _elm_win_default_label_obj_append(VIEW(top));
+
+        if (_elm_atspi_enabled())
           {
-             ELM_NAVIFRAME_ITEM_DATA_GET(eo_top, top);
              efl_access_state_notify(VIEW(top), ACCESS_STATE(EFL_ACCESS_STATE_SHOWING) | ACCESS_STATE(EFL_ACCESS_STATE_VISIBLE), EINA_TRUE);
           }
      }
@@ -1258,7 +1260,12 @@ _on_item_show_finished(void *data,
    efl_event_callback_legacy_call(WIDGET(it), ELM_NAVIFRAME_EVENT_TRANSITION_FINISHED, EO_OBJ(it));
 
    if (EO_OBJ(it) == elm_naviframe_top_item_get(WIDGET(it)))
-     efl_event_callback_legacy_call(WIDGET(it), ELM_NAVIFRAME_EVENT_ITEM_ACTIVATED, EO_OBJ(it));
+     {
+        efl_event_callback_legacy_call(WIDGET(it), ELM_NAVIFRAME_EVENT_ITEM_ACTIVATED, EO_OBJ(it));
+        //TIZEN_ONLY(20170919): Handle default label object
+        _elm_win_default_label_obj_append(VIEW(it));
+        //
+     }
 }
 
 static void
@@ -1650,7 +1657,12 @@ _item_push_helper(Elm_Naviframe_Item_Data *item)
    elm_layout_sizing_eval(obj);
 
    if (!top_item)
-     efl_event_callback_legacy_call(obj, ELM_NAVIFRAME_EVENT_ITEM_ACTIVATED, EO_OBJ(item));
+     {
+        efl_event_callback_legacy_call(obj, ELM_NAVIFRAME_EVENT_ITEM_ACTIVATED, EO_OBJ(item));
+        //TIZEN_ONLY(20170919): Handle default label object
+        _elm_win_default_label_obj_append(VIEW(item));
+        //
+     }
 }
 
 EAPI Evas_Object *
index 9aa1a53..7327c15 100644 (file)
@@ -147,6 +147,9 @@ _timeout_cb(void *data, const Efl_Event *event EINA_UNUSED)
 static void
 _show_finished_cb(void *data, const Efl_Event *event EINA_UNUSED)
 {
+   //TIZEN_ONLY(20170919): Handle default label object
+   _elm_win_default_label_obj_append(data);
+   //
    efl_event_callback_legacy_call(data, ELM_POPUP_EVENT_SHOW_FINISHED, NULL);
 }
 /* END */
@@ -2132,8 +2135,11 @@ _elm_popup_scrollable_get(Eo *obj EINA_UNUSED, Elm_Popup_Data *pd)
 }
 
 EOLIAN static void
-_elm_popup_dismiss(Eo *obj EINA_UNUSED, Elm_Popup_Data *pd)
+_elm_popup_dismiss(Eo *obj, Elm_Popup_Data *pd)
 {
+   //TIZEN_ONLY(20170919): Handle default label object
+   _elm_win_default_label_obj_remove(obj);
+   //
    elm_layout_signal_emit(pd->main_layout, "elm,state,hide", "elm");
    elm_notify_dismiss(pd->notify);
 }
index 49ae6b9..5648a3c 100644 (file)
@@ -1355,6 +1355,39 @@ fail:
 }
 //
 
+//TIZEN_ONLY(20170919): Handle default label object
+static Eldbus_Message *
+_accessible_default_label_info_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
+{
+   Eldbus_Message *ret;
+   Eldbus_Message_Iter *iter;
+   const char *obj_path = eldbus_message_path_get(msg);
+   Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
+   Eo *obj = _bridge_object_from_path(bridge, obj_path);
+   Eo *default_label_obj;
+   Efl_Access_Role role;
+   AtspiRole atspi_role = ATSPI_ROLE_INVALID;
+
+   ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, EFL_ACCESS_MIXIN, msg);
+
+   ret = eldbus_message_method_return_new(msg);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
+
+   iter = eldbus_message_iter_get(ret);
+
+    default_label_obj = _elm_win_default_label_obj_get(obj);
+    if (!default_label_obj) default_label_obj = obj;
+   _bridge_iter_object_reference_append(bridge, iter, default_label_obj);
+   _bridge_object_register(bridge, default_label_obj);
+
+   role = efl_access_role_get(default_label_obj);
+   atspi_role = role > EFL_ACCESS_ROLE_LAST_DEFINED ? ATSPI_ROLE_LAST_DEFINED : elm_roles_to_atspi_roles[role][1];
+   eldbus_message_iter_basic_append(iter, 'u', atspi_role);
+
+   return ret;
+}
+//
+
 static const Eldbus_Method accessible_methods[] = {
    // TIZEN_ONLY(20170310) - implementation of get object under coordinates for accessibility
    { "GetNavigableAtPoint", ELDBUS_ARGS({"i", "x"}, {"i", "y"}, {"u", "coord_type"}), ELDBUS_ARGS({"(so)", "accessible"}), _accessible_get_navigable_at_point, 0 },
@@ -1398,6 +1431,11 @@ static const Eldbus_Method accessible_methods[] = {
                  {"(so)", "describecByObject"}),
      _accessible_reading_material_get, 0},
    //
+   //TIZEN_ONLY(20170919): Handle default label object
+   { "GetDefaultLabelInfo",
+     NULL, ELDBUS_ARGS({"(so)", "defaultLabelObject"}, {"u", "defaultLabelRole"}),
+     _accessible_default_label_info_get, 0},
+   //
    { NULL, NULL, NULL, NULL, 0 }
 };
 
index 704c044..57a3a47 100644 (file)
@@ -142,6 +142,10 @@ _accessible_panel_hidden_set(Evas_Object* obj, Eina_Bool is_hidden)
    is_hidden = !!is_hidden;
    efl_access_can_highlight_set(obj, !is_hidden);
    efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_SHOWING, !is_hidden);
+   if (is_hidden)
+     _elm_win_default_label_obj_remove(obj);
+   else
+     _elm_win_default_label_obj_append(obj);
 }
 //
 
index ab278d2..a28113a 100644 (file)
@@ -563,6 +563,11 @@ void                  _elm_win_focus_auto_hide(Evas_Object *obj);
 // Evas_Object          *_elm_win_accessibility_highlight_get(Evas_Object *win);
 // //
 void                  _elm_win_object_set_accessibility_highlight(Evas_Object *win, Evas_Object *obj, Eina_Bool visible);
+//TIZEN_ONLY(20170919): Handle default label object
+void                  _elm_win_default_label_obj_append(Evas_Object *default_label_obj);
+void                  _elm_win_default_label_obj_remove(Evas_Object *default_label_obj);
+Evas_Object          *_elm_win_default_label_obj_get(Evas_Object *obj);
+//
 // TIZEN_ONLY(20171114): atspi: expose highlight information on atspi
 void                 *_elm_object_accessibility_currently_highlighted_get();
 //