From a109bf0a016ba5f575a1eb18eae604f2df29eff5 Mon Sep 17 00:00:00 2001 From: Lukasz Stanislawski Date: Thu, 3 Sep 2015 14:07:23 +0200 Subject: [PATCH] atspi: add global event emitter Introduce global event emitter for accessibility events. With such emitter there is no need to register array of callbacks on every accessibility object. --- src/lib/Makefile.am | 1 + src/lib/elm_atspi_bridge.c | 249 +++++++++++++++++------------- src/lib/elm_entry.c | 10 +- src/lib/elm_genlist.c | 21 +-- src/lib/elm_interface_atspi_accessible.c | 55 +++++++ src/lib/elm_interface_atspi_accessible.eo | 23 +++ src/lib/elm_interface_atspi_accessible.h | 46 ++++-- src/lib/elm_interface_atspi_window.h | 56 +++++++ src/lib/elm_interfaces.h | 3 +- src/lib/elm_widget.c | 38 ++--- src/lib/elm_win.c | 36 ++--- src/tests/elm_test_genlist.c | 11 +- 12 files changed, 364 insertions(+), 185 deletions(-) create mode 100644 src/lib/elm_interface_atspi_window.h diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 0922587..3b61532 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -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 \ diff --git a/src/lib/elm_atspi_bridge.c b/src/lib/elm_atspi_bridge.c index 5df0085..345ab6b 100644 --- a/src/lib/elm_atspi_bridge.c +++ b/src/lib/elm_atspi_bridge.c @@ -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; } diff --git a/src/lib/elm_entry.c b/src/lib/elm_entry.c index 6243501..3f0ab0f 100644 --- a/src/lib/elm_entry.c +++ b/src/lib/elm_entry.c @@ -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 diff --git a/src/lib/elm_genlist.c b/src/lib/elm_genlist.c index a0d5cd7..d76352f 100644 --- a/src/lib/elm_genlist.c +++ b/src/lib/elm_genlist.c @@ -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; } diff --git a/src/lib/elm_interface_atspi_accessible.c b/src/lib/elm_interface_atspi_accessible.c index 36e0cc0..3524008 100644 --- a/src/lib/elm_interface_atspi_accessible.c +++ b/src/lib/elm_interface_atspi_accessible.c @@ -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" diff --git a/src/lib/elm_interface_atspi_accessible.eo b/src/lib/elm_interface_atspi_accessible.eo index 0110e50..3672b02 100644 --- a/src/lib/elm_interface_atspi_accessible.eo +++ b/src/lib/elm_interface_atspi_accessible.eo @@ -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; } } diff --git a/src/lib/elm_interface_atspi_accessible.h b/src/lib/elm_interface_atspi_accessible.h index 7ce9d80..9b147c9 100644 --- a/src/lib/elm_interface_atspi_accessible.h +++ b/src/lib/elm_interface_atspi_accessible.h @@ -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/src/lib/elm_interface_atspi_window.h b/src/lib/elm_interface_atspi_window.h new file mode 100644 index 0000000..0b148b3 --- /dev/null +++ b/src/lib/elm_interface_atspi_window.h @@ -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 diff --git a/src/lib/elm_interfaces.h b/src/lib/elm_interfaces.h index 61a359e..78e262f 100644 --- a/src/lib/elm_interfaces.h +++ b/src/lib/elm_interfaces.h @@ -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 diff --git a/src/lib/elm_widget.c b/src/lib/elm_widget.c index 5a1f6fa..6bc1ccb 100644 --- a/src/lib/elm_widget.c +++ b/src/lib/elm_widget.c @@ -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()); } diff --git a/src/lib/elm_win.c b/src/lib/elm_win.c index d0bfb9a..65388e3 100644 --- a/src/lib/elm_win.c +++ b/src/lib/elm_win.c @@ -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; } diff --git a/src/tests/elm_test_genlist.c b/src/tests/elm_test_genlist.c index ade75c8..1dc64a2 100644 --- a/src/tests/elm_test_genlist.c +++ b/src/tests/elm_test_genlist.c @@ -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); -- 2.7.4