atspi: add global event emitter
authorLukasz Stanislawski <l.stanislaws@samsung.com>
Thu, 3 Sep 2015 12:07:23 +0000 (14:07 +0200)
committerLukasz Stanislawski <l.stanislaws@samsung.com>
Thu, 1 Oct 2015 14:00:28 +0000 (16:00 +0200)
Introduce global event emitter for accessibility events. With such emitter
there is no need to register array of callbacks on every accessibility object.

12 files changed:
legacy/elementary/src/lib/Makefile.am
legacy/elementary/src/lib/elm_atspi_bridge.c
legacy/elementary/src/lib/elm_entry.c
legacy/elementary/src/lib/elm_genlist.c
legacy/elementary/src/lib/elm_interface_atspi_accessible.c
legacy/elementary/src/lib/elm_interface_atspi_accessible.eo
legacy/elementary/src/lib/elm_interface_atspi_accessible.h
legacy/elementary/src/lib/elm_interface_atspi_window.h [new file with mode: 0644]
legacy/elementary/src/lib/elm_interfaces.h
legacy/elementary/src/lib/elm_widget.c
legacy/elementary/src/lib/elm_win.c
legacy/elementary/src/tests/elm_test_genlist.c

index 0922587..3b61532 100644 (file)
@@ -39,6 +39,7 @@ elm_atspi_bridge.h \
 elm_interface_atspi_accessible.h \
 elm_interface_atspi_text.h \
 elm_interface_atspi_widget_action.h \
+elm_interface_atspi_window.h \
 elm_interface_fileselector.h \
 elm_interface_scrollable.h \
 elm_interfaces.h \
index 5df0085..345ab6b 100644 (file)
@@ -93,14 +93,11 @@ typedef struct _Elm_Atspi_Bridge_Data
         Eldbus_Service_Interface *text;
         Eldbus_Service_Interface *value;
    } interfaces;
+   Elm_Atspi_Event_Handler *event_hdlr;
+   Eina_Hash *event_hash;
    Eina_Bool connected : 1;
 } Elm_Atspi_Bridge_Data;
 
-struct cache_closure {
-     Eo *bridge;
-     Eldbus_Message_Iter *iter;
-};
-
 static Eo *_instance;
 static int _init_count = 0;
 
@@ -109,6 +106,8 @@ static Eina_Bool _state_changed_signal_send(void *data, Eo *obj, const Eo_Event_
 static Eina_Bool _property_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info);
 static Eina_Bool _children_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info);
 static Eina_Bool _window_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
+static Eina_Bool _visible_data_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
+static Eina_Bool _active_descendant_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
 static Eina_Bool _selection_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
 static Eina_Bool _text_text_inserted_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
 static Eina_Bool _text_text_removed_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
@@ -116,7 +115,6 @@ static Eina_Bool _text_caret_moved_send(void *data, Eo *obj, const Eo_Event_Desc
 static Eina_Bool _text_selection_changed_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info EINA_UNUSED);
 
 // bridge private methods
-static void _bridge_cache_build(Eo *bridge, void *obj);
 static void _bridge_object_register(Eo *bridge, Eo *obj);
 static void _bridge_object_unregister(Eo *bridge, Eo *obj);
 static const char * _bridge_path_from_object(Eo *bridge, const Eo *eo);
