From d122d0296f49546ed74e731cccc72cc31a3a0ed8 Mon Sep 17 00:00:00 2001 From: Shinwoo Kim Date: Tue, 19 Sep 2017 20:28:12 +0900 Subject: [PATCH] atspi: Handle default label object on toolkit side 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 | 24 +++++++--- src/lib/elc_popup.c | 6 +++ src/lib/elm_atspi_bridge.c | 37 ++++++++++++++++ src/lib/elm_panel.c | 5 +++ src/lib/elm_widget.h | 6 +++ src/lib/elm_win.c | 100 ++++++++++++++++++++++++++++++++++++++++++ src/mobile_lib/elc_ctxpopup.c | 6 +++ 7 files changed, 178 insertions(+), 6 deletions(-) diff --git a/src/lib/elc_naviframe.c b/src/lib/elc_naviframe.c index 38fc156..229f6af 100644 --- a/src/lib/elc_naviframe.c +++ b/src/lib/elc_naviframe.c @@ -1303,12 +1303,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)); } @@ -1350,7 +1352,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 @@ -1899,7 +1906,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 * diff --git a/src/lib/elc_popup.c b/src/lib/elc_popup.c index 1301887..4bbc3db 100644 --- a/src/lib/elc_popup.c +++ b/src/lib/elc_popup.c @@ -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); } diff --git a/src/lib/elm_atspi_bridge.c b/src/lib/elm_atspi_bridge.c index 4183fc8..2d51da2 100644 --- a/src/lib/elm_atspi_bridge.c +++ b/src/lib/elm_atspi_bridge.c @@ -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 } }; diff --git a/src/lib/elm_panel.c b/src/lib/elm_panel.c index 0662227..bda52ea 100644 --- a/src/lib/elm_panel.c +++ b/src/lib/elm_panel.c @@ -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); } // diff --git a/src/lib/elm_widget.h b/src/lib/elm_widget.h index eb381bf..449da33 100644 --- a/src/lib/elm_widget.h +++ b/src/lib/elm_widget.h @@ -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); diff --git a/src/lib/elm_win.c b/src/lib/elm_win.c index 1f36f5c..2ceb78e 100644 --- a/src/lib/elm_win.c +++ b/src/lib/elm_win.c @@ -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) { diff --git a/src/mobile_lib/elc_ctxpopup.c b/src/mobile_lib/elc_ctxpopup.c index 1bc846c..eac6aad 100644 --- a/src/mobile_lib/elc_ctxpopup.c +++ b/src/mobile_lib/elc_ctxpopup.c @@ -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 -- 2.7.4