Backport atspi patches from Elementary 1.14 RC 34/38934/1 accepted/tizen/common/20150504.070845 accepted/tizen/mobile/20150503.090804 accepted/tizen/tv/20150503.090738 accepted/tizen/wearable/20150503.090750 submit/tizen/20150502.040028
authorLukasz Stanislawski <lukasz.stanislawski@gmail.com>
Mon, 6 Apr 2015 08:54:57 +0000 (10:54 +0200)
committerLukasz Stanislawski <l.stanislaws@samsung.com>
Thu, 30 Apr 2015 14:41:41 +0000 (16:41 +0200)
Merge branch 'devs/stanluk/eo_object_items_atspi'

Make elm object items atspi-aware objects. Implement atspi support
for elm_genlist, elm_gengrid and elm_toolbar items.

atspi: add missing signals array sentiel.

@fix

Change-Id: I3269f3e958cf45e7daf6888be17872e1f6410dce

32 files changed:
src/lib/Makefile.am
src/lib/elm_atspi_app_object.c
src/lib/elm_atspi_bridge.c
src/lib/elm_entry.c
src/lib/elm_entry.eo
src/lib/elm_gengrid.c
src/lib/elm_gengrid.eo
src/lib/elm_gengrid_item.eo
src/lib/elm_genlist.c
src/lib/elm_genlist.eo
src/lib/elm_genlist_item.eo
src/lib/elm_interface_atspi_accessible.c
src/lib/elm_interface_atspi_accessible.eo
src/lib/elm_interface_atspi_accessible.h
src/lib/elm_interface_atspi_widget.c [deleted file]
src/lib/elm_interface_atspi_widget.eo [deleted file]
src/lib/elm_interfaces.h
src/lib/elm_list.c
src/lib/elm_list.eo
src/lib/elm_list_item.eo
src/lib/elm_radio.c
src/lib/elm_radio.eo
src/lib/elm_spinner.c
src/lib/elm_toolbar.c
src/lib/elm_toolbar.eo
src/lib/elm_toolbar_item.eo
src/lib/elm_widget.c
src/lib/elm_widget.eo
src/lib/elm_widget.h
src/lib/elm_widget_item.eo
src/tests/elm_test_gengrid.c
src/tests/elm_test_genlist.c

index cd283800e3ffbe887a512a00a1d46f7cb5789607..04c4e5b8ee9da0d20e310fc405c5332cc5976215 100644 (file)
@@ -448,7 +448,6 @@ elm_interface_atspi_image.c \
 elm_interface_atspi_selection.c \
 elm_interface_atspi_text.c \
 elm_interface_atspi_value.c \
-elm_interface_atspi_widget.c \
 elm_interface_atspi_widget_action.c \
 elm_interface_atspi_window.c \
 elm_interface_fileselector.c \
@@ -561,7 +560,6 @@ elm_interface_atspi_image.eo \
 elm_interface_atspi_selection.eo \
 elm_interface_atspi_text.eo \
 elm_interface_atspi_value.eo \
-elm_interface_atspi_widget.eo \
 elm_interface_atspi_widget_action.eo \
 elm_interface_atspi_window.eo \
 elm_interface_fileselector.eo \
@@ -664,7 +662,6 @@ elementaryeolianfiles_DATA = \
             elm_interface_atspi_selection.eo \
             elm_interface_atspi_text.eo \
             elm_interface_atspi_value.eo \
-            elm_interface_atspi_widget.eo \
             elm_interface_atspi_widget_action.eo \
             elm_interface_atspi_window.eo \
             elm_bg.eo \
index 08932cfcf2960e2d7562916b7296ed5fdfa7b400..4d8b37f1d62ee4e21a188f5a80c9731589993fe3 100644 (file)
@@ -41,10 +41,12 @@ _elm_atspi_app_object_elm_interface_atspi_accessible_children_get(Eo *obj EINA_U
    return accs;
 }
 
-EOLIAN static const char*
+EOLIAN static char*
 _elm_atspi_app_object_elm_interface_atspi_accessible_name_get(Eo *obj EINA_UNUSED, Elm_Atspi_App_Object_Data *_pd EINA_UNUSED)
 {
-   return elm_app_name_get();
+   const char *ret;
+   ret = elm_app_name_get();
+   return ret ? strdup(ret) : NULL;
 }
 
 EOLIAN static const char*
index a3f5e24099846e1e623b1d895c5fa590fb8b2562..9a21e67e6fa05df756f2bd5cc7a4e1eb8555d88c 100644 (file)
 
 #define SIZE(x) sizeof(x)/sizeof(x[0])
 
-static int _init_count = 0;
+typedef struct Key_Event_Info {
+     Ecore_Event_Key event;
+     int type;
+} Key_Event_Info;
 
+static int _init_count = 0;
 static Eldbus_Connection *_a11y_bus = NULL;
+static Eina_List *reemited_events;
 static Eo *_root;
 static Ecore_Idler *_cache_update_idler;
 static Eina_List *_pending_objects;
@@ -50,7 +55,7 @@ static unsigned long _object_property_broadcast_mask;
 static unsigned long _object_children_broadcast_mask;
 static unsigned long long _object_state_broadcast_mask;
 static unsigned long long _window_signal_broadcast_mask;
-static Ecore_Event_Handler *_key_hdl;
+static Ecore_Event_Filter *_key_flr;
 
 static Eina_Bool _state_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
 static Eina_Bool _property_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info);
@@ -68,7 +73,7 @@ static void _object_append_desktop_reference(Eldbus_Message_Iter *iter);
 static void _cache_build(void *obj);
 static void _object_register(Eo *obj, char *path);
 static void _iter_interfaces_append(Eldbus_Message_Iter *iter, const Eo *obj);