@@ -127,37 +125,36 @@ static void _bridge_iter_object_reference_append(Eo *bridge, Eldbus_Message_Iter
 // utility functions
 static void _iter_interfaces_append(Eldbus_Message_Iter *iter, const Eo *obj);
 static Eina_Bool _elm_atspi_bridge_key_filter(void *data, void *loop, int type, void *event);
-static void _object_unregister(Eo *obj, void *data);
 static void _object_desktop_reference_append(Eldbus_Message_Iter *iter);
+static Eina_Bool _on_object_add(void *data, Eo *obj, const Eo_Event_Description *event EINA_UNUSED, void *event_info EINA_UNUSED);
 static Eina_Bool _on_object_del(void *data, Eo *obj, const Eo_Event_Description *event EINA_UNUSED, void *event_info EINA_UNUSED);
 
-EO_CALLBACKS_ARRAY_DEFINE(_events_cb,
-   { EO_EV_DEL, _on_object_del},
-   { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_PROPERTY_CHANGED, _property_changed_signal_send},
-   { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_CHILDREN_CHANGED, _children_changed_signal_send},
-   { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_STATE_CHANGED, _state_changed_signal_send}
-);
+typedef struct {
+     const Eo_Event_Description *desc;
+     const Eo_Event_Cb callback;
+} Elm_Atspi_Bridge_Event_Handler;
 
-EO_CALLBACKS_ARRAY_DEFINE(_window_cb,
+static const Elm_Atspi_Bridge_Event_Handler event_handlers[] = {
+   { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_CHILDREN_CHANGED, _children_changed_signal_send},
+   { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_PROPERTY_CHANGED, _property_changed_signal_send},
+   { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_STATE_CHANGED, _state_changed_signal_send},
+   { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_VISIBLE_DATA_CHANGED, _visible_data_changed_signal_send},
+   { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_ACTIVE_DESCENDANTS_CHANGED, _active_descendant_changed_signal_send},
+   { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_ADDED, _on_object_add},
+   { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_REMOVED, _on_object_del},
    { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_CREATED, _window_signal_send},
    { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_DESTROYED, _window_signal_send},
    { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_ACTIVATED, _window_signal_send},
    { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_DEACTIVATED, _window_signal_send},
    { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_MAXIMIZED, _window_signal_send},
    { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_MINIMIZED, _window_signal_send},
-   { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_RESTORED, _window_signal_send}
-);
-
-EO_CALLBACKS_ARRAY_DEFINE(_selection_cb,
-   { ELM_INTERFACE_ATSPI_SELECTION_EVENT_SELECTION_CHANGED, _selection_signal_send}
-);
-
-EO_CALLBACKS_ARRAY_DEFINE(_text_cb,
+   { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_RESTORED, _window_signal_send},
+   { ELM_INTERFACE_ATSPI_SELECTION_EVENT_SELECTION_CHANGED, _selection_signal_send},
    { ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_CARET_MOVED, _text_caret_moved_send },
    { ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_INSERTED, _text_text_inserted_send },
    { ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_REMOVED, _text_text_removed_send },
    { ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_SELECTION_CHANGED, _text_selection_changed_send }
-);
+};
 
 enum _Atspi_Object_Child_Event_Type
 {
@@ -659,6 +656,18 @@ _elm_atspi_state_hash_build(void)
    return ret;
 }
 
+static Eina_Hash*
+_elm_atspi_event_hash_build(void)
+{
+   Eina_Hash *ret = eina_hash_pointer_new(NULL);
+   unsigned int i = 0;
+
+   for (i = 0; i < SIZE(event_handlers); i++)
+     eina_hash_add(ret, &(event_handlers[i].desc), event_handlers[i].callback);
+
+   return ret;
+}
+
 static Eldbus_Message *
 _accessible_get_state(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
 {
@@ -2407,17 +2416,15 @@ _iter_interfaces_append(Eldbus_Message_Iter *iter, const Eo *obj)
 }
 
 static Eina_Bool
-_cache_item_reference_append_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata)
+_cache_item_reference_append_cb(Eo *bridge, Eo *data, Eldbus_Message_Iter *iter_array)
 {
   if (!eo_ref_get(data) || eo_destructed_is(data))
     return EINA_TRUE;
 
-  struct cache_closure *cl = fdata;
   Eldbus_Message_Iter *iter_struct, *iter_sub_array;
-  Eldbus_Message_Iter *iter_array = cl->iter;
   Elm_Atspi_State_Set states;
   Elm_Atspi_Role role;
-  Eo *root = elm_atspi_bridge_root_get(cl->bridge);
+  Eo *root = elm_atspi_bridge_root_get(bridge);
 
   eo_do(data, role = elm_interface_atspi_accessible_role_get());
 
@@ -2425,10 +2432,10 @@ _cache_item_reference_append_cb(const Eina_Hash *hash EINA_UNUSED, const void *k
   EINA_SAFETY_ON_NULL_RETURN_VAL(iter_struct, EINA_TRUE);
 
   /* Marshall object path */
-  _bridge_iter_object_reference_append(cl->bridge, iter_struct, data);
+  _bridge_iter_object_reference_append(bridge, iter_struct, data);
 
   /* Marshall application */
-  _bridge_iter_object_reference_append(cl->bridge, iter_struct, root);
+  _bridge_iter_object_reference_append(bridge, iter_struct, root);
 
   Eo *parent = NULL;
   eo_do(data, parent = elm_interface_atspi_accessible_parent_get());
@@ -2436,7 +2443,7 @@ _cache_item_reference_append_cb(const Eina_Hash *hash EINA_UNUSED, const void *k
   if ((!parent) && (ELM_ATSPI_ROLE_APPLICATION == role))
     _object_desktop_reference_append(iter_struct);
   else
-    _bridge_iter_object_reference_append(cl->bridge, iter_struct, parent);
+    _bridge_iter_object_reference_append(bridge, iter_struct, parent);
 
   /* Marshall children  */
   Eina_List *children_list = NULL, *l;
@@ -2447,7 +2454,7 @@ _cache_item_reference_append_cb(const Eina_Hash *hash EINA_UNUSED, const void *k
   EINA_SAFETY_ON_NULL_GOTO(iter_sub_array, fail);
 
   EINA_LIST_FOREACH(children_list, l, child)
-     _bridge_iter_object_reference_append(cl->bridge, iter_sub_array, child);
+     _bridge_iter_object_reference_append(bridge, iter_sub_array, child);
 
   eldbus_message_iter_container_close(iter_struct, iter_sub_array);
   eina_list_free(children_list);
@@ -2498,9 +2505,10 @@ fail:
 static Eldbus_Message *
 _cache_get_items(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
 {
-   Eldbus_Message_Iter *iter;
+   Eldbus_Message_Iter *iter, *iter_array;
    Eldbus_Message *ret;
-   struct cache_closure cl;
+   Eina_List *to_process;
+   Eo *root;
 
    Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
    if (!bridge) return NULL;
@@ -2511,13 +2519,25 @@ _cache_get_items(const Eldbus_Service_Interface *iface, const Eldbus_Message *ms
    EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
 
    iter = eldbus_message_iter_get(ret);
-   cl.iter = eldbus_message_iter_container_new(iter, 'a', CACHE_ITEM_SIGNATURE);
-   EINA_SAFETY_ON_NULL_GOTO(cl.iter, fail);
+   iter_array = eldbus_message_iter_container_new(iter, 'a', CACHE_ITEM_SIGNATURE);
+   EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
+
+   eo_do(bridge, root = elm_obj_atspi_bridge_root_get());
+   to_process = eina_list_append(NULL, root);
+
+   while (to_process)
+     {
+        Eo *obj = eina_list_data_get(to_process);
+        to_process = eina_list_remove_list(to_process, to_process);
+        _cache_item_reference_append_cb(bridge, obj, iter_array);
+        _bridge_object_register(bridge, obj);
 
-   cl.bridge = bridge;
+        Eina_List *children;
+        eo_do(obj, children = elm_interface_atspi_accessible_children_get());
+        to_process = eina_list_merge(to_process, children);
+     }
 
-   eina_hash_foreach(pd->cache, _cache_item_reference_append_cb, &cl);
-   eldbus_message_iter_container_close(iter, cl.iter);
+   eldbus_message_iter_container_close(iter, iter_array);
 
    return ret;
 fail:
@@ -2913,7 +2933,7 @@ _elm_atspi_bridge_app_unregister(Eo *bridge)
 static void
 _cache_register(Eo *obj)
 {
-   Elm_Atspi_Bridge_Data *pd = eo_data_scope_get(obj, ELM_ATSPI_BRIDGE_CLASS);
+   ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(obj, pd);
    pd->cache_interface = eldbus_service_interface_register(pd->a11y_bus, CACHE_INTERFACE_PATH, &cache_iface_desc);
    eldbus_service_object_data_set(pd->cache_interface, ELM_ATSPI_BRIDGE_CLASS_NAME, obj);
 }
@@ -2922,7 +2942,7 @@ static void
 _set_broadcast_flag(const char *event, Eo *bridge)
 {
    char **tokens;
-   Elm_Atspi_Bridge_Data *pd = eo_data_scope_get(bridge, ELM_ATSPI_BRIDGE_CLASS);
+   ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
 
    tokens = eina_str_split(event, ":", 3);
 
@@ -2974,6 +2994,10 @@ _set_broadcast_flag(const char *event, Eo *bridge)
           STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_SELECTION_CHANGED);
         else if (!strcmp(tokens[1], "TextAttributesChanged"))
           STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_ATTRIBUTES_CHANGED);
+        else if (!strcmp(tokens[1], "VisibleDataChanged"))
+          STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_VISIBLE_DATA_CHANGED);
+        else if (!strcmp(tokens[1], "ActiveDescendantsChanged"))
+          STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_ACTIVE_DESCENDANT_CHANGED);
      }
    else if (!strcmp(tokens[0], "Window"))
      {
@@ -3005,7 +3029,7 @@ static void
 _registered_listeners_get(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
 {
    const char *event, *bus;
-   Elm_Atspi_Bridge_Data *pd = eo_data_scope_get(data, ELM_ATSPI_BRIDGE_CLASS);
+   ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(data, pd);
    pd->pending_requests = eina_list_remove(pd->pending_requests, pending);
 
    DBG("Updating registered ATSPI signals list.");
@@ -3041,7 +3065,7 @@ static void
 _registered_events_list_update(Eo *bridge)
 {
    Eldbus_Message *msg;
-   Elm_Atspi_Bridge_Data *pd = eo_data_scope_get(bridge, ELM_ATSPI_BRIDGE_CLASS);
+   ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
    Eldbus_Pending *p;
 
    msg = eldbus_message_method_call_new(ATSPI_DBUS_NAME_REGISTRY, ATSPI_DBUS_PATH_REGISTRY, ATSPI_DBUS_INTERFACE_REGISTRY, "GetRegisteredEvents");
@@ -3127,6 +3151,40 @@ _property_changed_signal_send(void *data, Eo *obj EINA_UNUSED, const Eo_Event_De
 }
 
 static Eina_Bool
+_visible_data_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_FALSE);
+
+   if (!STATE_TYPE_GET(pd->object_children_broadcast_mask, ATSPI_OBJECT_EVENT_VISIBLE_DATA_CHANGED))
+     return EINA_FALSE;
+
+   _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
+                       &_event_obj_signals[ATSPI_OBJECT_EVENT_VISIBLE_DATA_CHANGED], "",
+                       0, 0, NULL, NULL);
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_active_descendant_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
+{
+   Eo *child = event_info;
+   int idx;
+
+   ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_FALSE);
+
+   if (!STATE_TYPE_GET(pd->object_children_broadcast_mask, ATSPI_OBJECT_EVENT_ACTIVE_DESCENDANT_CHANGED))
+     return EINA_FALSE;
+
+   eo_do(child, idx = elm_interface_atspi_accessible_index_in_parent_get());
+
+   _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
+                       &_event_obj_signals[ATSPI_OBJECT_EVENT_ACTIVE_DESCENDANT_CHANGED], "",
+                       idx, 0, "(so)", eldbus_connection_unique_name_get(pd->a11y_bus), child);
+   return EINA_TRUE;
+}
+
+static Eina_Bool
 _children_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
 {
    const char *atspi_desc = NULL;
@@ -3138,10 +3196,6 @@ _children_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *d
 
    type = ev_data->is_added ? ATSPI_OBJECT_CHILD_ADDED : ATSPI_OBJECT_CHILD_REMOVED;
 
-   // update cached objects
-   if (ev_data->is_added)
-     _bridge_cache_build(data, ev_data->child);
-
    if (!STATE_TYPE_GET(pd->object_children_broadcast_mask, type))
      return EINA_FALSE;
 
@@ -3366,7 +3420,7 @@ _text_selection_changed_send(void *data, Eo *obj, const Eo_Event_Description *de
 static void
 _event_handlers_register(Eo *bridge)
 {
-   Elm_Atspi_Bridge_Data *pd = eo_data_scope_get(bridge, ELM_ATSPI_BRIDGE_CLASS);
+   ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
 
    _registered_events_list_update(bridge);
 
@@ -3384,8 +3438,6 @@ _bridge_object_unregister(Eo *bridge, Eo *obj)
 
    ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
 
-   _object_unregister(obj, bridge);
-
    sig = eldbus_service_signal_new(pd->cache_interface, ATSPI_OBJECT_CHILD_REMOVED);
    Eldbus_Message_Iter *iter = eldbus_message_iter_get(sig);
    _bridge_iter_object_reference_append(bridge, iter, obj);
@@ -3395,36 +3447,20 @@ _bridge_object_unregister(Eo *bridge, Eo *obj)
 }
 
 static Eina_Bool
-_on_object_del(void *data, Eo *obj, const Eo_Event_Description *event EINA_UNUSED, void *event_info EINA_UNUSED)
+_on_object_add(void *data, Eo *obj, const Eo_Event_Description *event EINA_UNUSED, void *event_info EINA_UNUSED)
 {
    Eo *bridge = data;
-
-   _bridge_object_unregister(bridge, obj);
+   _bridge_object_register(bridge, obj);
 
    return EINA_TRUE;
 }
 
-static void
-_bridge_cache_build(Eo *bridge, void *obj)
+static Eina_Bool
+_on_object_del(void *data, Eo *obj, const Eo_Event_Description *event EINA_UNUSED, void *event_info EINA_UNUSED)
 {
-   Eina_List *children;
-   Eo *child;
-
-   ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
-
-   if (!eo_isa(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
-     return;
-
-   _bridge_object_register(bridge, obj);
-
-   eo_do(obj, children = elm_interface_atspi_accessible_children_get());
-   EINA_LIST_FREE(children, child)
-      _bridge_cache_build(bridge, child);
-}
+   Eo *bridge = data;
+   _bridge_object_unregister(bridge, obj);
 
-static Eina_Bool _unregister_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata)
-{
-   _object_unregister(data, fdata);
    return EINA_TRUE;
 }
 
@@ -3452,17 +3488,14 @@ _interfaces_unregister(Eo *bridge)
 static void
 _a11y_connection_shutdown(Eo *bridge)
 {
-   Elm_Atspi_Bridge_Data *pd = eo_data_scope_get(bridge, ELM_ATSPI_BRIDGE_CLASS);
+   ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
    Eldbus_Pending *pending;
 
    if (pd->connected)
       _elm_atspi_bridge_app_unregister(bridge);
 
    if (pd->cache)
-     {
-        eina_hash_foreach(pd->cache, _unregister_cb, bridge);
-        eina_hash_free(pd->cache);
-     }
+     eina_hash_free(pd->cache);
    pd->cache = NULL;
 
    if (pd->cache_interface)
@@ -3490,6 +3523,12 @@ _a11y_connection_shutdown(Eo *bridge)
    if (pd->state_hash) eina_hash_free(pd->state_hash);
    pd->state_hash = NULL;
 
+   if (pd->event_hash) eina_hash_free(pd->event_hash);
+   pd->event_hash = NULL;
+
+   eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_handler_del(pd->event_hdlr));
+   pd->event_hdlr = NULL;
+
    eo_do(bridge, eo_event_callback_call(ELM_ATSPI_BRIDGE_EVENT_DISCONNECTED, NULL));
    pd->connected = EINA_FALSE;
 }
@@ -3541,11 +3580,19 @@ _interfaces_register(Eo *bridge)
    eldbus_service_object_data_set(pd->interfaces.value, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge);
 }
 
+static Eina_Bool
+_bridge_accessible_event_dispatch(void *data, Eo *accessible, const Eo_Event_Description *desc, void *event_info)
+{
+   ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_TRUE);
+
+   Eo_Event_Cb cb = eina_hash_find(pd->event_hash, &desc);
+   return cb ? cb(data, accessible, desc, event_info) : EINA_TRUE;
+}
+
 static void
 _a11y_bus_initialize(Eo *obj, const char *socket_addr)
 {
-   Elm_Atspi_Bridge_Data *pd = eo_data_scope_get(obj, ELM_ATSPI_BRIDGE_CLASS);
-   Eo *root;
+   ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(obj, pd);
 
    pd->a11y_bus = eldbus_private_address_connection_get(socket_addr);
    if (!pd->a11y_bus)
@@ -3556,6 +3603,7 @@ _a11y_bus_initialize(Eo *obj, const char *socket_addr)
    // init data structures
    pd->cache = eina_hash_pointer_new(NULL);
    pd->state_hash = _elm_atspi_state_hash_build();
+   pd->event_hash = _elm_atspi_event_hash_build();
 
    // dbus init
    _cache_register(obj);
@@ -3563,16 +3611,15 @@ _a11y_bus_initialize(Eo *obj, const char *socket_addr)
    _event_handlers_register(obj);
    _elm_atspi_bridge_app_register(obj);
 
-   // buid cache
-   eo_do(obj, root = elm_obj_atspi_bridge_root_get());
-   _bridge_cache_build(obj, root);
+   // register accesible object event listener
+   eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, pd->event_hdlr = elm_interface_atspi_accessible_event_handler_add(_bridge_accessible_event_dispatch, obj));
 }
 
 static void
 _a11y_bus_address_get(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
 {
    const char *errname, *errmsg, *sock_addr = NULL;
-   Elm_Atspi_Bridge_Data *pd = eo_data_scope_get(data, ELM_ATSPI_BRIDGE_CLASS);
+   ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(data, pd);
 
    pd->pending_requests = eina_list_remove(pd->pending_requests, pending);
 
@@ -3593,7 +3640,7 @@ _a11y_bus_address_get(void *data, const Eldbus_Message *msg, Eldbus_Pending *pen
 
 static void _a11y_connection_init(Eo *bridge)
 {
-   Elm_Atspi_Bridge_Data *pd = eo_data_scope_get(bridge, ELM_ATSPI_BRIDGE_CLASS);
+   ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
    Eina_Bool is_connected;
 
    eo_do(bridge, is_connected = elm_obj_atspi_bridge_connected_get());
@@ -3610,7 +3657,7 @@ static void _a11y_connection_init(Eo *bridge)
 static void
 _screen_reader_enabled_get(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
 {
-   Elm_Atspi_Bridge_Data *pd = eo_data_scope_get(data, ELM_ATSPI_BRIDGE_CLASS);
+   ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(data, pd);
    const char *errname, *errmsg;
    Eina_Bool is_enabled;
    Eldbus_Message_Iter *variant;
@@ -3641,8 +3688,8 @@ _screen_reader_enabled_get(void *data, const Eldbus_Message *msg, Eldbus_Pending
 
 static void _bridge_object_register(Eo *bridge, Eo *obj)
 {
-   struct cache_closure cc;
    Eldbus_Message *sig;
+   Eldbus_Message_Iter *iter;
 
    ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
 
@@ -3660,36 +3707,13 @@ static void _bridge_object_register(Eo *bridge, Eo *obj)
 
    eina_hash_add(pd->cache, &obj, obj);
 
-   eo_do(obj, eo_event_callback_array_add(_events_cb(), bridge));
-
-   if (eo_isa(obj, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE))
-     eo_do(obj, eo_event_callback_array_add(_selection_cb(), bridge));
-
-   if (eo_isa(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE))
-     eo_do(obj, eo_event_callback_array_add(_text_cb(), bridge));
-
-   if (eo_isa(obj, ELM_INTERFACE_ATSPI_WINDOW_INTERFACE))
-     eo_do(obj, eo_event_callback_array_add(_window_cb(), bridge));
-
    sig = eldbus_service_signal_new(pd->cache_interface, ATSPI_OBJECT_CHILD_ADDED);
-   cc.iter = eldbus_message_iter_get(sig);
-   cc.bridge = bridge;
-   _cache_item_reference_append_cb(NULL, NULL, obj, &cc);
+   iter = eldbus_message_iter_get(sig);
+   _cache_item_reference_append_cb(bridge, obj, iter);
 
    eldbus_service_signal_send(pd->cache_interface, sig);
 }
 
-static void _object_unregister(Eo *obj, void *data)
-{
-   eo_do(obj, eo_event_callback_array_del(_events_cb(), data));
-   if (eo_isa(obj, ELM_INTERFACE_ATSPI_WINDOW_INTERFACE))
-     eo_do(obj, eo_event_callback_array_del(_window_cb(), data));
-   if (eo_isa(obj, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE))
-      eo_do(obj, eo_event_callback_array_del(_selection_cb(), data));
-   if (eo_isa(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE))
-      eo_do(obj, eo_event_callback_array_del(_text_cb(), data));
-}
-
 void
 _elm_atspi_bridge_init(void)
 {
@@ -3853,7 +3877,10 @@ EOLIAN Eo*
 _elm_atspi_bridge_root_get(Eo *obj EINA_UNUSED, Elm_Atspi_Bridge_Data *pd)
 {
    if (!pd->root)
-      pd->root = eo_add(ELM_ATSPI_APP_OBJECT_CLASS, NULL);
+     {
+        pd->root = eo_add(ELM_ATSPI_APP_OBJECT_CLASS, NULL);
+        elm_interface_atspi_accessible_added(pd->root);
+     }
 
    return pd->root;
 }
index 6243501..3f0ab0f 100644 (file)
@@ -2019,14 +2019,14 @@ _entry_changed_user_signal_cb(void *data,
              atspi_info.content = edje_info->change.insert.content;
              atspi_info.pos = edje_info->change.insert.pos;
              atspi_info.len = edje_info->change.insert.plain_length;
-             eo_do(data, eo_event_callback_call(ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_INSERTED, &atspi_info));
+             eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_emit(data, ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_INSERTED, &atspi_info));
           }
         else if (edje_info && !edje_info->insert)
           {
              atspi_info.content = edje_info->change.del.content;
              atspi_info.pos = MIN(edje_info->change.del.start, edje_info->change.del.end);
              atspi_info.len = MAX(edje_info->change.del.start, edje_info->change.del.end) - atspi_info.pos;
-             eo_do(data, eo_event_callback_call(ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_REMOVED, &atspi_info));
+             eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_emit(data, ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_REMOVED, &atspi_info));
           }
      }
 }
@@ -2118,7 +2118,7 @@ _entry_selection_changed_signal_cb(void *data,
    _selection_store(ELM_SEL_TYPE_PRIMARY, data);
    _update_selection_handler(data);
    if (_elm_config->atspi_mode)
-     eo_do(data, eo_event_callback_call(ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_SELECTION_CHANGED, NULL));
+     eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_emit(data, ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_SELECTION_CHANGED, NULL));
 }
 
 static void
@@ -2215,7 +2215,7 @@ _entry_cursor_changed_signal_cb(void *data,
      edje_object_signal_emit(sd->entry_edje, "elm,action,show,cursor", "elm");
    _cursor_geometry_recalc(data);
    if (_elm_config->atspi_mode)
-     eo_do(data, eo_event_callback_call(ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_CARET_MOVED, NULL));
+     eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_emit(data, ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_CARET_MOVED, NULL));
 }
 
 static void
@@ -2227,7 +2227,7 @@ _entry_cursor_changed_manual_signal_cb(void *data,
    eo_do(data, eo_event_callback_call
      (ELM_ENTRY_EVENT_CURSOR_CHANGED_MANUAL, NULL));
    if (_elm_config->atspi_mode)
-     eo_do(data, eo_event_callback_call(ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_CARET_MOVED, NULL));
+     eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_emit(data, ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_CARET_MOVED, NULL));
 }
 
 static void
index a0d5cd7..d76352f 100644 (file)
@@ -4633,6 +4633,12 @@ _item_queue(Elm_Genlist_Data *sd,
 //   evas_event_thaw_eval(evas_object_evas_get(sd->obj));
    evas_object_geometry_get(sd->obj, NULL, NULL, &w, NULL);
    if (w > 0) _requeue_idle_enterer(sd);
+
+   if (_elm_config->atspi_mode)
+     {
+        elm_interface_atspi_accessible_added(EO_OBJ(it));
+        elm_interface_atspi_accessible_children_changed_added_signal_emit(sd->obj, EO_OBJ(it));
+     }
 }
 
 /* If the application wants to know the relative item, use
@@ -6117,9 +6123,6 @@ _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);
 }
 
@@ -6167,9 +6170,6 @@ _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);
 }
 
@@ -6217,9 +6217,6 @@ _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);
 }
 
@@ -6267,9 +6264,6 @@ _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);
 }
 
@@ -6373,9 +6367,6 @@ _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;
 }
 
index 36e0cc0..3524008 100644 (file)
@@ -115,6 +115,13 @@ const char* Atspi_Name[] = {
     "last defined"
 };
 
+struct _Elm_Atspi_Event_Handler
+{
+   Eo_Event_Cb cb;
+   void *data;
+};
+
+static Eina_List *global_callbacks;
 
 EOLIAN static int
 _elm_interface_atspi_accessible_index_in_parent_get(Eo *obj, void *pd EINA_UNUSED)
@@ -281,4 +288,52 @@ EAPI void elm_atspi_attributes_list_free(Eina_List *list)
      }
 }
 
+EOLIAN void
+_elm_interface_atspi_accessible_event_emit(Eo *class EINA_UNUSED, void *pd EINA_UNUSED, Eo *accessible, const Eo_Event_Description *event, void *event_info)
+{
+   Eina_List *l;
+   Elm_Atspi_Event_Handler *hdl;
+
+   if (!accessible || !event || !eo_isa(accessible, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
+     {
+        CRI("Invalid accessibility event emit parameters");
+        return;
+     }
+
+   EINA_LIST_FOREACH(global_callbacks, l, hdl)
+     {
+        if (hdl->cb)
+          hdl->cb(hdl->data, accessible, event, event_info);
+     }
+}
+
+EOLIAN Elm_Atspi_Event_Handler *
+_elm_interface_atspi_accessible_event_handler_add(Eo *class EINA_UNUSED, void *pd EINA_UNUSED, Eo_Event_Cb cb, void *data)
+{
+   Elm_Atspi_Event_Handler *ret = calloc(sizeof(Elm_Atspi_Event_Handler), 1);
+
+   ret->cb = cb;
+   ret->data = data;
+
+   global_callbacks = eina_list_append(global_callbacks, ret);
+
+   return ret;
+}
+
+EOLIAN void 
+_elm_interface_atspi_accessible_event_handler_del(Eo *class EINA_UNUSED, void *pd EINA_UNUSED, Elm_Atspi_Event_Handler *handler)
+{
+   Eina_List *l, *l2;
+   Elm_Atspi_Event_Handler *hdl;
+   EINA_LIST_FOREACH_SAFE(global_callbacks, l, l2, hdl)
+     {
+        if (hdl == handler)
+          {
+             global_callbacks = eina_list_remove_list(global_callbacks, l);
+             free(hdl);
+             break;
+          }
+     }
+}
+
 #include "elm_interface_atspi_accessible.eo.c"
index 0110e50..3672b02 100644 (file)
@@ -102,6 +102,27 @@ mixin Elm_Interface_Atspi_Accessible ()
             states: Elm_Atspi_State_Set;
          }
       }
+      event_handler_add @class @protected {
+         [[Register accessibility event listener]]
+         params {
+              @in cb: Eo_Event_Cb; [[callback]]
+              @in data: void*; [[data]]
+         }
+         return: Elm_Atspi_Event_Handler*; [[Event handler]]
+      }
+      event_handler_del @class @protected {
+         [[Deregister accessibility event listener]]
+         params {
+              @in handler: Elm_Atspi_Event_Handler *; [[Event handler]]
+         }
+      }
+      event_emit @class @protected {
+         params {
+            @in accessible: Eo*; [[Accessibility object.]]
+            @in event: const(Eo_Event_Description)*; [[Accessibility event type.]]
+            @in event_info: void*; [[Accessibility event details.]]
+         }
+      }
    }
    events {
       property,changed: const(char)*;
@@ -109,5 +130,7 @@ mixin Elm_Interface_Atspi_Accessible ()
       state,changed: Elm_Atspi_Event_State_Changed_Data;
       visible,data,changed;
       active,descendants,changed;
+      added;
+      removed;
    }
 }
index 7ce9d80..9b147c9 100644 (file)
@@ -3,6 +3,12 @@
 
 #ifdef EFL_BETA_API_SUPPORT
 
+
+/**
+ * ATSPI event listener
+ */
+typedef struct _Elm_Atspi_Event_Handler Elm_Atspi_Event_Handler;
+
 /**
  * ATSPI object state set.
  */
@@ -266,38 +272,38 @@ EAPI void elm_atspi_attributes_list_free(Eina_List *list);
       Elm_Atspi_Event_State_Changed_Data evinfo; \
       evinfo.type = (tp); \
       evinfo.new_value = (nvl); \
-      eo_do(obj, eo_event_callback_call(ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_STATE_CHANGED, (void*)&evinfo)); \
+      eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_emit(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_STATE_CHANGED, (void*)&evinfo)); \
    } while(0); }
 
 /**
  * Emits ATSPI 'PropertyChanged' dbus signal for 'Name' property.
  */
 #define elm_interface_atspi_accessible_name_changed_signal_emit(obj) \
-   eo_do(obj, eo_event_callback_call(ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_PROPERTY_CHANGED, "name"));
+   eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_emit(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_PROPERTY_CHANGED, "name"));
 
 /**
  * Emits ATSPI 'PropertyChanged' dbus signal for 'Description' property.
  */
 #define elm_interface_atspi_accessible_description_changed_signal_emit(obj) \
