From 0dc0ad891a33572bc2c056c425a3ae6566c26050 Mon Sep 17 00:00:00 2001 From: Lukasz Stanislawski Date: Mon, 29 Jun 2015 16:30:34 +0200 Subject: [PATCH] atspi: fix missing Window signals on AT-SPI2 initialization Patch adds connected/disconnected elm_atspi_bridge events to avoid races between window getting focus and AT-SPI2 bus initialization. When bridge gets connected windows will reemit all "Created", "Activated" and "Deactivated" events with regard to window focus. --- src/lib/elm_atspi_bridge.c | 45 +++++++++++++-------------------------------- src/lib/elm_atspi_bridge.eo | 4 ++++ src/lib/elm_win.c | 43 +++++++++++++++++++++++++++++++++++++------ 3 files changed, 54 insertions(+), 38 deletions(-) diff --git a/src/lib/elm_atspi_bridge.c b/src/lib/elm_atspi_bridge.c index 9a5c9cb..289f3af 100644 --- a/src/lib/elm_atspi_bridge.c +++ b/src/lib/elm_atspi_bridge.c @@ -2997,6 +2997,10 @@ _registered_listeners_get(void *data, const Eldbus_Message *msg, Eldbus_Pending eldbus_message_iter_arguments_get(siter, "ss", &bus, &event); _set_broadcast_flag(event, data); } + + if (!pd->connected) + eo_do(data, eo_event_callback_call(ELM_ATSPI_BRIDGE_EVENT_CONNECTED, NULL)); + pd->connected = EINA_TRUE; } static void @@ -3145,46 +3149,24 @@ static Eina_Bool _window_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info EINA_UNUSED) { enum _Atspi_Window_Signals type; - const char *name; ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_FALSE); ELM_ATSPI_OBJECT_INTERFACE_GET_OR_RETURN_VAL(obj, eo_class_name_get(ELM_INTERFACE_ATSPI_WINDOW_INTERFACE), ifc, EINA_FALSE); if (desc == ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_CREATED) - { - type = ATSPI_WINDOW_EVENT_CREATE; - name = "Create"; - } + type = ATSPI_WINDOW_EVENT_CREATE; else if (desc == ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_DESTROYED) - { - type = ATSPI_WINDOW_EVENT_DESTROY; - name = "Destroy"; - } + type = ATSPI_WINDOW_EVENT_DESTROY; else if (desc == ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_DEACTIVATED) - { - type = ATSPI_WINDOW_EVENT_DEACTIVATE; - name = "Deactivate"; - } + type = ATSPI_WINDOW_EVENT_DEACTIVATE; else if (desc == ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_ACTIVATED) - { - type = ATSPI_WINDOW_EVENT_ACTIVATE; - name = "Activate"; - } + type = ATSPI_WINDOW_EVENT_ACTIVATE; else if (desc == ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_MAXIMIZED) - { - type = ATSPI_WINDOW_EVENT_MAXIMIZE; - name = "Maximize"; - } + type = ATSPI_WINDOW_EVENT_MAXIMIZE; else if (desc == ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_MINIMIZED) - { - type = ATSPI_WINDOW_EVENT_MINIMIZE; - name = "Minimize"; - } + type = ATSPI_WINDOW_EVENT_MINIMIZE; else if (desc == ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_RESTORED) - { - type = ATSPI_WINDOW_EVENT_RESTORE; - name = "Restore"; - } + type = ATSPI_WINDOW_EVENT_RESTORE; else return EINA_FALSE; @@ -3197,7 +3179,7 @@ _window_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc, void return EINA_FALSE; } - _bridge_signal_send(data, ifc, type, name, 0, 0, "i", 0); + _bridge_signal_send(data, ifc, type, "", 0, 0, "i", 0); return EINA_TRUE; } @@ -3461,6 +3443,7 @@ _a11y_connection_shutdown(Eo *bridge) if (pd->a11y_bus) eldbus_connection_unref(pd->a11y_bus); pd->a11y_bus = NULL; + eo_do(bridge, eo_event_callback_call(ELM_ATSPI_BRIDGE_EVENT_DISCONNECTED, NULL)); pd->connected = EINA_FALSE; } @@ -3492,8 +3475,6 @@ _a11y_bus_initialize(Eo *obj, const char *socket_addr) // buid cache eo_do(obj, root = elm_obj_atspi_bridge_root_get()); _bridge_cache_build(obj, root); - - pd->connected = EINA_TRUE; } static void diff --git a/src/lib/elm_atspi_bridge.eo b/src/lib/elm_atspi_bridge.eo index fc1471a..eafd9f4 100644 --- a/src/lib/elm_atspi_bridge.eo +++ b/src/lib/elm_atspi_bridge.eo @@ -23,4 +23,8 @@ class Elm.Atspi_Bridge (Eo.Base) Eo.Base.constructor; Eo.Base.destructor; } + events { + connected; + disconnected; + } } diff --git a/src/lib/elm_win.c b/src/lib/elm_win.c index ff2021e..e41113a 100644 --- a/src/lib/elm_win.c +++ b/src/lib/elm_win.c @@ -1507,9 +1507,6 @@ _elm_win_evas_object_smart_show(Eo *obj, Elm_Win_Data *sd) TRAP(sd, show); if (sd->shot.info) _shot_handle(sd); - - if (_elm_config->atspi_mode) - eo_do(obj, eo_event_callback_call(ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_CREATED, NULL)); } EOLIAN static void @@ -1878,6 +1875,9 @@ _elm_win_evas_object_smart_del(Eo *obj, Elm_Win_Data *sd) evas_font_cache_flush(evas_object_evas_get(obj)); elm_exit(); } + + if (_elm_config->atspi_mode) + eo_do(obj, eo_event_callback_call(ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_DESTROYED, NULL)); } static void @@ -2796,8 +2796,6 @@ _elm_win_frame_cb_close(void *data, evas_object_ref(win); evas_object_smart_callback_call(win, SIG_DELETE_REQUEST, NULL); // 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)); if (autodel) evas_object_del(win); else sd->autodel_clear = NULL; evas_object_unref(win); @@ -3761,7 +3759,10 @@ _elm_win_finalize_internal(Eo *obj, Elm_Win_Data *sd, const char *name, Elm_Win_ { Eo *bridge = _elm_atspi_bridge_get(); if (bridge) - elm_interface_atspi_accessible_children_changed_added_signal_emit(elm_atspi_bridge_root_get(bridge), obj); + { + elm_interface_atspi_accessible_children_changed_added_signal_emit(elm_atspi_bridge_root_get(bridge), obj); + } + eo_do(obj, eo_event_callback_call(ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_CREATED, NULL)); } evas_object_show(sd->edje); @@ -5411,10 +5412,40 @@ elm_win_window_id_get(const Evas_Object *obj) return ret; } +static Eina_Bool +_on_atspi_bus_connected(void *data EINA_UNUSED, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Evas_Object *win; + Eina_List *l; + + EINA_LIST_FOREACH(_elm_win_list, l, win) + { + /** + * Reemit accessibility events when AT-SPI2 connection is begin + * established. This assures that Assistive Technology clients will + * 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)); + if (elm_win_focus_get(win)) + eo_do(win, eo_event_callback_call(ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_ACTIVATED, NULL)); + else + eo_do(win, eo_event_callback_call(ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_DEACTIVATED, NULL)); + } + return EINA_TRUE; +} + EOLIAN static void _elm_win_class_constructor(Eo_Class *klass) { evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass); + + if (_elm_config->atspi_mode) + { + Eo *bridge = _elm_atspi_bridge_get(); + if (bridge) + eo_do(bridge, eo_event_callback_add(ELM_ATSPI_BRIDGE_EVENT_CONNECTED, _on_atspi_bus_connected, NULL)); + } } EOLIAN static Eo* -- 2.7.4