-static Eina_Bool _elm_atspi_bridge_key_down_event_notify(void *data, int type, void *event);
+static Eina_Bool _elm_atspi_bridge_key_filter(void *data, void *loop, int type, void *event);
 static void _object_signal_send(Eldbus_Service_Interface *infc, int sig_id, const char *minor, unsigned int det1, unsigned int det2, const char *variant_sig, ...);
 
 EO_CALLBACKS_ARRAY_DEFINE(_events_cb,
@@ -183,6 +188,7 @@ static const Eldbus_Signal _event_obj_signals[] = {
    [ATSPI_OBJECT_EVENT_TEXT_ATTRIBUTES_CHANGED] = {"TextAttributesChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
    [ATSPI_OBJECT_EVENT_TEXT_CARET_MOVED] = {"TextCaretMoved", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
    [ATSPI_OBJECT_EVENT_ATTRIBUTES_CHANGED] = {"AttributesChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
+   {NULL, ELDBUS_ARGS({NULL, NULL}), 0}
 };
 
 static const Eldbus_Signal _window_obj_signals[] = {
@@ -1767,10 +1773,12 @@ _accessible_property_get(const Eldbus_Service_Interface *interface, const char *
 
    if (!strcmp(property, "Name"))
      {
-        eo_do(obj, ret = elm_interface_atspi_accessible_name_get());
-        if (!ret)
-          ret = "";
-        eldbus_message_iter_basic_append(iter, 's', ret);
+        char *ret2;
+        eo_do(obj, ret2 = elm_interface_atspi_accessible_name_get());
+        if (!ret2)
+          ret2 = strdup("");
+        eldbus_message_iter_basic_append(iter, 's', ret2);
+        free(ret2);
         return EINA_TRUE;
      }
    else if (!strcmp(property, "Description"))
@@ -2135,11 +2143,13 @@ _append_item_fn(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED,
   _iter_interfaces_append(iter_struct, data);
 
   /* Marshall name */
-  const char *name = NULL;
+  char *name = NULL;
   eo_do(data, name = elm_interface_atspi_accessible_name_get());
   if (!name)
-    name = "";
+    name = strdup("");
+
   eldbus_message_iter_basic_append(iter_struct, 's', name);
+  free(name);
 
   /* Marshall role */
   eldbus_message_iter_basic_append(iter_struct, 'u', role);
@@ -2649,14 +2659,8 @@ _registered_events_list_update(void)
 }
 
 static void
-_handle_listener_change(void *data EINA_UNUSED, const Eldbus_Message *msg)
+_handle_listener_change(void *data EINA_UNUSED, const Eldbus_Message *msg EINA_UNUSED)
 {
-   const char *bus, *event;
-   if (!eldbus_message_arguments_get(msg, "ss", &bus, &event))
-     {
-        ERR("Invalid org.a11y.Registry signal message args.");
-        return;
-     }
    _registered_events_list_update();
 }
 
@@ -2763,17 +2767,6 @@ _property_changed_signal_send(void *data, Eo *obj EINA_UNUSED, const Eo_Event_De
    return EINA_TRUE;
 }
 
-static Eina_Bool
-_idler_cb(void *data EINA_UNUSED)
-{
-   Eo *obj;
-   EINA_LIST_FREE(_pending_objects, obj)
-      _cache_build(obj);
-   _pending_objects = NULL;
-   _cache_update_idler = NULL;
-   return EINA_FALSE;
-}
-
 static Eina_Bool
 _children_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
 {
@@ -2788,9 +2781,7 @@ _children_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *d
    // update cached objects
    if (ev_data->is_added)
      {
-        _pending_objects = eina_list_append(_pending_objects, obj);
-        if (!_cache_update_idler)
-          _cache_update_idler = ecore_idler_add(_idler_cb, NULL);
+        _cache_build(obj);
      }
 
    if (!STATE_TYPE_GET(_object_children_broadcast_mask, type))
@@ -3048,7 +3039,7 @@ _event_handlers_register(void)
    _register_hdl = eldbus_signal_handler_add(_a11y_bus, ATSPI_DBUS_NAME_REGISTRY, ATSPI_DBUS_PATH_REGISTRY, ATSPI_DBUS_INTERFACE_REGISTRY, "EventListenerRegistered", _handle_listener_change, NULL);
    _unregister_hdl = eldbus_signal_handler_add(_a11y_bus, ATSPI_DBUS_NAME_REGISTRY, ATSPI_DBUS_PATH_REGISTRY, ATSPI_DBUS_INTERFACE_REGISTRY, "EventListenerDeregistered", _handle_listener_change, NULL);
 
-   _key_hdl = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _elm_atspi_bridge_key_down_event_notify, NULL);
+   _key_flr = ecore_event_filter_add(NULL, _elm_atspi_bridge_key_filter, NULL, NULL);
 }
 
 static Eina_Bool
@@ -3252,46 +3243,132 @@ _elm_atspi_bridge_shutdown(void)
           eldbus_connection_unref(_a11y_bus);
         _a11y_bus = NULL;
 
-        if (_key_hdl)
-          ecore_event_handler_del(_key_hdl);
-        _key_hdl = NULL;
+        if (_key_flr)
+          ecore_event_filter_del(_key_flr);
+        _key_flr = NULL;
 
         _init_count = 0;
         _root = NULL;
      }
 }
 
+static Key_Event_Info*
+_key_event_info_new(int event_type, const Ecore_Event_Key *data)
+{
+   Key_Event_Info *ret;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(data, NULL);
+
+   ret = calloc(sizeof(Key_Event_Info), 1);
+
+   ret->type = event_type;
+   ret->event = *data;
+
+   ret->event.keyname = eina_stringshare_add(data->keyname);
+   ret->event.key = eina_stringshare_add(data->key);
+   ret->event.string = eina_stringshare_add(data->string);
+   ret->event.compose = eina_stringshare_add(data->compose);
+
+   // not sure why it is here, but explicite keep it NULLed.
+   ret->event.data = NULL;
+
+   return ret;
+}
+
 static void
-_iter_marshall_key_down_event(Eldbus_Message_Iter *iter, Ecore_Event_Key *event)
+_key_event_info_free(Key_Event_Info *data)
 {
-   Eldbus_Message_Iter *struct_iter;
+   EINA_SAFETY_ON_NULL_RETURN(data);
+
+   eina_stringshare_del(data->event.keyname);
+   eina_stringshare_del(data->event.key);
+   eina_stringshare_del(data->event.string);
+   eina_stringshare_del(data->event.compose);
 
-   EINA_SAFETY_ON_NULL_RETURN(event);
+   free(data);
+}
+
+static void
+_iter_marshall_key_event(Eldbus_Message_Iter *iter, Key_Event_Info *data)
+{
+   Eldbus_Message_Iter *struct_iter;
+   EINA_SAFETY_ON_NULL_RETURN(data);
 
    struct_iter = eldbus_message_iter_container_new(iter, 'r', NULL);
 
-   const char *str = event->keyname ? event->keyname : "";
-   int is_text = event->keyname? 1 : 0;
-   eldbus_message_iter_arguments_append(struct_iter, "uiiiisb", ATSPI_KEY_PRESSED_EVENT, 0, event->keycode, 0, event->timestamp, str, is_text);
+   const char *str = data->event.keyname ? data->event.keyname : "";
+   int is_text = data->event.keyname ? 1 : 0;
+   int type;
+   if (data->type == ECORE_EVENT_KEY_DOWN)
+     type = ATSPI_KEY_PRESSED_EVENT;
+   else
+     type = ATSPI_KEY_RELEASED_EVENT;
 
+   eldbus_message_iter_arguments_append(struct_iter, "uiiiisb", type, 0, data->event.keycode, 0, data->event.timestamp, str, is_text);
    eldbus_message_iter_container_close(iter, struct_iter);
 }
 
+static void
+_on_event_del(void *user_data, void *func_data EINA_UNUSED)
+{
+   Key_Event_Info *info = user_data;
+   _key_event_info_free(info);
+}
+
+static void
+_on_listener_answer(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
+{
+   Key_Event_Info *info = data;
+   const char *errname, *errmsg;
+   Eina_Bool ret = EINA_TRUE;
+
+   if (eldbus_message_error_get(msg, &errname, &errmsg))
+     {
+        ERR("%s %s", errname, errmsg);
+        goto reemit;
+     }
+   if (!eldbus_message_arguments_get(msg, "b", &ret))
+     {
+        ERR("Return message doen not contian return value");
+        goto reemit;
+     }
+   if (ret)
+     {
+        _key_event_info_free(info);
+        return;
+     }
+reemit:
+   ecore_event_add(info->type, &info->event, _on_event_del, info);
+   reemited_events = eina_list_append(reemited_events, &info->event);
+}
+
 static Eina_Bool
-_elm_atspi_bridge_key_down_event_notify(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
+_elm_atspi_bridge_key_filter(void *data EINA_UNUSED, void *loop EINA_UNUSED, int type, void *event)
 {
    Eldbus_Message *msg;
    Eldbus_Message_Iter *iter;
    Ecore_Event_Key *key_event = event;
+   Key_Event_Info *ke;
 
    if (!_init_count) return EINA_TRUE;
+   if ((type != ECORE_EVENT_KEY_DOWN) && (type != ECORE_EVENT_KEY_UP)) return EINA_TRUE;
+
+   // check if reemited
+   if (eina_list_data_find(reemited_events, event))
+     {
+        reemited_events = eina_list_remove(reemited_events, event);
+        return EINA_TRUE;
+     }
+
+   ke = _key_event_info_new(type, key_event);
+   if (!ke) return EINA_TRUE;
 
    msg = eldbus_message_method_call_new(ATSPI_DBUS_NAME_REGISTRY, ATSPI_DBUS_PATH_DEC,
                                         ATSPI_DBUS_INTERFACE_DEC, "NotifyListenersSync");
    iter = eldbus_message_iter_get(msg);
-   _iter_marshall_key_down_event(iter, key_event);
+   _iter_marshall_key_event(iter, ke);
 
-   eldbus_connection_send(_a11y_bus, msg, NULL, NULL, -1);
+   // timeout should be kept reasonaby low to avoid
+   eldbus_connection_send(_a11y_bus, msg, _on_listener_answer, ke, 500);
 
-   return EINA_TRUE;
+   return EINA_FALSE;
 }
index e7f018ca6a247e2762b9a241838c29524c59f3ac..f9d7bd32499ac860c3ef4c80b2262a236dcba9e7 100644 (file)
@@ -5571,4 +5571,16 @@ _elm_entry_elm_interface_atspi_editable_text_cut(Eo *obj, Elm_Entry_Data *_pd EI
    return EINA_TRUE;
 }
 
+EOLIAN static Elm_Atspi_State_Set
+_elm_entry_elm_interface_atspi_accessible_state_set_get(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED)
+{
+   Elm_Atspi_State_Set ret;
+   eo_do_super(obj, ELM_ENTRY_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
+
+   if (elm_entry_editable_get(obj))
+     STATE_TYPE_SET(ret, ELM_ATSPI_STATE_EDITABLE);
+
+   return ret;
+}
+
 #include "elm_entry.eo.c"
index 278247b1b420f2fb50a9199e8f57d1800e26855e..4e5b9f6c82aa4a7531ac6567d8e5f9f1d6f8566e 100644 (file)
@@ -1201,6 +1201,7 @@ class Elm_Entry (Elm_Layout, Elm_Interface_Scrollable, Evas.Clickable_Interface,
       Elm_Layout.content_aliases.get;
       Elm_Interface_Scrollable.policy.set;
       Elm_Interface_Scrollable.bounce_allow.set;
+      Elm_Interface_Atspi_Accessible.state_set.get;
       Elm_Interface_Atspi_Text.text.get;
       Elm_Interface_Atspi_Text.string.get;
       Elm_Interface_Atspi_Text.attribute.get;
index 8ab1e738c78ff8adb97a9d33f8091c207d26bf0b..35f9c497bd014c1066a103822dd4c422f1ff5e81 100644 (file)
@@ -1647,6 +1647,8 @@ _elm_gengrid_item_focused(Elm_Object_Item *eo_it)
           evas_object_raise(VIEW(it));
      }
    evas_object_smart_callback_call(obj, SIG_ITEM_FOCUSED, eo_it);
+   if (_elm_config->atspi_mode)
+     elm_interface_atspi_accessible_state_changed_signal_emit(eo_it, ELM_ATSPI_STATE_FOCUSED, EINA_TRUE);
 }
 
 static void
@@ -1675,6 +1677,8 @@ _elm_gengrid_item_unfocused(Elm_Object_Item *eo_it)
 
    sd->focused_item = NULL;
    evas_object_smart_callback_call(obj, SIG_ITEM_UNFOCUSED, eo_it);
+   if (_elm_config->atspi_mode)
+     elm_interface_atspi_accessible_state_changed_signal_emit(eo_it, ELM_ATSPI_STATE_FOCUSED, EINA_FALSE);
 }
 
 static Eina_Bool
@@ -3629,6 +3633,7 @@ _elm_gengrid_item_eo_base_constructor(Eo *eo_it, Elm_Gen_Item *it)
 {
    eo_do_super(eo_it, ELM_GENGRID_ITEM_CLASS, eo_constructor());
    it->base = eo_data_scope_get(eo_it, ELM_WIDGET_ITEM_CLASS);
+   eo_do(eo_it, elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_LIST_ITEM));
 }
 
 static Elm_Gen_Item *
@@ -3818,7 +3823,7 @@ _elm_gengrid_eo_base_constructor(Eo *obj, Elm_Gengrid_Data *sd)
    eo_do(obj,
          evas_obj_type_set(MY_CLASS_NAME_LEGACY),
          evas_obj_smart_callbacks_descriptions_set(_smart_callbacks),
-         elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_TABLE));
+         elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_TREE_TABLE));
 }
 
 EOLIAN static void
@@ -4900,6 +4905,83 @@ _elm_gengrid_item_select_mode_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
    return it->select_mode;
 }
 