-   eo_do(obj, eo_event_callback_call(ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_PROPERTY_CHANGED, "description"));
+   eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_emit(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_PROPERTY_CHANGED, "description"));
 
 /**
  * Emits ATSPI 'PropertyChanged' dbus signal for 'Parent' property.
  */
 #define elm_interface_atspi_accessible_parent_changed_signal_emit(obj) \
-   eo_do(obj, eo_event_callback_call(ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_PROPERTY_CHANGED, "parent"));
+   eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_emit(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_PROPERTY_CHANGED, "parent"));
 
 /**
  * Emits ATSPI 'PropertyChanged' dbus signal for 'Role' property.
  */
 #define elm_interface_atspi_accessible_role_changed_signal_emit(obj) \
-   eo_do(obj, eo_event_callback_call(ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_PROPERTY_CHANGED, "role"));
+   eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_emit(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_PROPERTY_CHANGED, "role"));
 
 /**
  * Emits ATSPI 'PropertyChanged' dbus signal for 'Value' property.
  */
 #define elm_interface_atspi_accessible_value_changed_signal_emit(obj) \
-   eo_do(obj, eo_event_callback_call(ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_PROPERTY_CHANGED, "value"));
+   eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_emit(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_PROPERTY_CHANGED, "value"));
 
 /**
  * Emits ATSPI 'ChildrenChanged' dbus signal with added child as argument.
@@ -305,7 +311,7 @@ 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 atspi_data = { EINA_TRUE, child }; \
-      eo_do(obj, eo_event_callback_call(ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_CHILDREN_CHANGED, &atspi_data)); \
+   eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_emit(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_CHILDREN_CHANGED, &atspi_data)); \
    } while(0);
 
 /**
@@ -314,14 +320,32 @@ 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 atspi_data = { EINA_FALSE, child }; \
-      eo_do(obj, eo_event_callback_call(ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_CHILDREN_CHANGED, &atspi_data)); \
+      eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_emit(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_CHILDREN_CHANGED, &atspi_data)); \
    } while(0);
 
 /**
- * Emits ATSPI 'ActiveDescendantsChanged' dbus signal with deleted child as argument.
+ * Emits ATSPI 'ActiveDescendantsChanged' dbus signal.
+ */
+#define elm_interface_atspi_accessible_active_descendants_changed_signal_emit(obj, child) \
+   eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_emit(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_ACTIVE_DESCENDANT_CHANGED, child));
+
+/**
+ * Emits ATSPI 'VisibleDataChanged' dbus signal.
+ */
+#define elm_interface_atspi_accessible_visible_data_changed_signal_emit(obj) \
+   eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_emit(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_VISIBLE_DATA_CHANGED, NULL));
+
+/**
+ * Emits ATSPI 'AddAccessible' dbus signal.
+ */
+#define elm_interface_atspi_accessible_added(obj) \
+   eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_emit(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_ADDED, NULL));
+
+/**
+ * Emits ATSPI 'RemoveAccessible' dbus signal.
  */
