atspi: Handle default label object on toolkit side 33/151033/8
authorShinwoo Kim <cinoo.kim@samsung.com>
Tue, 19 Sep 2017 11:28:12 +0000 (20:28 +0900)
committerShinwoo Kim <cinoo.kim@samsung.com>
Sat, 30 Sep 2017 08:25:13 +0000 (17:25 +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: I0834f9d0625f4e787d6315ce4858bdec4a67ab18

src/lib/elc_naviframe.c
src/lib/elc_popup.c
src/lib/elm_atspi_bridge.c
src/lib/elm_panel.c
src/lib/elm_widget.h
src/lib/elm_win.c
src/mobile_lib/elc_ctxpopup.c

index 69eb7be..59274de 100644 (file)
@@ -1295,12 +1295,14 @@ _on_item_pop_finished(void *data,
    eo_do(EO_OBJ(it), elm_wdg_item_del());
 
    //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);
              eo_do(VIEW(top), elm_interface_atspi_accessible_state_notify(
                    ATSPI_STATE(ELM_ATSPI_STATE_SHOWING) | ATSPI_STATE(ELM_ATSPI_STATE_VISIBLE), EINA_TRUE));
           }
@@ -1342,7 +1344,12 @@ _on_item_show_finished(void *data,
    eo_do(WIDGET(it), eo_event_callback_call(ELM_NAVIFRAME_EVENT_TRANSITION_FINISHED, EO_OBJ(it)));
 
    if (EO_OBJ(it) == elm_naviframe_top_item_get(WIDGET(it)))
-     eo_do(WIDGET(it), eo_event_callback_call(ELM_NAVIFRAME_EVENT_ITEM_ACTIVATED, EO_OBJ(it)));
+     {
+        eo_do(WIDGET(it), eo_event_callback_call(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
@@ -1891,7 +1898,12 @@ _item_push_helper(Elm_Naviframe_Item_Data *item)
    elm_layout_sizing_eval(obj);
 
    if (!top_item)
-     eo_do(obj, eo_event_callback_call(ELM_NAVIFRAME_EVENT_ITEM_ACTIVATED, EO_OBJ(item)));
+     {
+        eo_do(obj, eo_event_callback_call(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 1301887..4bbc3db 100644 (file)
@@ -152,6 +152,9 @@ static Eina_Bool
 _show_finished_cb(void *data,
       Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
 {
+   //TIZEN_ONLY(20170919): Handle default label object
+   _elm_win_default_label_obj_append(data);
+   //
    eo_do(data, eo_event_callback_call(ELM_POPUP_EVENT_SHOW_FINISHED, NULL));
 
    return EINA_TRUE;
@@ -2520,6 +2523,9 @@ _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)
 {
+   //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 4183fc8..2d51da2 100644 (file)
@@ -1391,6 +1391,38 @@ fail:
    return NULL;
 }
 //
+//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;
+   Elm_Atspi_Role role;
+   AtspiRole atspi_role = ATSPI_ROLE_INVALID;
+
+   ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_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);
+
+   eo_do(default_label_obj, role = elm_interface_atspi_accessible_role_get());
+   atspi_role = role > ELM_ATSPI_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
@@ -1434,6 +1466,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 0662227..bda52ea 100644 (file)
@@ -138,6 +138,11 @@ _accessible_panel_hidden_set(Evas_Object* obj, Eina_Bool is_hidden)
    is_hidden = !!is_hidden;
    elm_atspi_accessible_can_highlight_set(obj, !is_hidden);
    elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_SHOWING, !is_hidden);
+
+   if (is_hidden)
+     _elm_win_default_label_obj_remove(obj);
+   else
+     _elm_win_default_label_obj_append(obj);
 }
 //
 
index eb381bf..449da33 100644 (file)
@@ -579,6 +579,12 @@ void                  _elm_win_focus_auto_hide(Evas_Object *obj);
 //TIZEN_ONLY(20160404) Accessibility Highlight Frame added (99248ce)
 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);
+//
 void                 *_elm_object_accessibility_currently_highlighted_get();
 void                  _elm_widget_showing_geometry_get(Eo *obj, int *x, int *y, int *w, int *h);
 
index 1f36f5c..2ceb78e 100644 (file)
@@ -209,6 +209,9 @@ struct _Elm_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;
@@ -6963,6 +6966,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;
+        eo_do(data1, parent = elm_interface_atspi_accessible_parent_get());
+        while (parent)
+          {
+             if (parent == data2) return 1;
+             eo_do(parent, parent = elm_interface_atspi_accessible_parent_get());
+          }
+     }
+   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 || !eo_isa(win, ELM_WIN_CLASS))
+     {
+        WRN("The top object of %s is not a window.",
+            eo_class_name_get(eo_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 || !eo_isa(win, ELM_WIN_CLASS))
+     {
+        WRN("The top object of %s is not a window.",
+            eo_class_name_get(eo_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);
+}
+//
+
 EAPI Ecore_Window
 elm_win_window_id_get(const Evas_Object *obj)
 {
index 1bc846c..eac6aad 100644 (file)
@@ -1782,6 +1782,9 @@ _on_show(void *data EINA_UNUSED,
    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
 
    sd->visible = EINA_TRUE;
+   //TIZEN_ONLY(20170919): Handle default label object
+   _elm_win_default_label_obj_append(obj);
+   //
 
    elm_layout_signal_emit(obj, "elm,state,show", "elm");
 
@@ -1867,6 +1870,9 @@ _on_hide(void *data EINA_UNUSED,
    if (!sd->visible) return;
 
    sd->visible = EINA_FALSE;
+   //TIZEN_ONLY(20170919): Handle default label object
+   _elm_win_default_label_obj_remove(obj);
+   //
 }
 
 static void