+EOLIAN Elm_Atspi_State_Set
+_elm_gengrid_item_elm_interface_atspi_accessible_state_set_get(Eo *eo_it, Elm_Gen_Item *it EINA_UNUSED)
+{
+   Elm_Atspi_State_Set ret;
+   Eina_Bool sel;
+
+   eo_do_super(eo_it, ELM_GENGRID_ITEM_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
+
+   eo_do(eo_it, sel = elm_obj_gengrid_item_selected_get());
+
+   STATE_TYPE_SET(ret, ELM_ATSPI_STATE_SELECTABLE);
+
+   if (sel)
+      STATE_TYPE_SET(ret, ELM_ATSPI_STATE_SELECTED);
+
+   return ret;
+}
+
+EOLIAN char*
+_elm_gengrid_item_elm_interface_atspi_accessible_name_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
+{
+   char *ret;
+   Eina_Strbuf *buf;
+
+   buf = eina_strbuf_new();
+
+   if (it->itc->func.text_get)
+     {
+        Eina_List *texts;
+        const char *key;
+
+        texts =
+           elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
+
+        EINA_LIST_FREE(texts, key)
+          {
+             char *s = it->itc->func.text_get
+                ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
+
+             s = _elm_util_mkup_to_text(s);
+
+             if (s)
+               {
+                  if (eina_strbuf_length_get(buf) > 0)
+                    eina_strbuf_append(buf, ", ");
+                  eina_strbuf_append(buf, s);
+                  free(s);
+               }
+          }
+     }
+
+   ret = eina_strbuf_string_steal(buf);
+   eina_strbuf_free(buf);
+   return ret;
+}
+
+EOLIAN Eina_List*
+_elm_gengrid_item_elm_interface_atspi_accessible_children_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
+{
+   Eina_List *ret = NULL;
+   if (VIEW(it))
+     {
+        Eina_List *parts;
+        const char *key;
+        parts = elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "contents"));
+
+        EINA_LIST_FREE(parts, key)
+          {
+             Evas_Object *part;
+             part = edje_object_part_swallow_get(VIEW(it), key);
+             if (part && eo_isa(part, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
+               ret = eina_list_append(ret, part);
+          }
+     }
+   return ret;
+}
+
 EAPI Elm_Object_Item *
 elm_gengrid_nth_item_get(const Evas_Object *obj, unsigned int nth)
 {
@@ -5031,5 +5113,29 @@ _elm_gengrid_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUS
    return &atspi_actions[0];
 }
 
+EOLIAN Eina_List*
+_elm_gengrid_elm_interface_atspi_accessible_children_get(Eo *obj EINA_UNUSED, Elm_Gengrid_Data *sd)
+{
+   Eina_List *ret = NULL;
+   Elm_Gen_Item *it;
+
+   EINA_INLIST_FOREACH(sd->items, it)
+      ret = eina_list_append(ret, EO_OBJ(it));
+
+   return ret;
+}
+
+EOLIAN Elm_Atspi_State_Set
+_elm_gengrid_elm_interface_atspi_accessible_state_set_get(Eo *obj, Elm_Gengrid_Data *sd EINA_UNUSED)
+{
+   Elm_Atspi_State_Set ret;
+
+   eo_do_super(obj, ELM_GENGRID_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
+
+   STATE_TYPE_SET(ret, ELM_ATSPI_STATE_MANAGES_DESCENDANTS);
+
+   return ret;
+}
+
 #include "elm_gengrid.eo.c"
 #include "elm_gengrid_item.eo.c"
index 506f0c3503d13846f214c34eb13c7c90b0b9b056..d808ef6a3e41c2ddbf913255f72ae3d882dc7120 100644 (file)
@@ -1,4 +1,5 @@
-class Elm_Gengrid (Elm_Layout, Elm_Interface_Scrollable, Evas.Clickable_Interface)
+class Elm_Gengrid (Elm_Layout, Elm_Interface_Scrollable,
+                   Evas.Clickable_Interface, Elm_Interface_Atspi_Widget_Action)
 {
    eo_prefix: elm_obj_gengrid;
    properties {
@@ -703,6 +704,9 @@ class Elm_Gengrid (Elm_Layout, Elm_Interface_Scrollable, Evas.Clickable_Interfac
       Elm_Layout.sizing_eval;
       Elm_Interface_Scrollable.bounce_allow.set;
       Elm_Interface_Scrollable.policy;
+      Elm_Interface_Atspi_Accessible.children.get;
+      Elm_Interface_Atspi_Accessible.state_set.get;
+      Elm_Interface_Atspi_Widget_Action.elm_actions.get;
    }
    events {
       language,changed;
index a7966acee70d731345d713a960427fdadfdb00f9..bb2fae11c957eb100fd385bf56435302e9383a19 100644 (file)
@@ -242,6 +242,9 @@ class Elm_Gengrid_Item(Elm_Widget_Item)
            Elm_Widget_Item.tooltip_unset;
            Elm_Widget_Item.cursor.set;
            Elm_Widget_Item.cursor_unset;
+           Elm_Interface_Atspi_Accessible.name.get;
+           Elm_Interface_Atspi_Accessible.state_set.get;
+           Elm_Interface_Atspi_Accessible.children.get;
       }
 }
 
index 68d045998b80455bfdd472fbbea7093dc6d7155a..d45ad4e360768a889d6d0cb209143949a62bea18 100644 (file)
@@ -328,6 +328,8 @@ _item_text_realize(Elm_Gen_Item *it,
           {
              edje_object_part_text_set(target, key, "");
           }
+        if (_elm_config->atspi_mode)
+          elm_interface_atspi_accessible_name_changed_signal_emit(EO_OBJ(it));
      }
 }
 
@@ -369,6 +371,8 @@ _item_content_realize(Elm_Gen_Item *it,
                   ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
              if (!content) continue;
              *contents = eina_list_append(*contents, content);
+             if (_elm_config->atspi_mode && eo_isa(content, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
+               eo_do(content, elm_interface_atspi_accessible_parent_set(EO_OBJ(it)));
              if (!edje_object_part_swallow(target, key, content))
                {
                   ERR("%s (%p) can not be swallowed into %s",
@@ -2563,6 +2567,8 @@ _elm_genlist_item_focused(Elm_Object_Item *eo_it)
           evas_object_raise(VIEW(it));
      }
    evas_object_smart_callback_call(obj, SIG_ITEM_FOCUSED, eo_it);
+   if (_elm_config->atspi_mode)
+     elm_interface_atspi_accessible_state_changed_signal_emit(eo_it, ELM_ATSPI_STATE_FOCUSED, EINA_TRUE);
 }
 
 static void
@@ -2589,6 +2595,8 @@ _elm_genlist_item_unfocused(Elm_Object_Item *eo_it)
 
    sd->focused_item = NULL;
    evas_object_smart_callback_call(obj, SIG_ITEM_UNFOCUSED, eo_it);
+   if (_elm_config->atspi_mode)
+     elm_interface_atspi_accessible_state_changed_signal_emit(eo_it, ELM_ATSPI_STATE_FOCUSED, EINA_FALSE);
 }
 
 static Eina_Bool
@@ -5819,7 +5827,9 @@ EOLIAN static void
 _elm_genlist_item_eo_base_constructor(Eo *eo_it, Elm_Gen_Item *it)
 {
    eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, eo_constructor());
+
    it->base = eo_data_scope_get(eo_it, ELM_WIDGET_ITEM_CLASS);
+   eo_do(eo_it, elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_LIST_ITEM));
 }
 
 static Elm_Gen_Item *
@@ -5973,6 +5983,9 @@ _elm_genlist_item_append(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, const Elm_Ge
    it->item->before = EINA_FALSE;
    _item_queue(sd, it, NULL);
 
+   if (_elm_config->atspi_mode)
+     elm_interface_atspi_accessible_children_changed_added_signal_emit(sd->obj, EO_OBJ(it));
+
    return EO_OBJ(it);
 }
 
@@ -6017,6 +6030,9 @@ _elm_genlist_item_prepend(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, const Elm_G
    it->item->before = EINA_TRUE;
    _item_queue(sd, it, NULL);
 
+   if (_elm_config->atspi_mode)
+     elm_interface_atspi_accessible_children_changed_added_signal_emit(sd->obj, EO_OBJ(it));
+
    return EO_OBJ(it);
 }
 
@@ -6064,6 +6080,9 @@ _elm_genlist_item_insert_after(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, const
    it->item->before = EINA_FALSE;
    _item_queue(sd, it, NULL);
 
+   if (_elm_config->atspi_mode)
+     elm_interface_atspi_accessible_children_changed_added_signal_emit(sd->obj, EO_OBJ(it));
+
    return EO_OBJ(it);
 }
 
@@ -6111,6 +6130,9 @@ _elm_genlist_item_insert_before(Eo *obj, Elm_Genlist_Data *sd, const Elm_Genlist
    it->item->before = EINA_TRUE;
    _item_queue(sd, it, NULL);
 
+   if (_elm_config->atspi_mode)
+     elm_interface_atspi_accessible_children_changed_added_signal_emit(sd->obj, EO_OBJ(it));
+
    return EO_OBJ(it);
 }
 
@@ -6214,6 +6236,9 @@ _elm_genlist_item_sorted_insert(Eo *obj, Elm_Genlist_Data *sd, const Elm_Genlist
 
    _item_queue(sd, it, _elm_genlist_item_list_compare);
 
+   if (_elm_config->atspi_mode)
+     elm_interface_atspi_accessible_children_changed_added_signal_emit(sd->obj, eo_it);
+
    return eo_it;
 }
 
@@ -7561,6 +7586,86 @@ _elm_genlist_item_select_mode_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
    return it->select_mode;
 }
 
+EOLIAN Elm_Atspi_State_Set
+_elm_genlist_item_elm_interface_atspi_accessible_state_set_get(Eo *eo_it, Elm_Gen_Item *it EINA_UNUSED)
+{
+   Elm_Atspi_State_Set ret;
+   Eina_Bool sel;
+
+   eo_do_super(eo_it, ELM_GENLIST_ITEM_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
+
+   eo_do(eo_it, sel = elm_obj_genlist_item_selected_get());
+
+   STATE_TYPE_SET(ret, ELM_ATSPI_STATE_SELECTABLE);
+
+   if (sel)
+      STATE_TYPE_SET(ret, ELM_ATSPI_STATE_SELECTED);
+
+   return ret;
+}
+
+EOLIAN char*
+_elm_genlist_item_elm_interface_atspi_accessible_name_get(Eo *eo_it EINA_UNUSED,
+                                                          Elm_Gen_Item *it)
+{
+   char *ret;
+   Eina_Strbuf *buf;
+
+   buf = eina_strbuf_new();
+
+   if (it->itc->func.text_get)
+     {
+        Eina_List *texts;
+        const char *key;
+
+        texts =
+           elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "texts"));
+
+        EINA_LIST_FREE(texts, key)
+          {
+             char *s = it->itc->func.text_get
+                ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
+
+             s = _elm_util_mkup_to_text(s);
+
+             if (s)
+               {
+                  if (eina_strbuf_length_get(buf) > 0) eina_strbuf_append(buf, ", ");
+                  eina_strbuf_append(buf, s);
+                  free(s);
+               }
+          }
+     }
+
+   ret = eina_strbuf_string_steal(buf);
+   eina_strbuf_free(buf);
+   return ret;
+}
+
+EOLIAN Eina_List*
+_elm_genlist_item_elm_interface_atspi_accessible_children_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
+{
+   Eina_List *ret = NULL;
+   if (VIEW(it))
+     {
+        Eina_List *parts;
+        const char *key;
+        parts = elm_widget_stringlist_get(edje_object_data_get(VIEW(it), "contents"));
+
+        EINA_LIST_FREE(parts, key)
+          {
+             Evas_Object *part;
+             part = edje_object_part_swallow_get(VIEW(it), key);
+             if (part && eo_isa(part, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
+               {
+                  ret = eina_list_append(ret, part);
+                  eo_do(part, elm_interface_atspi_accessible_parent_set(eo_it));
+               }
+          }
+     }
+   return ret;
+}
+
 EOLIAN static void
 _elm_genlist_tree_effect_enabled_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Eina_Bool enabled)
 {
@@ -7748,5 +7853,29 @@ _elm_genlist_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUS
    return &atspi_actions[0];
 }
 
+EOLIAN Eina_List*
+_elm_genlist_elm_interface_atspi_accessible_children_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
+{
+   Eina_List *ret = NULL;
+   Elm_Gen_Item *it;
+
+   EINA_INLIST_FOREACH(sd->items, it)
+      ret = eina_list_append(ret, EO_OBJ(it));
+
+   return ret;
+}
+
+EOLIAN Elm_Atspi_State_Set
+_elm_genlist_elm_interface_atspi_accessible_state_set_get(Eo *obj, Elm_Genlist_Data *sd EINA_UNUSED)
+{
+   Elm_Atspi_State_Set ret;
+
+   eo_do_super(obj, ELM_GENLIST_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
+
+   STATE_TYPE_SET(ret, ELM_ATSPI_STATE_MANAGES_DESCENDANTS);
+
+   return ret;
+}
+
 #include "elm_genlist.eo.c"
 #include "elm_genlist_item.eo.c"
index 026a93d014245a4b363883f334359c07f9f6d50c..537a801251f0a0bf60c80d76560679a785e73c03 100644 (file)
@@ -728,6 +728,8 @@ class Elm_Genlist (Elm_Layout, Elm_Interface_Scrollable, Evas.Clickable_Interfac
       Elm_Layout.sizing_eval;
       Elm_Interface_Scrollable.bounce_allow;
       Elm_Interface_Scrollable.policy;
+      Elm_Interface_Atspi_Accessible.children.get;
+      Elm_Interface_Atspi_Accessible.state_set.get;
       Elm_Interface_Atspi_Widget_Action.elm_actions.get;
    }
    events {
index 34a6179ca3a47d9555b234afd4cee40a90b509c8..80984ab9417522a0d36e2b83add1f9342123a727 100644 (file)
@@ -505,6 +505,9 @@ class Elm_Genlist_Item(Elm_Widget_Item)
            Elm_Widget_Item.tooltip_unset;
            Elm_Widget_Item.cursor.set;
            Elm_Widget_Item.cursor_unset;
+           Elm_Interface_Atspi_Accessible.name.get;
+           Elm_Interface_Atspi_Accessible.state_set.get;
+           Elm_Interface_Atspi_Accessible.children.get;
       }
 }
 
index 4ddb36961949842655b240b13de39eafb8dd8981..36e0cc042aab6f9e1a76224b2f16be9118dd3168 100644 (file)
@@ -138,8 +138,9 @@ _elm_interface_atspi_accessible_index_in_parent_get(Eo *obj, void *pd EINA_UNUSE
    if (ret == (int)eina_list_count(children))
      {
         ERR("Object %s not present in its AT-SPI parents (%s) children list! This should never happen.", eo_class_name_get(eo_class_get(obj)), eo_class_name_get(eo_class_get(parent)));
-        return -1;
+        ret = -1;
      }
+   eina_list_free(children);
    return ret;
 }
 
@@ -193,7 +194,7 @@ _elm_interface_atspi_accessible_role_name_get(Eo *obj EINA_UNUSED, void *pd EINA
    return role > ELM_ATSPI_ROLE_LAST_DEFINED ? "" : Atspi_Name[role];
 }
 
-EOLIAN const char *
+EOLIAN char *
 _elm_interface_atspi_accessible_name_get(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED)
 {
    WRN("The %s object does not implement the \"accessible_name_get\" function.",
@@ -202,7 +203,7 @@ _elm_interface_atspi_accessible_name_get(Eo *obj EINA_UNUSED, void *pd EINA_UNUS
 }
 
 EOLIAN static void
-_elm_interface_atspi_accessible_name_set(Eo *obj, void *pd EINA_UNUSED, const char *val EINA_UNUSED)
+_elm_interface_atspi_accessible_name_set(Eo *obj, void *pd EINA_UNUSED, char *val EINA_UNUSED)
 {
    WRN("The %s object does not implement the \"accessible_name_set\" function.",
        eo_class_name_get(eo_class_get(obj)));
index 9ee5980acbd101cd7c5bbaa89a88aeac734a59f5..d277e3ada12e5e1ca9f8db78a5bbe82158f8ea3e 100644 (file)
@@ -14,12 +14,13 @@ mixin Elm_Interface_Atspi_Accessible ()
       }
       name @protected {
          get {
-            /*@ Gets an string describing ATSPI widget role name. */
+            /*@ Gets an string describing ATSPI widget role name. 
+                Should be free by a user. */
          }
          set {
          }
          values {
-            const(char)* name; /*@ obj name */
+            char* name; /*@ obj name */
          }
       }
       relation_set @protected {
index 32c9b952036ede058c0899c6f78cf6e39d2d83f5..acd152e1bd348b10c9b6cc3dc1a0cef1ebd84f6e 100644 (file)
@@ -304,8 +304,8 @@ EAPI void elm_atspi_attributes_list_free(Eina_List *list);
  */
 #define elm_interface_atspi_accessible_children_changed_added_signal_emit(obj, child) \
    do { \
-      Elm_Atspi_Event_Children_Changed_Data data = { EINA_TRUE, child }; \
-      eo_do(obj, eo_event_callback_call(ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_CHILDREN_CHANGED, &data)); \
+      Elm_Atspi_Event_Children_Changed_Data atspi_data = { EINA_TRUE, child }; \
+      eo_do(obj, eo_event_callback_call(ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_CHILDREN_CHANGED, &atspi_data)); \
    } while(0);
 
 /**
@@ -313,8 +313,8 @@ EAPI void elm_atspi_attributes_list_free(Eina_List *list);
  */
 #define elm_interface_atspi_accessible_children_changed_del_signal_emit(obj, child) \
    do { \
-      Elm_Atspi_Event_Children_Changed_Data data = { EINA_FALSE, child }; \
-      eo_do(obj, eo_event_callback_call(ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_CHILDREN_CHANGED, &data)); \
+      Elm_Atspi_Event_Children_Changed_Data atspi_data = { EINA_FALSE, child }; \
+      eo_do(obj, eo_event_callback_call(ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_CHILDREN_CHANGED, &atspi_data)); \
    } while(0);
 
 /**
diff --git a/src/lib/elm_interface_atspi_widget.c b/src/lib/elm_interface_atspi_widget.c
deleted file mode 100644 (file)
index cf04d89..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-#ifdef HAVE_CONFIG_H
-  #include "elementary_config.h"
-#endif
-
-#define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
-#define ELM_INTERFACE_ATSPI_COMPONENT_PROTECTED
-
-#include <Elementary.h>
-#include "elm_widget.h"
-#include "elm_priv.h"
-
-#include "assert.h"
-
-typedef struct _Elm_Interface_Atspi_Widget_Data Elm_Interface_Atspi_Widget_Data;
-
-struct _Elm_Interface_Atspi_Widget_Data {
-     Elm_Atspi_Role role;
-     const char *description;
-};
-
-static void
-_on_focus_change(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
-{
-   Eina_Bool val = data ? EINA_TRUE : EINA_FALSE;
-   elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_FOCUSED, val);
-}
-
-EOLIAN void
-_elm_interface_atspi_widget_eo_base_constructor(Eo *obj EINA_UNUSED, Elm_Interface_Atspi_Widget_Data *pd)
-{
-   eo_do_super(obj, ELM_INTERFACE_ATSPI_WIDGET_MIXIN, eo_constructor());
-
-   pd->role = ELM_ATSPI_ROLE_UNKNOWN;
-
-   // Elm_Widget_Access_Object can only be constructed on top of Elm_Widget
-   assert(eo_isa(obj, ELM_WIDGET_CLASS));
-
-   evas_object_smart_callback_add(obj, "focused", _on_focus_change, (void*)1);
-   evas_object_smart_callback_add(obj, "unfocused", _on_focus_change, NULL);
-}
-
-EOLIAN void
-_elm_interface_atspi_widget_eo_base_destructor(Eo *obj EINA_UNUSED, Elm_Interface_Atspi_Widget_Data *pd)
-{
-   Eo *parent;
-   if (pd->description) eina_stringshare_del(pd->description);
-
-   eo_do(obj, parent = elm_interface_atspi_accessible_parent_get());
-
-   if (parent && !eo_destructed_is(parent))
-     elm_interface_atspi_accessible_children_changed_del_signal_emit(parent, obj);
-
-   eo_do_super(obj, ELM_INTERFACE_ATSPI_WIDGET_MIXIN, eo_destructor());
-}
-
-EOLIAN static Eina_Bool
-_elm_interface_atspi_widget_elm_interface_atspi_component_focus_grab(Eo *obj, Elm_Interface_Atspi_Widget_Data *pd EINA_UNUSED)
-{
-   if (elm_object_focus_allow_get(obj))
-     {
-       Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
-       if (!ee) return EINA_FALSE;
-       ecore_evas_activate(ee);
-       elm_object_focus_set(obj, EINA_TRUE);
-       return EINA_TRUE;
-     }
-   return EINA_FALSE;
-}
-
-EOLIAN static const char*
-_elm_interface_atspi_widget_elm_interface_atspi_accessible_name_get(Eo *obj EINA_UNUSED, Elm_Interface_Atspi_Widget_Data *_pd EINA_UNUSED)
-{
-   return elm_object_text_get(obj);
-}
-
-EOLIAN static const char*
-_elm_interface_atspi_widget_elm_interface_atspi_accessible_description_get(Eo *obj EINA_UNUSED, Elm_Interface_Atspi_Widget_Data *_pd)
-{
-   return _pd->description;
-}
-
-EOLIAN static void
-_elm_interface_atspi_widget_elm_interface_atspi_accessible_description_set(Eo *obj EINA_UNUSED, Elm_Interface_Atspi_Widget_Data *_pd, const char *descr)
-{
-   eina_stringshare_replace(&_pd->description, descr);
-}
-
-EOLIAN static Elm_Atspi_Role
-_elm_interface_atspi_widget_elm_interface_atspi_accessible_role_get(Eo *obj EINA_UNUSED, Elm_Interface_Atspi_Widget_Data *pd EINA_UNUSED)
-{
-   return pd->role;
-}
-
-EOLIAN static void
-_elm_interface_atspi_widget_elm_interface_atspi_accessible_role_set(Eo *obj EINA_UNUSED, Elm_Interface_Atspi_Widget_Data *pd, Elm_Atspi_Role role)
-{
-   pd->role = role;
-}
-
-EOLIAN static Eina_List*
-_elm_interface_atspi_widget_elm_interface_atspi_accessible_children_get(Eo *obj EINA_UNUSED, Elm_Interface_Atspi_Widget_Data *pd EINA_UNUSED)
-{
-   Eina_List *l, *accs = NULL;
-   Elm_Widget_Smart_Data *wd;
-   Evas_Object *widget;
-
-   wd = eo_data_scope_get(obj, ELM_WIDGET_CLASS);
-   if (!wd) return NULL;
-
-   EINA_LIST_FOREACH(wd->subobjs, l, widget)
-     {
-        if (!elm_object_widget_check(widget)) continue;
-        if (eo_isa(widget, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
-          accs = eina_list_append(accs, widget);
-     }
-   return accs;
-}
-
-EOLIAN static Elm_Atspi_State_Set
-_elm_interface_atspi_widget_elm_interface_atspi_accessible_state_set_get(Eo *obj, Elm_Interface_Atspi_Widget_Data *pd EINA_UNUSED)
-{
-   Elm_Atspi_State_Set states = 0;
-   Evas *evas = NULL;
-
-   eo_do_super(obj, ELM_INTERFACE_ATSPI_WIDGET_MIXIN, states = elm_interface_atspi_accessible_state_set_get());
-
-   if (evas_object_visible_get(obj))
-     STATE_TYPE_SET(states, ELM_ATSPI_STATE_VISIBLE);
-   evas = evas_object_evas_get(obj);
-   if (evas)
-     {
-        Evas_Coord x, y, w, h, wx, wy, ww, wh;
-
-        evas_output_viewport_get(evas, &x, &y, &w, &h);
-        evas_object_geometry_get(obj, &wx, &wy, &ww, &wh);
-        if (!(((wx < x) && (wx + ww < x)) || ((wx > x + w) && (wx + ww > x + w)) ||
-              ((wy < y) && (wy + wh < y)) || ((wy > y+ h) && (wy + wh > y + h))))
-          STATE_TYPE_SET(states, ELM_ATSPI_STATE_SHOWING);
-     }
-   if (elm_object_focus_get(obj))
-     STATE_TYPE_SET(states, ELM_ATSPI_STATE_FOCUSED);
-   if (elm_object_focus_allow_get(obj))
-     STATE_TYPE_SET(states, ELM_ATSPI_STATE_FOCUSABLE);
-   if (!elm_object_disabled_get(obj))
-     {
-        STATE_TYPE_SET(states, ELM_ATSPI_STATE_ENABLED);
-        STATE_TYPE_SET(states, ELM_ATSPI_STATE_ACTIVE);
-        STATE_TYPE_SET(states, ELM_ATSPI_STATE_SENSITIVE);
-     }
-
-   return states;
-}
-
-EOLIAN static Eina_List*
-_elm_interface_atspi_widget_elm_interface_atspi_accessible_attributes_get(Eo *obj, Elm_Interface_Atspi_Widget_Data *pd EINA_UNUSED)
-{
-   Eina_List *ret = NULL;
-   Elm_Atspi_Attribute *attr = calloc(1, sizeof(Elm_Atspi_Attribute));
-   if (!attr) return NULL;
-
-   attr->key = eina_stringshare_add("type");
-   attr->value = eina_stringshare_add(evas_object_type_get(obj));
-
-   ret = eina_list_append(ret, attr);
-   return ret;
-}
-
-static Elm_Atspi_Relation*
-_relation_new(Elm_Atspi_Relation_Type type, Eo *obj)
-{
-   Elm_Atspi_Relation *rel = calloc(1, sizeof(Elm_Atspi_Relation));
-   if (!rel) return NULL;
-
-   rel->type = type;
-   rel->obj = obj;
-
-   return rel;
-}
-
-EOLIAN static Eina_List*
-_elm_interface_atspi_widget_elm_interface_atspi_accessible_relation_set_get(Eo *obj, Elm_Interface_Atspi_Widget_Data *pd EINA_UNUSED)
-{
-   Eina_List *list = NULL;
-   Elm_Atspi_Relation *rel;
-   Evas_Object *rel_obj;
-
-   rel_obj = elm_object_focus_next_object_get(obj, ELM_FOCUS_NEXT);
-   if (eo_isa(rel_obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
-     {
-        rel = _relation_new(ELM_ATSPI_RELATION_FLOWS_TO, rel_obj);
-        list = eina_list_append(list, rel);
-     }
-
-   rel_obj = elm_object_focus_next_object_get(obj, ELM_FOCUS_PREVIOUS);
-   if (eo_isa(rel_obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
-     {
-        rel = _relation_new(ELM_ATSPI_RELATION_FLOWS_FROM, rel_obj);
-        list = eina_list_append(list, rel);
-     }
-
-   return list;
-}
-
-#include "elm_interface_atspi_widget.eo.c"
diff --git a/src/lib/elm_interface_atspi_widget.eo b/src/lib/elm_interface_atspi_widget.eo
deleted file mode 100644 (file)
index 672d212..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-mixin Elm_Interface_Atspi_Widget (Elm_Interface_Atspi_Accessible, Elm_Interface_Atspi_Component, Eo.Base)
-{
-   eo_prefix: elm_interface_atspi_widget;
-   data: Elm_Interface_Atspi_Widget_Data;
-   implements {
-      Eo.Base.constructor;
-      Eo.Base.destructor;
-      Elm_Interface_Atspi_Accessible.name.get;
-      Elm_Interface_Atspi_Accessible.description.get;
-      Elm_Interface_Atspi_Accessible.description.set;
-      Elm_Interface_Atspi_Accessible.role.get;
-      Elm_Interface_Atspi_Accessible.role.set;
-      Elm_Interface_Atspi_Accessible.state_set.get;
-      Elm_Interface_Atspi_Accessible.children.get;
-      Elm_Interface_Atspi_Accessible.attributes.get;
-      Elm_Interface_Atspi_Accessible.relation_set.get;
-      Elm_Interface_Atspi_Component.focus_grab;
-   }
-}
index a77c8cb65983a088ea1f2921be06178686da3548..61a359ef97e6759f2355ecfcfffeea8fc1e46ac3 100644 (file)
@@ -11,7 +11,6 @@
 #include "elm_interface_atspi_image.eo.h"
 #include "elm_interface_atspi_selection.eo.h"
 #include "elm_interface_atspi_value.eo.h"
-#include "elm_interface_atspi_widget.eo.h"
 #include "elm_interface_atspi_window.eo.h"
 #endif
 #endif
@@ -23,7 +22,6 @@
 #include "elm_interface_atspi_image.eo.legacy.h"
 #include "elm_interface_atspi_selection.eo.legacy.h"
 #include "elm_interface_atspi_value.eo.legacy.h"
-#include "elm_interface_atspi_widget.eo.legacy.h"
 #include "elm_interface_atspi_window.eo.legacy.h"
 #endif
 #endif
index 0f361db0a3b15bfe833675a00503bda5b941cbb8..60337148e1d4aeb17d7fadf5ed9ce0af52749f5e 100644 (file)
@@ -4,6 +4,7 @@
 
 #define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
 #define ELM_INTERFACE_ATSPI_WIDGET_ACTION_PROTECTED
+#define ELM_INTERFACE_ATSPI_SELECTION_PROTECTED
 #define ELM_WIDGET_ITEM_PROTECTED
 
 #include <Elementary.h>
@@ -1158,6 +1159,8 @@ _elm_list_item_focused(Elm_Object_Item *eo_it)
      evas_object_raise(VIEW(it));
    evas_object_smart_callback_call
       (WIDGET(it), SIG_ITEM_FOCUSED, eo_it);
+   if (_elm_config->atspi_mode)
+     elm_interface_atspi_accessible_state_changed_signal_emit(eo_it, ELM_ATSPI_STATE_FOCUSED, EINA_TRUE);
 }
 
 static void
@@ -1183,6 +1186,8 @@ _elm_list_item_unfocused(Elm_Object_Item *eo_it)
 
    sd->focused_item = NULL;
    evas_object_smart_callback_call(obj, SIG_ITEM_UNFOCUSED, eo_it);
+   if (_elm_config->atspi_mode)
+     elm_interface_atspi_accessible_state_changed_signal_emit(eo_it, ELM_ATSPI_STATE_FOCUSED, EINA_FALSE);
 }
 
 /*
@@ -2158,6 +2163,42 @@ _elm_list_item_elm_widget_item_focus_get(Eo *eo_it, Elm_List_Item_Data *it)
    return EINA_FALSE;
 }
 
+EOLIAN static Elm_Atspi_State_Set
+_elm_list_item_elm_interface_atspi_accessible_state_set_get(Eo *eo_it, Elm_List_Item_Data *data EINA_UNUSED)
+{
+   Elm_Atspi_State_Set ret;
+   Eina_Bool sel;
+
+   eo_do_super(eo_it, ELM_LIST_ITEM_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
+   eo_do(eo_it, sel = elm_obj_list_item_selected_get());
+
+   if (sel)
+     STATE_TYPE_SET(ret, ELM_ATSPI_STATE_SELECTED);
+   else
+     STATE_TYPE_UNSET(ret, ELM_ATSPI_STATE_SELECTED);
+
+   return ret;
+}
+
+EOLIAN static char*
+_elm_list_item_elm_interface_atspi_accessible_name_get(Eo *eo_it EINA_UNUSED, Elm_List_Item_Data *data)
+{
+   return data->label ? strdup(data->label) : NULL;
+}
+
+EOLIAN static Eina_List*
+_elm_list_item_elm_interface_atspi_accessible_children_get(Eo *eo_it EINA_UNUSED, Elm_List_Item_Data *data)
+{
+   Eina_List *ret = NULL;
+
+   if (data->icon && eo_isa(data->icon, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
+     ret = eina_list_append(ret, data->icon);
+   if (data->end && eo_isa(data->end, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
+     ret = eina_list_append(ret, data->end);
+
+   return ret;
+}
+
 static char *
 _access_info_cb(void *data, Evas_Object *obj EINA_UNUSED)
 {
@@ -2280,6 +2321,7 @@ _elm_list_item_eo_base_constructor(Eo *eo_it, Elm_List_Item_Data *it)
 {
    eo_do_super(eo_it, ELM_LIST_ITEM_CLASS, eo_constructor());
    it->base = eo_data_scope_get(eo_it, ELM_WIDGET_ITEM_CLASS);
+   eo_do(eo_it, elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_LIST_ITEM));
 }
 
 static Elm_List_Item_Data *
@@ -2778,6 +2820,9 @@ _elm_list_item_append(Eo *obj, Elm_List_Data *sd, const char *label, Evas_Object
    it->node = eina_list_last(sd->items);
    elm_box_pack_end(sd->box, VIEW(it));
 
+   if (_elm_config->atspi_mode)
+     elm_interface_atspi_accessible_children_changed_added_signal_emit(obj, EO_OBJ(it));
+
    return EO_OBJ(it);
 }
 
@@ -2792,6 +2837,9 @@ _elm_list_item_prepend(Eo *obj, Elm_List_Data *sd, const char *label, Evas_Objec
    it->node = sd->items;
    elm_box_pack_start(sd->box, VIEW(it));
 
+   if (_elm_config->atspi_mode)
+     elm_interface_atspi_accessible_children_changed_added_signal_emit(obj, EO_OBJ(it));
+
    return EO_OBJ(it);
 }
 
@@ -2811,6 +2859,9 @@ _elm_list_item_insert_before(Eo *obj, Elm_List_Data *sd, Elm_Object_Item *eo_bef
    it->node = before_it->node->prev;
    elm_box_pack_before(sd->box, VIEW(it), VIEW(before_it));
 
+   if (_elm_config->atspi_mode)
+     elm_interface_atspi_accessible_children_changed_added_signal_emit(obj, EO_OBJ(it));
+
    return EO_OBJ(it);
 }
 
@@ -2830,6 +2881,9 @@ _elm_list_item_insert_after(Eo *obj, Elm_List_Data *sd, Elm_Object_Item *eo_afte
    it->node = after_it->node->next;
    elm_box_pack_after(sd->box, VIEW(it), VIEW(after_it));
 
+   if (_elm_config->atspi_mode)
+     elm_interface_atspi_accessible_children_changed_added_signal_emit(obj, EO_OBJ(it));
+
    return EO_OBJ(it);
 }
 
@@ -2858,16 +2912,23 @@ _elm_list_item_sorted_insert(Eo *obj, Elm_List_Data *sd, const char *label, Evas
         elm_box_pack_before(sd->box, VIEW(it), VIEW(before));
      }
 
+   if (_elm_config->atspi_mode)
+     elm_interface_atspi_accessible_children_changed_added_signal_emit(obj, EO_OBJ(it));
+
    return EO_OBJ(it);
 }
 
 EOLIAN static void
-_elm_list_item_separator_set(Eo *eo_item EINA_UNUSED, Elm_List_Item_Data *it,
-      Eina_Bool setting)
+_elm_list_item_separator_set(Eo *eo_item, Elm_List_Item_Data *it, Eina_Bool setting)
 {
    ELM_LIST_ITEM_CHECK_OR_RETURN(it);
 
    it->is_separator = !!setting;
+
+   if (it->is_separator)
+      eo_do(eo_item, elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_SEPARATOR));
+   else
+      eo_do(eo_item, elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_LIST_ITEM));
 }
 
 EOLIAN static Eina_Bool
@@ -3166,5 +3227,101 @@ _elm_list_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED,
    };
    return &atspi_actions[0];
 }
+
+EOLIAN Eina_List*
+_elm_list_elm_interface_atspi_accessible_children_get(Eo *eo_item EINA_UNUSED, Elm_List_Data *pd)
+{
+   return eina_list_clone(pd->items);
+}
+
+EOLIAN int
+_elm_list_elm_interface_atspi_selection_selected_children_count_get(Eo *objm EINA_UNUSED, Elm_List_Data *pd)
+{
+   return eina_list_count(pd->selected);
+}
+
+EOLIAN Eo*
+_elm_list_elm_interface_atspi_selection_selected_child_get(Eo *obj EINA_UNUSED, Elm_List_Data *pd, int child_idx)
+{
+   return eina_list_nth(pd->selected, child_idx);
+}
+
+EOLIAN Eina_Bool
+_elm_list_elm_interface_atspi_selection_child_select(Eo *obj EINA_UNUSED, Elm_List_Data *pd, int child_index)
+{
+   if (pd->select_mode != ELM_OBJECT_SELECT_MODE_NONE)
+     {
+        Eo *item = eina_list_nth(pd->items, child_index);
+        if (item)
+           elm_list_item_selected_set(item, EINA_TRUE);
+        return EINA_TRUE;
+     }
+   return EINA_FALSE;
+}
+
+EOLIAN Eina_Bool
+_elm_list_elm_interface_atspi_selection_selected_child_deselect(Eo *obj EINA_UNUSED, Elm_List_Data *pd, int child_index)
+{
+   Eo *item = eina_list_nth(pd->selected, child_index);
+   if (item)
+     {
+        elm_list_item_selected_set(item, EINA_FALSE);
+        return EINA_TRUE;
+     }
+   return EINA_FALSE;
+}
+
+EOLIAN Eina_Bool
+_elm_list_elm_interface_atspi_selection_is_child_selected(Eo *obj EINA_UNUSED, Elm_List_Data *pd, int child_index)
+{
+   Eo *item = eina_list_nth(pd->items, child_index);
+   if (item)
+     return elm_list_item_selected_get(item);
+
+   return EINA_FALSE;
+}
+
+EOLIAN Eina_Bool
+_elm_list_elm_interface_atspi_selection_all_children_select(Eo *obj EINA_UNUSED, Elm_List_Data *pd)
+{
+   Eo *it;
+   Eina_List *l;
+
+   if (pd->select_mode == ELM_OBJECT_SELECT_MODE_NONE)
+     return EINA_FALSE;
+
+   EINA_LIST_FOREACH(pd->items, l, it)
+      elm_list_item_selected_set(it, EINA_TRUE);
+
+   return EINA_TRUE;
+}
+
+EOLIAN Eina_Bool
+_elm_list_elm_interface_atspi_selection_clear(Eo *obj EINA_UNUSED, Elm_List_Data *pd)
+{
+   Eo *it;
+   Eina_List *l;
+
+   if (pd->select_mode == ELM_OBJECT_SELECT_MODE_NONE)
+     return EINA_FALSE;
+
+   EINA_LIST_FOREACH(pd->items, l, it)
+      elm_list_item_selected_set(it, EINA_FALSE);
+
+   return EINA_TRUE;
+}
+
+EOLIAN Eina_Bool
+_elm_list_elm_interface_atspi_selection_child_deselect(Eo *obj EINA_UNUSED, Elm_List_Data *pd, int child_index)
+{
+   Eo *item = eina_list_nth(pd->items, child_index);
+   if (item)
+     {
+        elm_list_item_selected_set(item, EINA_FALSE);
+        return EINA_TRUE;
+     }
+   return EINA_FALSE;
+}
+
 #include "elm_list.eo.c"
 #include "elm_list_item.eo.c"
index f1b9556133233d133db8566879a0ff1381556822..9685ca08735c2cc4c4be779c6ae9c1dc484d9d06 100644 (file)
@@ -1,5 +1,5 @@
 class Elm_List (Elm_Layout, Elm_Interface_Scrollable,
-                Elm_Interface_Atspi_Widget_Action)
+                Elm_Interface_Atspi_Widget_Action, Elm_Interface_Atspi_Selection)
 {
    eo_prefix: elm_obj_list;
    properties {
@@ -609,6 +609,15 @@ class Elm_List (Elm_Layout, Elm_Interface_Scrollable,
       Elm_Layout.sizing_eval;
       Elm_Interface_Scrollable.policy.set;
       Elm_Interface_Atspi_Widget_Action.elm_actions.get;
+      Elm_Interface_Atspi_Accessible.children.get;
+      Elm_Interface_Atspi_Selection.selected_children_count.get;
+      Elm_Interface_Atspi_Selection.selected_child.get;
+      Elm_Interface_Atspi_Selection.selected_child_deselect;
+      Elm_Interface_Atspi_Selection.child_select;
+      Elm_Interface_Atspi_Selection.child_deselect;
+      Elm_Interface_Atspi_Selection.is_child_selected;
+      Elm_Interface_Atspi_Selection.all_children_select;
+      Elm_Interface_Atspi_Selection.clear;
    }
    events {
       activated;
index 597be64946764c207faa222d0e7978644e4c9ca7..7fa8c842002a173ef99162a7c9f089a0c4254dde 100644 (file)
@@ -6,9 +6,7 @@ class Elm_List_Item(Elm_Widget_Item)
                 get {
                      /*@
                       Get a value whether item is a separator or not.
-
-                      @see elm_list_item_separator_set() for details.
-
+@see elm_list_item_separator_set() for details.  
                       @ingroup List
                       */
                 }
@@ -163,6 +161,9 @@ class Elm_List_Item(Elm_Widget_Item)
            Elm_Widget_Item.part_content.get;
            Elm_Widget_Item.part_content.set;
            Elm_Widget_Item.part_content_unset;
+           Elm_Interface_Atspi_Accessible.name.get;
+           Elm_Interface_Atspi_Accessible.state_set.get;
+           Elm_Interface_Atspi_Accessible.children.get;
       }
 }
 
index da253f1f3aafc8b6f4f351ea86f121129b1fa1dd..604e823ee3e74fa6a3badb09183899ba84356d86 100644 (file)
@@ -57,6 +57,15 @@ _state_set(Evas_Object *obj, Eina_Bool state)
           elm_layout_signal_emit(obj, "elm,state,radio,on", "elm");
         else
           elm_layout_signal_emit(obj, "elm,state,radio,off", "elm");
+        if (_elm_config->atspi_mode)
+          {
+             if (sd->state)
+               {
+                  elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_CHECKED, EINA_TRUE);
+               }
+             else
+               elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_CHECKED, EINA_FALSE);
+          }
      }
 }
 