-#define elm_interface_atspi_accessible_active_descendants_changed_signal_emit(obj, desc) \
-   eo_do(obj, eo_event_callback_call(ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_ACTIVE_DESCENDANT_CHANGED, desc));
+#define elm_interface_atspi_accessible_removed(obj) \
+   eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_emit(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_REMOVED, NULL));
 
 #include "elm_interface_atspi_accessible.eo.h"
 #endif
diff --git a/legacy/elementary/src/lib/elm_interface_atspi_window.h b/legacy/elementary/src/lib/elm_interface_atspi_window.h
new file mode 100644 (file)
index 0000000..0b148b3
--- /dev/null
@@ -0,0 +1,56 @@
+#ifndef ELM_INTERFACE_ATSPI_WINDOW_H
+#define ELM_INTERFACE_ATSPI_WINDOW_H
+
+#ifdef EFL_BETA_API_SUPPORT
+#ifdef EFL_EO_API_SUPPORT
+
+/**
+ * Emits ATSPI 'Window:Activated' dbus signal.
+ */
+#define elm_interface_atspi_window_activated_signal_emit(obj) \
+   eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_emit(obj, ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_ACTIVATED, NULL));
+
+/**
+ * Emits ATSPI 'Window:Deactivated' dbus signal.
+ */
+#define elm_interface_atspi_window_deactivated_signal_emit(obj) \
+   eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_emit(obj, ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_DEACTIVATED, NULL));
+
+/**
+ * Emits ATSPI 'Window:Created' dbus signal.
+ */
+#define elm_interface_atspi_window_created_signal_emit(obj) \
+   eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_emit(obj, ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_CREATED, NULL));
+
+/**
+ * Emits ATSPI 'Window:Destroyed' dbus signal.
+ */
+#define elm_interface_atspi_window_destroyed_signal_emit(obj) \
+   eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_emit(obj, ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_DESTROYED, NULL));
+
+/**
+ * Emits ATSPI 'Window:Maximized' dbus signal.
+ */
+#define elm_interface_atspi_window_maximized_signal_emit(obj) \
+   eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_emit(obj, ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_MAXIMIZED, NULL));
+
+/**
+ * Emits ATSPI 'Window:Minimized' dbus signal.
+ */
+#define elm_interface_atspi_window_minimized_signal_emit(obj) \
+   eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_emit(obj, ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_MINIMIZED, NULL));
+
+/**
+ * Emits ATSPI 'Window:Restored' dbus signal.
+ */
+#define elm_interface_atspi_window_restored_signal_emit(obj) \
+   eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_emit(obj, ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_RESTORED, NULL));
+
+#include "elm_interface_atspi_window.eo.h"
+#endif
+#ifndef EFL_NOLEGACY_API_SUPPORT
+#include "elm_interface_atspi_window.eo.legacy.h"
+#endif
+
+#endif
+#endif
index 61a359e..78e262f 100644 (file)
@@ -1,6 +1,7 @@
 #include "elm_interface_atspi_accessible.h"
 #include "elm_interface_atspi_text.h"
 #include "elm_interface_atspi_widget_action.h"
+#include "elm_interface_atspi_window.h"
 
 #ifdef EFL_EO_API_SUPPORT
 #include "elm_interface_scrollable.h"
@@ -11,7 +12,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_window.eo.h"
 #endif
 #endif
 #ifndef EFL_NOLEGACY_API_SUPPORT
@@ -22,6 +22,5 @@
 #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_window.eo.legacy.h"
 #endif
 #endif
index 5a1f6fa..6bc1ccb 100644 (file)
@@ -529,15 +529,6 @@ _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);
-        if (_elm_widget_onscreen_is(obj))
-           elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_SHOWING, EINA_TRUE);
-     }
-
    it = evas_object_smart_iterator_new(obj);
    EINA_ITERATOR_FOREACH(it, o)
      {
@@ -545,6 +536,16 @@ _elm_widget_evas_object_smart_show(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUS
        evas_object_show(o);
      }
    eina_iterator_free(it);
+
+   if (_elm_config->atspi_mode)
+     {
+        elm_interface_atspi_accessible_added(obj);
+        Eo *parent;
+        eo_do(obj, parent = elm_interface_atspi_accessible_parent_get());
+        if (parent) elm_interface_atspi_accessible_children_changed_added_signal_emit(parent, obj);
+        if (_elm_widget_onscreen_is(obj))
+           elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_SHOWING, EINA_TRUE);
+     }
 }
 
 EOLIAN static void