@@ -452,4 +461,16 @@ _elm_radio_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED
    return &atspi_actions[0];
 }
 
+EOLIAN Elm_Atspi_State_Set
+_elm_radio_elm_interface_atspi_accessible_state_set_get(Eo *obj, Elm_Radio_Data *pd EINA_UNUSED)
+{
+   Elm_Atspi_State_Set ret;
+
+   eo_do_super(obj, ELM_RADIO_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
+   if (obj == elm_radio_selected_object_get(obj))
+     STATE_TYPE_SET(ret, ELM_ATSPI_STATE_CHECKED);
+
+   return ret;
+}
+
 #include "elm_radio.eo.c"
index 566afdff1131fd9988539ffbfef11925cfc625ad..7a644aa5cf4d38682210c1051ed2c34242072b2a 100644 (file)
@@ -112,6 +112,7 @@ class Elm_Radio (Elm_Layout, Elm_Interface_Atspi_Widget_Action)
       Elm_Layout.text_aliases.get;
       Elm_Layout.content_aliases.get;
       Elm_Layout.sizing_eval;
+      Elm_Interface_Atspi_Accessible.state_set.get;
       Elm_Interface_Atspi_Widget_Action.elm_actions.get;
    }
    events {
index 77725eb326d0d43f2fad11d52f85f8b94e4d6c0a..f8007650f8566fb4b76959b8214c034b8703e0f4 100644 (file)
@@ -1114,10 +1114,11 @@ _elm_spinner_elm_interface_atspi_value_increment_get(Eo *obj EINA_UNUSED, Elm_Sp
    return sd->step;
 }
 
-EOLIAN static const char*
+EOLIAN static char*
 _elm_spinner_elm_interface_atspi_accessible_name_get(Eo *obj, Elm_Spinner_Data *sd EINA_UNUSED)
 {
-   return elm_layout_text_get(obj, "elm.text");
+   const char *ret = elm_layout_text_get(obj, "elm.text");
+   return ret ? strdup(ret) : NULL;
 }
 
 EOLIAN static const Elm_Atspi_Action*
index 92e217b8fae2cab9fd36e876868d097c9fe1e0a6..2e6ef22143fa59a18c434a89b39c3cba628679d1 100644 (file)
@@ -634,6 +634,8 @@ _elm_toolbar_item_focused(Elm_Object_Item *eo_it)
      evas_object_raise(VIEW(it));
    evas_object_smart_callback_call
       (obj, SIG_ITEM_FOCUSED, EO_OBJ(it));
+   if (_elm_config->atspi_mode)
+     elm_interface_atspi_accessible_state_changed_signal_emit(EO_OBJ(it), ELM_ATSPI_STATE_FOCUSED, EINA_TRUE);
 }
 
 static void