@@ -562,7 +563,12 @@ _elm_widget_evas_object_smart_hide(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUS
    eina_iterator_free(it);
 
    if (_elm_config->atspi_mode)
-     elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_SHOWING, EINA_FALSE);
+     {
+        Eo *parent;
+        eo_do(obj, parent = elm_interface_atspi_accessible_parent_get());
+        if (parent) elm_interface_atspi_accessible_children_changed_del_signal_emit(parent, obj);
+        elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_SHOWING, EINA_FALSE);
+     }
 }
 
 EOLIAN static void
@@ -1282,8 +1288,6 @@ _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;
@@ -4431,7 +4435,9 @@ _elm_widget_item_eo_base_destructor(Eo *eo_item, Elm_Widget_Item_Data *item)
      eina_stringshare_del(item->description);
 
    if (_elm_config->atspi_mode)
-        elm_interface_atspi_accessible_children_changed_del_signal_emit(item->widget, eo_item);
+     elm_interface_atspi_accessible_children_changed_del_signal_emit(item->widget, eo_item);
+
+   elm_interface_atspi_accessible_removed(eo_item);
 
    EINA_MAGIC_SET(item, EINA_MAGIC_NONE);
 
@@ -5721,19 +5727,15 @@ _elm_widget_eo_base_constructor(Eo *obj, Elm_Widget_Smart_Data *sd)
    sd->on_create = EINA_FALSE;
 
    sd->role = ELM_ATSPI_ROLE_UNKNOWN;