@@ -659,6 +661,8 @@ _elm_toolbar_item_unfocused(Elm_Object_Item *eo_it)
    sd->focused_item = NULL;
    evas_object_smart_callback_call
       (obj, SIG_ITEM_UNFOCUSED, eo_it);
+   if (_elm_config->atspi_mode)
+     elm_interface_atspi_accessible_state_changed_signal_emit(eo_it, ELM_ATSPI_STATE_FOCUSED, EINA_TRUE);
 }
 
 /*
@@ -2304,6 +2308,7 @@ _elm_toolbar_item_eo_base_constructor(Eo *eo_it, Elm_Toolbar_Item_Data *it)
 {
    eo_do_super(eo_it, ELM_TOOLBAR_ITEM_CLASS, eo_constructor());
    it->base = eo_data_scope_get(eo_it, ELM_WIDGET_ITEM_CLASS);
+   eo_do(eo_it, elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_MENU_ITEM));
 }
 
 static Elm_Toolbar_Item_Data *
@@ -3823,6 +3828,30 @@ _elm_toolbar_item_bring_in(Eo *eo_item EINA_UNUSED, Elm_Toolbar_Item_Data *item,
      (x, y, w, h));
 }
 
+EOLIAN static char*
+_elm_toolbar_item_elm_interface_atspi_accessible_name_get(Eo *eo_item EINA_UNUSED, Elm_Toolbar_Item_Data *item)
+{
+   return item->label ? strdup(item->label) : NULL;
+}
+
+EOLIAN static Elm_Atspi_State_Set
+_elm_toolbar_item_elm_interface_atspi_accessible_state_set_get(Eo *eo_it, Elm_Toolbar_Item_Data *item EINA_UNUSED)
+{
+   Elm_Atspi_State_Set ret;
+   Eina_Bool sel;
+
+   eo_do_super(eo_it, ELM_TOOLBAR_ITEM_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
+
+   eo_do(eo_it, sel = elm_obj_toolbar_item_selected_get());
+
+   STATE_TYPE_SET(ret, ELM_ATSPI_STATE_SELECTABLE);
+
+   if (sel)
+      STATE_TYPE_SET(ret, ELM_ATSPI_STATE_SELECTED);
+
+   return ret;
+}
+
 EOLIAN static Elm_Object_Item *
 _elm_toolbar_elm_widget_focused_item_get(Eo *obj EINA_UNUSED, Elm_Toolbar_Data *sd)
 {
@@ -3849,5 +3878,29 @@ _elm_toolbar_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUS
    return &atspi_actions[0];
 }
 
+EOLIAN static Eina_List*
+_elm_toolbar_elm_interface_atspi_accessible_children_get(Eo *obj EINA_UNUSED, Elm_Toolbar_Data *sd)
+{
+   Eina_List *ret = NULL;
+   Elm_Toolbar_Item_Data *it;
+
+   EINA_INLIST_FOREACH(sd->items, it)
+      ret = eina_list_append(ret, EO_OBJ(it));
+
+   return ret;
+}
+
+EOLIAN static Elm_Atspi_State_Set
+_elm_toolbar_elm_interface_atspi_accessible_state_set_get(Eo *obj, Elm_Toolbar_Data *sd EINA_UNUSED)
+{
+   Elm_Atspi_State_Set ret;
+
+   eo_do_super(obj, ELM_TOOLBAR_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
+
+   STATE_TYPE_SET(ret, ELM_ATSPI_STATE_MANAGES_DESCENDANTS);
+
+   return ret;
+}
+
 #include "elm_toolbar.eo.c"
 #include "elm_toolbar_item.eo.c"
index fe09f2557f63e732bc72788b6e76b5c4fc098697..7d572e5886f5516536d636420a3b1c10d105a7a3 100644 (file)
@@ -514,6 +514,8 @@ class Elm_Toolbar (Elm_Widget, Elm_Interface_Scrollable,
       Elm_Widget.focus_highlight_geometry_get;
       Elm_Widget.focused_item.get;
       Elm_Interface_Atspi_Widget_Action.elm_actions.get;
+      Elm_Interface_Atspi_Accessible.children.get;
+      Elm_Interface_Atspi_Accessible.state_set.get;
    }
    events {
       scroll;
index 9d0e8028a004bc818f356de1d2fdfc30ea8e9129..f0cb9282f705d5edc0934834d682e575083f9095 100644 (file)
@@ -424,5 +424,7 @@ class Elm_Toolbar_Item(Elm_Widget_Item)
            Elm_Widget_Item.part_content.get;
            Elm_Widget_Item.part_content.set;
            Elm_Widget_Item.part_content_unset;
+           Elm_Interface_Atspi_Accessible.name.get;
+           Elm_Interface_Atspi_Accessible.state_set.get;
       }
 }
index a465e17025af9f89f34b45a57b1abbd10691953e..3ad7e667bfb1fa98862c3f54fc2a64170b435bee 100644 (file)
@@ -2,6 +2,8 @@
 # include "elementary_config.h"
 #endif
 
+#define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
+#define ELM_INTERFACE_ATSPI_COMPONENT_PROTECTED
 #define ELM_WIDGET_ITEM_PROTECTED
 #include <Elementary.h>
 
@@ -541,6 +543,13 @@ _elm_widget_evas_object_smart_show(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUS
    Eina_Iterator *it;
    Evas_Object *o;
 
+   if (_elm_config->atspi_mode)
+     {
+        Eo *parent;
+        eo_do(obj, parent = elm_interface_atspi_accessible_parent_get());
+        elm_interface_atspi_accessible_children_changed_added_signal_emit(parent, obj);
+     }
+
    it = evas_object_smart_iterator_new(obj);
    EINA_ITERATOR_FOREACH(it, o)
      {
@@ -1283,6 +1292,8 @@ _elm_widget_sub_object_del(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Object *sobj
 
    sd->subobjs = eina_list_remove(sd->subobjs, sobj);
 
+   if (_elm_config->atspi_mode)
+     elm_interface_atspi_accessible_children_changed_del_signal_emit(obj, sobj);
    _callbacks_del(sobj, obj);
 
    return EINA_TRUE;
@@ -4274,6 +4285,12 @@ _elm_widget_item_eo_base_destructor(Eo *eo_item, Elm_Widget_Item_Data *item)
      }
    eina_hash_free(item->labels);
 
+   if (item->description)
+     eina_stringshare_del(item->description);
+
+   if (_elm_config->atspi_mode)
+        elm_interface_atspi_accessible_children_changed_del_signal_emit(item->widget, eo_item);
+
    EINA_MAGIC_SET(item, EINA_MAGIC_NONE);
 
    eo_do_super(eo_item, ELM_WIDGET_ITEM_CLASS, eo_destructor());
@@ -4396,6 +4413,61 @@ _elm_widget_item_widget_get(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
    return item->widget;
 }
 
+EOLIAN static const char*
+_elm_widget_item_elm_interface_atspi_accessible_description_get(Eo *eo_item EINA_UNUSED,
+                                                                Elm_Widget_Item_Data *item)
+{
+   return item->description;
+}
+
+EOLIAN static void
+_elm_widget_item_elm_interface_atspi_accessible_description_set(Eo *eo_item EINA_UNUSED,
+                                                                Elm_Widget_Item_Data *item,
+                                                                const char *descr)
+{
+   eina_stringshare_replace(&item->description, descr);
+}
+
+EOLIAN static Elm_Atspi_Role
+_elm_widget_item_elm_interface_atspi_accessible_role_get(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
+{
+   return item->role;
+}
+
+EOLIAN static void
+_elm_widget_item_elm_interface_atspi_accessible_role_set(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item,
+                                                         Elm_Atspi_Role role)
+{
+   item->role = role;
+}
+
+EOLIAN static Elm_Atspi_State_Set
+_elm_widget_item_elm_interface_atspi_accessible_state_set_get(Eo *eo_item EINA_UNUSED,
+                                                              Elm_Widget_Item_Data *item EINA_UNUSED)
+{
+   Elm_Atspi_State_Set states = 0;
+
+   STATE_TYPE_SET(states, ELM_ATSPI_STATE_FOCUSABLE);
+
+   if (elm_object_item_focus_get(eo_item))
+     STATE_TYPE_SET(states, ELM_ATSPI_STATE_FOCUSED);
+   if (!elm_object_item_disabled_get(eo_item))
+     {
+        STATE_TYPE_SET(states, ELM_ATSPI_STATE_ACTIVE);
+        STATE_TYPE_SET(states, ELM_ATSPI_STATE_ENABLED);
+        STATE_TYPE_SET(states, ELM_ATSPI_STATE_SENSITIVE);
+     }
+
+   return states;
+}
+
+EOLIAN static Eo*
+_elm_widget_item_elm_interface_atspi_accessible_parent_get(Eo *eo_item, Elm_Widget_Item_Data *item EINA_UNUSED)
+{
+   Eo *parent;
+   eo_do(eo_item, parent = eo_parent_get());
+   return parent;
+}
 
 EAPI void
 elm_object_item_data_set(Elm_Object_Item *it, void *data)
@@ -5354,6 +5426,13 @@ elm_widget_tree_dot_dump(const Evas_Object *top,
 #endif
 }
 
+static void
+_on_focus_change(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+   Eina_Bool val = data ? EINA_TRUE : EINA_FALSE;
+   elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_FOCUSED, val);
+}
+
 EOLIAN static void
 _elm_widget_eo_base_constructor(Eo *obj, Elm_Widget_Smart_Data *sd)
 {
@@ -5367,6 +5446,23 @@ _elm_widget_eo_base_constructor(Eo *obj, Elm_Widget_Smart_Data *sd)
          parent = eo_parent_get());
    eo_do(obj, elm_obj_widget_parent_set(parent));
    sd->on_create = EINA_FALSE;
+
+   sd->role = ELM_ATSPI_ROLE_UNKNOWN;
+   evas_object_smart_callback_add(obj, "focused", _on_focus_change, (void*)1);
+   evas_object_smart_callback_add(obj, "unfocused", _on_focus_change, NULL);
+}
+
+EOLIAN static void
+_elm_widget_eo_base_destructor(Eo *obj, Elm_Widget_Smart_Data *sd)
+{
+   Eo *parent;
+   if (sd->description) eina_stringshare_del(sd->description);
+
+   eo_do(obj, parent = elm_interface_atspi_accessible_parent_get());
+   if (parent && !eo_destructed_is(parent))
+     elm_interface_atspi_accessible_children_changed_del_signal_emit(parent, obj);
+
+   eo_do_super(obj, ELM_WIDGET_CLASS, eo_destructor());
 }
 
 EOLIAN static Eina_Bool
@@ -5435,5 +5531,172 @@ _elm_widget_class_constructor(Eo_Class *klass)
    evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
 }
 
+EOLIAN static Eina_Bool
+_elm_widget_elm_interface_atspi_component_focus_grab(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
+{
+   if (elm_object_focus_allow_get(obj))
+     {
+       Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
+       if (!ee) return EINA_FALSE;
+       ecore_evas_activate(ee);
+       elm_object_focus_set(obj, EINA_TRUE);
+       return EINA_TRUE;
+     }
+   return EINA_FALSE;
+}
+
+EOLIAN static char*
+_elm_widget_elm_interface_atspi_accessible_name_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
+{
+   const char *ret;
+   ret = elm_object_text_get(obj);
+   if (!ret) return NULL;
+
+   return _elm_util_mkup_to_text(ret);
+}
+
+EOLIAN static const char*
+_elm_widget_elm_interface_atspi_accessible_description_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd)
+{
+   return _pd->description;
+}
+
+EOLIAN static void
+_elm_widget_elm_interface_atspi_accessible_description_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd, const char *descr)
+{
+   eina_stringshare_replace(&_pd->description, descr);
+}
+
+EOLIAN static Elm_Atspi_Role
+_elm_widget_elm_interface_atspi_accessible_role_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd EINA_UNUSED)
+{
+   return pd->role;
+}
+
+EOLIAN static void
+_elm_widget_elm_interface_atspi_accessible_role_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd, Elm_Atspi_Role role)
+{
+   pd->role = role;
+}
+
+EOLIAN static Eina_List*
+_elm_widget_elm_interface_atspi_accessible_children_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd EINA_UNUSED)
+{
+   Eina_List *l, *accs = NULL;
+   Elm_Widget_Smart_Data *wd;
+   Evas_Object *widget;
+
+   wd = eo_data_scope_get(obj, ELM_WIDGET_CLASS);
+   if (!wd) return NULL;
+
+   EINA_LIST_FOREACH(wd->subobjs, l, widget)
+     {
+        if (!elm_object_widget_check(widget)) continue;
+        if (eo_isa(widget, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
+          accs = eina_list_append(accs, widget);
+     }
+   return accs;
+}
+
+EOLIAN static Eo*
+_elm_widget_elm_interface_atspi_accessible_parent_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd)
+{
+   if (pd->atspi_custom_parent)
+     return pd->atspi_custom_parent;
+   else
+     return pd->parent_obj;
+}
+
+EOLIAN static void
+_elm_widget_elm_interface_atspi_accessible_parent_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd, Eo *parent)
+{
+   pd->atspi_custom_parent = parent;
+}
+
+EOLIAN static Elm_Atspi_State_Set
+_elm_widget_elm_interface_atspi_accessible_state_set_get(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
+{
+   Elm_Atspi_State_Set states = 0;
+   Evas *evas = NULL;
+
+   eo_do_super(obj, ELM_WIDGET_CLASS, states = elm_interface_atspi_accessible_state_set_get());
+
+   if (evas_object_visible_get(obj))
+     STATE_TYPE_SET(states, ELM_ATSPI_STATE_VISIBLE);
+   evas = evas_object_evas_get(obj);
+   if (evas)
+     {
+        Evas_Coord x, y, w, h, wx, wy, ww, wh;
+
+        evas_output_viewport_get(evas, &x, &y, &w, &h);
+        evas_object_geometry_get(obj, &wx, &wy, &ww, &wh);
+        if (!(((wx < x) && (wx + ww < x)) || ((wx > x + w) && (wx + ww > x + w)) ||
+              ((wy < y) && (wy + wh < y)) || ((wy > y+ h) && (wy + wh > y + h))))
+          STATE_TYPE_SET(states, ELM_ATSPI_STATE_SHOWING);
+     }
+   if (elm_object_focus_get(obj))
+     STATE_TYPE_SET(states, ELM_ATSPI_STATE_FOCUSED);
+   if (elm_object_focus_allow_get(obj))
+     STATE_TYPE_SET(states, ELM_ATSPI_STATE_FOCUSABLE);
+   if (!elm_object_disabled_get(obj))
+     {
+        STATE_TYPE_SET(states, ELM_ATSPI_STATE_ENABLED);
+        STATE_TYPE_SET(states, ELM_ATSPI_STATE_ACTIVE);
+        STATE_TYPE_SET(states, ELM_ATSPI_STATE_SENSITIVE);
+     }
+
+   return states;
+}
+
+EOLIAN static Eina_List*
+_elm_widget_elm_interface_atspi_accessible_attributes_get(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
+{
+   Eina_List *ret = NULL;
+   Elm_Atspi_Attribute *attr = calloc(1, sizeof(Elm_Atspi_Attribute));
+   if (!attr) return NULL;
+
+   attr->key = eina_stringshare_add("type");
+   attr->value = eina_stringshare_add(evas_object_type_get(obj));
+
+   ret = eina_list_append(ret, attr);
+   return ret;
+}
+
+static Elm_Atspi_Relation*
+_relation_new(Elm_Atspi_Relation_Type type, Eo *obj)
+{
+   Elm_Atspi_Relation *rel = calloc(1, sizeof(Elm_Atspi_Relation));
+   if (!rel) return NULL;
+
+   rel->type = type;
+   rel->obj = obj;
+
+   return rel;
+}
+
+EOLIAN static Eina_List*
+_elm_widget_elm_interface_atspi_accessible_relation_set_get(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
+{
+   Eina_List *list = NULL;
+   Elm_Atspi_Relation *rel;
+   Evas_Object *rel_obj;
+
+   rel_obj = elm_object_focus_next_object_get(obj, ELM_FOCUS_NEXT);
+   if (eo_isa(rel_obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
+     {
+        rel = _relation_new(ELM_ATSPI_RELATION_FLOWS_TO, rel_obj);
+        list = eina_list_append(list, rel);
+     }
+
+   rel_obj = elm_object_focus_next_object_get(obj, ELM_FOCUS_PREVIOUS);
+   if (eo_isa(rel_obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
+     {
+        rel = _relation_new(ELM_ATSPI_RELATION_FLOWS_FROM, rel_obj);
+        list = eina_list_append(list, rel);
+     }
+
+   return list;
+}
+
 #include "elm_widget_item.eo.c"
 #include "elm_widget.eo.c"
index 9df00f8b75033939986f343f395717adb8931063..53e3c4fd8cfb0eb3ce311eea8e11fcff42929c34 100644 (file)
@@ -1,4 +1,4 @@
-abstract Elm_Widget (Evas.Object_Smart, Elm_Interface_Atspi_Widget)
+abstract Elm_Widget (Evas.Object_Smart, Elm_Interface_Atspi_Accessible, Elm_Interface_Atspi_Component)
 {
    eo_prefix: elm_obj_widget;
    data: Elm_Widget_Smart_Data;
@@ -796,6 +796,7 @@ abstract Elm_Widget (Evas.Object_Smart, Elm_Interface_Atspi_Widget)
    implements {
       class.constructor;
       Eo.Base.constructor;
+      Eo.Base.destructor;
       Eo.Base.dbg_info_get;
       Evas.Object_Smart.hide;
       Evas.Object_Smart.calculate;
@@ -812,5 +813,17 @@ abstract Elm_Widget (Evas.Object_Smart, Elm_Interface_Atspi_Widget)
       @virtual .focus_direction;
       @virtual .focus_next;
       @virtual .parent_widget.get;
+      Elm_Interface_Atspi_Accessible.name.get;
+      Elm_Interface_Atspi_Accessible.description.get;
+      Elm_Interface_Atspi_Accessible.description.set;
+      Elm_Interface_Atspi_Accessible.role.get;
+      Elm_Interface_Atspi_Accessible.role.set;
+      Elm_Interface_Atspi_Accessible.state_set.get;
+      Elm_Interface_Atspi_Accessible.children.get;
+      Elm_Interface_Atspi_Accessible.parent.get;
+      Elm_Interface_Atspi_Accessible.parent.set;
+      Elm_Interface_Atspi_Accessible.attributes.get;
+      Elm_Interface_Atspi_Accessible.relation_set.get;
+      Elm_Interface_Atspi_Component.focus_grab;
    }
 }
index e7b91ed67d08110c714c1019160652d9c25ff3c3..84c3442d086b099f8338dc3cbefa0639ddd1fac1 100644 (file)
@@ -407,6 +407,10 @@ typedef struct _Elm_Widget_Smart_Data
    Eina_List                    *focus_chain;
    Eina_List                    *event_cb;
 
+   int                          role;         /**< Accessibility role */
+   const char                   *description; /**< Accessibility description */
+   Eo                           *atspi_custom_parent; /**< Accessibility parent if different then parent_obj */
+
    /* this is a hook to be set on-the-fly on widgets. this is code
     * handling the request of showing a specific region from an inner
     * widget (mainly issued by entries, on cursor moving) */
@@ -614,6 +618,10 @@ struct _Elm_Widget_Item_Data
    Eina_Hash                     *labels;
    Evas_Object                   *track_obj;
 
+   /**< A11Y info */
+   const char                    *description;
+   int                            role;
+
    Eina_Bool                      disabled : 1;
    Eina_Bool                      on_deletion : 1;
    Eina_Bool                      on_translate : 1;
index 2c080faff3476fd91241212e98c632b6ef7a2865..431d237f52aa73f9796b17c4299e71aaca3541f0 100644 (file)
@@ -1,4 +1,4 @@
-class Elm_Widget_Item(Eo.Base)
+class Elm_Widget_Item(Eo.Base, Elm_Interface_Atspi_Accessible)
 {
       eo_prefix: elm_wdg_item;
       legacy_prefix: elm_object_item;
@@ -726,5 +726,11 @@ class Elm_Widget_Item(Eo.Base)
       implements {
            Eo.Base.constructor;
            Eo.Base.destructor;
+           Elm_Interface_Atspi_Accessible.description.get;
+           Elm_Interface_Atspi_Accessible.description.set;
+           Elm_Interface_Atspi_Accessible.role.get;
+           Elm_Interface_Atspi_Accessible.role.set;
+           Elm_Interface_Atspi_Accessible.state_set.get;
+           Elm_Interface_Atspi_Accessible.parent.get;
       }
 }