-
    return obj;
 }
 
 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);
+   elm_interface_atspi_accessible_removed(obj);
 
    eo_do_super(obj, ELM_WIDGET_CLASS, eo_destructor());
 }
index d0bfb9a..65388e3 100644 (file)
@@ -1113,7 +1113,7 @@ _elm_win_focus_in(Ecore_Evas *ee)
 
    if (_elm_config->atspi_mode)
      {
-        eo_do(obj, eo_event_callback_call(ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_ACTIVATED, NULL));
+        elm_interface_atspi_window_activated_signal_emit(obj);
         elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_ACTIVE, EINA_TRUE);
      }
 
@@ -1151,7 +1151,7 @@ _elm_win_focus_out(Ecore_Evas *ee)
 
    if (_elm_config->atspi_mode)
      {
-        eo_do(obj, eo_event_callback_call(ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_DEACTIVATED, NULL));
+        elm_interface_atspi_window_deactivated_signal_emit(obj);
         elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_ACTIVE, EINA_FALSE);
      }
 
@@ -1358,15 +1358,13 @@ _elm_win_state_change(Ecore_Evas *ee)
           {
              eo_do(obj, eo_event_callback_call(ELM_WIN_EVENT_ICONIFIED, NULL));
              if (_elm_config->atspi_mode)
-               eo_do(obj, eo_event_callback_call
-                 (ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_MINIMIZED, NULL));
+               elm_interface_atspi_window_minimized_signal_emit(obj);
           }
         else
           {
              eo_do(obj, eo_event_callback_call(ELM_WIN_EVENT_NORMAL, NULL));
              if (_elm_config->atspi_mode)
-               eo_do(obj, eo_event_callback_call
-                 (ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_RESTORED, NULL));
+               elm_interface_atspi_window_restored_signal_emit(obj);
           }
      }
    if (ch_sticky)