index cd10fd727436e886b8173ac09df6a2a12ae000bd..1d95a67bc5c95a5ad526cfba31e4b2dbff5e5234 100644 (file)
@@ -18,7 +18,7 @@ START_TEST (elm_atspi_role_get)
    gengrid = elm_gengrid_add(win);
    eo_do(gengrid, role = elm_interface_atspi_accessible_role_get());
 
-   ck_assert(role == ELM_ATSPI_ROLE_TABLE);
+   ck_assert(role == ELM_ATSPI_ROLE_TREE_TABLE);
 
    elm_shutdown();
 }
index d3bb70d5ac559c2a228c2be38af59b2e03c38d7e..ade75c880186bf60dbb0839b1a01da0a275ac827 100644 (file)
@@ -6,16 +6,26 @@
 #include <Elementary.h>
 #include "elm_suite.h"
 
+static Evas_Object *win, *genlist;
+static Elm_Gen_Item_Class itc;
+static Eo *current;
+static int counter;
+static Elm_Atspi_Event_Children_Changed_Data ev_data;
 
-START_TEST (elm_atspi_role_get)
+void test_init(void)
 {
-   Evas_Object *win, *genlist;
-   Elm_Atspi_Role role;
-
    elm_init(1, NULL);
+   elm_config_atspi_mode_set(EINA_TRUE);
    win = elm_win_add(NULL, "genlist", ELM_WIN_BASIC);
-
    genlist = elm_genlist_add(win);
+}
+
+START_TEST (elm_atspi_role_get)
+{
+   test_init();
+
+   Elm_Atspi_Role role;
+
    eo_do(genlist, role = elm_interface_atspi_accessible_role_get());
 
    ck_assert(role == ELM_ATSPI_ROLE_LIST);
@@ -24,7 +34,153 @@ START_TEST (elm_atspi_role_get)
 }
 END_TEST
 
+START_TEST(elm_atspi_children_get1)
+{
+   test_init();
+   Eina_List *children;
+   Elm_Object_Item *it[3];
+
+   eo_do(genlist, children = elm_interface_atspi_accessible_children_get());
+   ck_assert(children == NULL);
+
+   it[0] = elm_genlist_item_append(genlist, &itc, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
+   it[1] = elm_genlist_item_append(genlist, &itc, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
+   it[2] = elm_genlist_item_append(genlist, &itc, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
+
+   eo_do(genlist, children = elm_interface_atspi_accessible_children_get());
+   ck_assert(eina_list_count(children) == 3);
+   ck_assert(eina_list_nth(children, 0) == it[0]);
+   ck_assert(eina_list_nth(children, 1) == it[1]);
+   ck_assert(eina_list_nth(children, 2) == it[2]);
+
+   eina_list_free(children);
+
+   elm_shutdown();
+}
+END_TEST
+
+START_TEST(elm_atspi_children_get2)
+{
+   test_init();
+   Eina_List *children;
+   Elm_Object_Item *it[3];
+
+   it[0] = elm_genlist_item_append(genlist, &itc, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
+   it[1] = elm_genlist_item_prepend(genlist, &itc, NULL, NULL, ELM_GENLIST_ITEM_GROUP, NULL, NULL);
+   it[2] = elm_genlist_item_append(genlist, &itc, NULL, NULL, ELM_GENLIST_ITEM_TREE, NULL, NULL);
+
+   eo_do(genlist, children = elm_interface_atspi_accessible_children_get());
+   ck_assert(eina_list_nth(children, 1) == it[0]);
+   ck_assert(eina_list_nth(children, 0) == it[1]);
+   ck_assert(eina_list_nth(children, 2) == it[2]);
+
+   elm_shutdown();
+}
+END_TEST
+
+static Eina_Bool
+_children_changed_cb(void *data EINA_UNUSED, Eo *obj EINA_UNUSED,
+                     const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   ev_data = *(Elm_Atspi_Event_Children_Changed_Data*)event_info;
+   current = obj;
+   counter++;
+
+   return EINA_TRUE;
+}
+
+START_TEST(elm_atspi_children_events_add)
+{
+   test_init();
+
+   current = NULL;
+   counter = 0;
+
+   Elm_Object_Item *it[3];
+
+   eo_do(genlist, eo_event_callback_add(ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_CHILDREN_CHANGED, _children_changed_cb, NULL));
+
+   it[0] = elm_genlist_item_append(genlist, &itc, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
+   ck_assert(genlist == current);
+   ck_assert(counter == 1);
+   ck_assert(ev_data.is_added == EINA_TRUE);
+   ck_assert(ev_data.child == it[0]);
+
+   it[1] = elm_genlist_item_prepend(genlist, &itc, it[0], NULL, ELM_GENLIST_ITEM_GROUP, NULL, NULL);
+   ck_assert(genlist == current);
+   ck_assert(counter == 2);
+   ck_assert(ev_data.is_added == EINA_TRUE);
+   ck_assert(ev_data.child == it[1]);
+
+   it[2] = elm_genlist_item_append(genlist, &itc, NULL, NULL, ELM_GENLIST_ITEM_TREE, NULL, NULL);
+   ck_assert(genlist == current);
+   ck_assert(counter == 3);
+   ck_assert(ev_data.is_added == EINA_TRUE);
+   ck_assert(ev_data.child == it[2]);
+
+   elm_shutdown();
+}
+END_TEST
+
+START_TEST(elm_atspi_children_events_del1)
+{
+   test_init();
+
+   current = NULL;
+   counter = 0;
+
+   Elm_Object_Item *it[3];
+
+   it[0] = elm_genlist_item_append(genlist, &itc, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
+   it[1] = elm_genlist_item_prepend(genlist, &itc, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
+   it[2] = elm_genlist_item_append(genlist, &itc, NULL, NULL, ELM_GENLIST_ITEM_TREE, NULL, NULL);
+
+   eo_do(genlist, eo_event_callback_add(ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_CHILDREN_CHANGED, _children_changed_cb, NULL));
+
+   elm_object_item_del(it[0]);
+   ck_assert(genlist == current);
+   ck_assert(counter == 1);
+   ck_assert(ev_data.is_added == EINA_FALSE);
+   ck_assert(ev_data.child == it[0]);
+
+   elm_object_item_del(it[2]);
+   ck_assert(genlist == current);
+   ck_assert(counter == 2);
+   ck_assert(ev_data.is_added == EINA_FALSE);
+   ck_assert(ev_data.child == it[2]);
+
+   elm_shutdown();
+}
+END_TEST
+
+START_TEST(elm_atspi_children_events_del2)
+{
+   test_init();
+
+   Elm_Object_Item *it;
+   current = NULL;
+   counter = 0;
+
+   it = elm_genlist_item_append(genlist, &itc, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
+
+   eo_do(genlist, eo_event_callback_add(ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_CHILDREN_CHANGED, _children_changed_cb, NULL));
+   elm_genlist_clear(genlist);
+
+   ck_assert(genlist == current);
+   ck_assert(counter == 1);
+   ck_assert(ev_data.is_added == EINA_FALSE);
+   ck_assert(ev_data.child == it);
+
+   elm_shutdown();
+}
+END_TEST
+
 void elm_test_genlist(TCase *tc)
 {
- tcase_add_test(tc, elm_atspi_role_get);
+   tcase_add_test(tc, elm_atspi_role_get);
+   tcase_add_test(tc, elm_atspi_children_get1);
+   tcase_add_test(tc, elm_atspi_children_get2);
+   tcase_add_test(tc, elm_atspi_children_events_add);
+   tcase_add_test(tc, elm_atspi_children_events_del1);
+   tcase_add_test(tc, elm_atspi_children_events_del2);
 }