@@ -1404,15 +1402,13 @@ _elm_win_state_change(Ecore_Evas *ee)
           {
              eo_do(obj, eo_event_callback_call(ELM_WIN_EVENT_MAXIMIZED, NULL));
              if (_elm_config->atspi_mode)
-               eo_do(obj, eo_event_callback_call
-                 (ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_MAXIMIZED, NULL));
+               elm_interface_atspi_window_maximized_signal_emit(obj);
           }
         else
           {
              eo_do(obj, eo_event_callback_call(ELM_WIN_EVENT_UNMAXIMIZED, NULL));
              if (_elm_config->atspi_mode)
-               eo_do(obj, eo_event_callback_call
-                 (ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_RESTORED, NULL));
+               elm_interface_atspi_window_restored_signal_emit(obj);
           }
      }
    if (ch_profile)
@@ -1620,7 +1616,7 @@ _elm_win_evas_object_smart_hide(Eo *obj, Elm_Win_Data *sd)
 #endif
      }
    if (_elm_config->atspi_mode)
-     eo_do(obj, eo_event_callback_call(ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_DESTROYED, NULL));
+     elm_interface_atspi_window_deactivated_signal_emit(obj);
 
    if (_elm_win_policy_quit_triggered(obj))
      _elm_win_flush_cache_and_exit(obj);
@@ -1894,6 +1890,9 @@ _elm_win_evas_object_smart_del(Eo *obj, Elm_Win_Data *sd)
 
    if (sd->autodel_clear) *(sd->autodel_clear) = -1;
 
+   if (_elm_config->atspi_mode)
+     elm_interface_atspi_window_destroyed_signal_emit(obj);
+
    _elm_win_list = eina_list_remove(_elm_win_list, obj);
    _elm_win_count--;
    _elm_win_state_eval_queue();
@@ -1958,9 +1957,6 @@ _elm_win_evas_object_smart_del(Eo *obj, Elm_Win_Data *sd)
      {
         _elm_win_flush_cache_and_exit(obj);
      }
-
-   if (_elm_config->atspi_mode)
-     eo_do(obj, eo_event_callback_call(ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_DESTROYED, NULL));
 }
 
 static void
@@ -2079,7 +2075,7 @@ _elm_win_delete_request(Ecore_Evas *ee)
      evas_object_hide(obj);
    // FIXME: if above callback deletes - then the below will be invalid
    if (_elm_config->atspi_mode)
-     eo_do(obj, eo_event_callback_call(ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_DESTROYED, NULL));
+     elm_interface_atspi_window_destroyed_signal_emit(obj);
    if (autodel) evas_object_del(obj);
    else sd->autodel_clear = NULL;
    evas_object_unref(obj);
@@ -3869,7 +3865,7 @@ _elm_win_finalize_internal(Eo *obj, Elm_Win_Data *sd, const char *name, Elm_Win_
 
    eo_do(obj, elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_WINDOW));
    if (_elm_config->atspi_mode == ELM_ATSPI_MODE_ON)
-     eo_do(obj, eo_event_callback_call(ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_CREATED, NULL));
+     elm_interface_atspi_window_created_signal_emit(obj);
 
    evas_object_show(sd->edje);
 
@@ -5553,11 +5549,13 @@ _on_atspi_bus_connected(void *data EINA_UNUSED, Eo *obj EINA_UNUSED, const Eo_Ev
          * recieve all org.a11y.window events and could keep track of active
          * windows whithin system.
          */
-        eo_do(win, eo_event_callback_call(ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_CREATED, NULL));
+        elm_interface_atspi_window_created_signal_emit(win);
         if (elm_win_focus_get(win))
-           eo_do(win, eo_event_callback_call(ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_ACTIVATED, NULL));
+          {
+             elm_interface_atspi_window_activated_signal_emit(win);
+          }
         else
-           eo_do(win, eo_event_callback_call(ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_DEACTIVATED, NULL));
+          elm_interface_atspi_window_deactivated_signal_emit(win);
      }
    return EINA_TRUE;
 }
index ade75c8..1dc64a2 100644 (file)
@@ -80,8 +80,11 @@ 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)
+                     const Eo_Event_Description *desc, void *event_info EINA_UNUSED)
 {
+   if (desc != ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_CHILDREN_CHANGED)
+     return EINA_TRUE;
+
    ev_data = *(Elm_Atspi_Event_Children_Changed_Data*)event_info;
    current = obj;
    counter++;
@@ -98,7 +101,7 @@ START_TEST(elm_atspi_children_events_add)
 
    Elm_Object_Item *it[3];
 
-   eo_do(genlist, eo_event_callback_add(ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_CHILDREN_CHANGED, _children_changed_cb, NULL));
+   eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_handler_add(_children_changed_cb, NULL));
 
    it[0] = elm_genlist_item_append(genlist, &itc, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
    ck_assert(genlist == current);
@@ -135,7 +138,7 @@ START_TEST(elm_atspi_children_events_del1)
    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));
+   eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_handler_add(_children_changed_cb, NULL));
 
    elm_object_item_del(it[0]);
    ck_assert(genlist == current);
@@ -163,7 +166,7 @@ START_TEST(elm_atspi_children_events_del2)
 
    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));
+   eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_handler_add(_children_changed_cb, NULL));
    elm_genlist_clear(genlist);
 
    ck_assert(genlist == current);