ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
r.x += ee_x;
r.y += ee_y;
+
+ //TIZEN_ONLY(20210608): make plug and socket window work
+ int sx = 0, sy = 0;
+ Evas_Object *top = elm_widget_top_get(obj);
+ efl_access_component_socket_offset_get(top, &sx, &sy);
+ r.x += sx;
+ r.y += sy;
+ //
}
return r;
_elm_win_focus_highlight_reconfigure_job_start(sd);
_elm_win_frame_style_update(sd, 0, 1);
- if (_elm_atspi_enabled())
+ //TIZEN_ONLY(20210608): make plug and socket window work
+ /* elm_plug: do not send activate signal if window is socket window.
+ The socket window is embedded in another window. if AT-client works
+ with activated embedded window directly, it will lost chance to work
+ with embedding window. ex: "1 finger double tap and hold" makes the
+ embedded window get focus when embedded window has highlight object,
+ then "1 finger tap" will interact with the embedded window even though
+ the "1 finger tap" occurs on embedding window */
+ if (_elm_atspi_enabled() && sd->type != EFL_UI_WIN_TYPE_SOCKET_IMAGE)
+ //
{
efl_access_window_activated_signal_emit(obj);
efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_TYPE_ACTIVE, EINA_TRUE);
/* access */
_elm_access_object_highlight_disable(evas_object_evas_get(obj));
- if (_elm_atspi_enabled())
+ //TIZEN_ONLY(20210608): make plug and socket window work
+ /* elm_plug: do not send deactivate signal if window is socket window.
+ The socket window is embedded in another window. if AT-client works
+ with activated embedded window directly, it will lost chance to work
+ with embedding window. ex: "1 finger double tap and hold" makes the
+ embedded window get focus when embedded window has highlight object,
+ then "1 finger tap" will interact with the embedded window even though
+ the "1 finger tap" occurs on embedding window */
+ if (_elm_atspi_enabled() && sd->type != EFL_UI_WIN_TYPE_SOCKET_IMAGE)
+ //
{
efl_access_window_deactivated_signal_emit(obj);
efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_TYPE_ACTIVE, EINA_FALSE);
//TIZEN_ONLY(20171108): make atspi_proxy work
Eo *socket_proxy; /* reference object to atspi object in separate process @since 1.15 */
//
+ //TIZEN_ONLY(20210608): make plug and socket window work
+ Eina_Stringshare *svcname;
+ int svcnum;
+ //
} Efl_Ui_Win_Socket_Data;
//TIZEN_ONLY(20170613) -listen if access mode is enabled
Efl_Ui_Win_Socket_Data * sd = efl_data_scope_get(o, MY_CLASS)
//
+//TIZEN_ONLY(20210608): make plug and socket window work
+static Ecore_Event_Handler *_atspi_bridge_ready_handler = NULL;
+//
+
EOLIAN static Efl_Object *
_efl_ui_win_socket_efl_object_finalize(Eo *obj, Efl_Ui_Win_Socket_Data *pd EINA_UNUSED)
{
return obj;
}
+//TIZEN_ONLY(20210608): make plug and socket window work
+static Eina_Bool
+_atspi_bridge_state_changed(void *data, int type EINA_UNUSED, void *event)
+{
+ Eo *proxy = data;
+ Elm_Event_Atspi_Bridge_State_Changed *ev = event;
+
+ if (ev->state == ELM_ATSPI_BRIDGE_CONNECTED)
+ {
+ elm_atspi_bridge_utils_proxy_listen(proxy);
+ }
+
+ return ECORE_CALLBACK_PASS_ON;
+}
+
+static void
+_win_socket_proxy_create_and_listen(Eo *obj, Efl_Ui_Win_Socket_Data *sd)
+{
+ sd->socket_proxy = _elm_atspi_bridge_utils_proxy_create(obj, sd->svcname, sd->svcnum, ELM_ATSPI_PROXY_TYPE_SOCKET);
+ evas_object_data_set(obj, "___atspi_socket_proxy", sd->socket_proxy);
+
+ /* elm_plug: socket window is a11y child of proxy(of socket window)
+ so the proxy should be a11y parent of the socket window.
+ finding a11y parents happens in atspi_accessible_get_neighbor
+ it will find proxy, and doing "GetNeighbor" with the search mode
+ NEIGHBOR_SEARCH_MODE_CONTIUNE_AFTER_FAILED_RECURSING */
+ Eo *p = efl_access_object_access_parent_get(obj);
+ efl_access_object_access_parent_set(obj, sd->socket_proxy);
+ efl_access_object_access_parent_set(sd->socket_proxy, p);
+
+ if (!elm_atspi_bridge_utils_proxy_listen(sd->socket_proxy))
+ {
+ if (_atspi_bridge_ready_handler) ecore_event_handler_del(_atspi_bridge_ready_handler);
+ _atspi_bridge_ready_handler = ecore_event_handler_add(ELM_EVENT_ATSPI_BRIDGE_STATE_CHANGED, _atspi_bridge_state_changed, sd->socket_proxy);
+ }
+}
+//
+
EOLIAN static Eina_Bool
_efl_ui_win_socket_socket_listen(Eo *obj, Efl_Ui_Win_Socket_Data *pd EINA_UNUSED, const char *svcname, int svcnum, Eina_Bool svcsys)
{
if (!ecore_evas_extn_socket_listen(ee, svcname, svcnum, svcsys))
return EINA_FALSE;
- if (_elm_atspi_enabled())
+ if (_elm_config->atspi_mode)
{
+ if (pd->svcname) eina_stringshare_del(pd->svcname);
+ pd->svcname = eina_stringshare_add(svcname);
+ pd->svcnum = svcnum;
+
if (pd->socket_proxy)
efl_del(pd->socket_proxy);
- pd->socket_proxy = _elm_atspi_bridge_utils_proxy_create(obj, svcname, svcnum, ELM_ATSPI_PROXY_TYPE_SOCKET);
- elm_atspi_bridge_utils_proxy_listen(pd->socket_proxy);
+
+ _win_socket_proxy_create_and_listen(obj, pd);
}
return EINA_TRUE;
}
//
}
+ else
+ {
+ if (!sd->svcname) return;
+
+ /* TODO: sometime the proxy is created already,
+ do not have to create again. remove multiple creation. */
+ if (sd->socket_proxy) return;
+
+ _win_socket_proxy_create_and_listen(obj, sd);
+ }
}
efl_del(sd->socket_proxy);
sd->socket_proxy = NULL;
evas_object_data_set(obj, "___atspi_socket_proxy", NULL);
+ if (_atspi_bridge_ready_handler)
+ {
+ ecore_event_handler_del(_atspi_bridge_ready_handler);
+ _atspi_bridge_ready_handler = NULL;
+ }
}
}
//
EOLIAN static Eina_Rect
_elm_ctxpopup_efl_access_component_extents_get(const Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd, Eina_Bool screen_coords)
{
- int ee_x, ee_y;
Eina_Rect r;
if (!sd->box)
if (screen_coords)
{
- Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(sd->box));
- if (!ee) return r;
- ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
- r.x += ee_x;
- r.y += ee_y;
+ r = _efl_access_component_screen_coords_extents_get(obj, r);
}
return r;
}
//TIZEN_ONLY(20171108): make atspi_proxy work
static const char *_a11y_socket_address;
//
-
EAPI int ELM_EVENT_ATSPI_BRIDGE_STATE_CHANGED = -1;
// Object Event handlers
iter = eldbus_message_iter_get(ret);
Eo *accessible = _calculate_neighbor(bridge, root, start, direction == 1, search_mode);
+
_bridge_iter_object_reference_append(bridge, iter, accessible);
_bridge_object_register(bridge, accessible);
{
/* This only works if we navigate backward, and it is not possible to
find in embedded process. In this case the deputy should be used */
- return _deputy_of_proxy_in_parent_get(start);
+ Eo *d = _deputy_of_proxy_in_parent_get(start);
+ if (d) return d;
+
+ /* elm_plug: does not have deputy, do not return if deputy is null */
}
void *node = start ? start : root;
// register accessible object event listener
pd->event_hdlr = efl_access_object_event_handler_add(_bridge_accessible_event_dispatch, obj);
-
}
static void
//TIZEN_ONLY(20210423): recover init failure
static Eina_Bool
-_init_job(void *data)
+_init_job(void *data EINA_UNUSED)
{
_instance = efl_add_ref(ELM_ATSPI_BRIDGE_CLASS, NULL);
_init_count++;
return;
}
-EAPI void elm_atspi_bridge_utils_proxy_connect(Eo *proxy)
+EAPI Eina_Bool elm_atspi_bridge_utils_proxy_connect(Eo *proxy)
{
Eo *bridge = _elm_atspi_bridge_get();
if (!bridge)
{
ERR("AT-SPI: Atspi bridge is not enabled.");
efl_event_callback_call(proxy, ELM_ATSPI_PROXY_EVENT_DISCONNECTED, NULL);
- return;
+ return EINA_FALSE;
}
- ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
+ ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, EINA_FALSE);
if (!pd->a11y_bus)
{
pd->plug_queue = eina_list_append(pd->plug_queue, proxy);
efl_event_callback_add(proxy, EFL_EVENT_DEL, _from_list_remove, &pd->plug_queue);
}
- return;
+ return EINA_TRUE;
}
_plug_connect(pd->a11y_bus, proxy);
+
+ return EINA_TRUE;
}
//TIZEN_ONLY(20200320) atspi: sanitize service, bus and path names for Dbus communication
return NULL;
}
- efl_access_object_access_parent_set(ret, parent);
+ /* a11y parent of socket window is socket proxy */
+ if (type != ELM_ATSPI_PROXY_TYPE_SOCKET)
+ efl_access_object_access_parent_set(ret, parent);
if (_instance) {
_bridge_object_register(_instance, ret);
_add_plug_or_socket_to_connected_list_in_bridge(proxy);
}
-EAPI void elm_atspi_bridge_utils_proxy_listen(Eo *proxy)
+EAPI Eina_Bool elm_atspi_bridge_utils_proxy_listen(Eo *proxy)
{
Eo *bridge = _elm_atspi_bridge_get();
if (!bridge)
{
ERR("AT-SPI: Atspi bridge is not enabled.");
- return;
+ return EINA_FALSE;
}
- ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
+ ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, EINA_FALSE);
if (!pd->a11y_bus)
{
if (!eina_list_data_find(pd->socket_queue, proxy))
pd->socket_queue = eina_list_append(pd->socket_queue, proxy);
efl_event_callback_add(proxy, EFL_EVENT_DEL, _from_list_remove, &pd->socket_queue);
}
- return;
+ return EINA_TRUE;
}
_socket_ifc_create(pd->a11y_bus, proxy);
+
+ return EINA_TRUE;
}
//
_retry_timer_cb, obj);
}
-EOLIAN static void
-_elm_atspi_proxy_efl_object_destructor(Eo *obj, Elm_Atspi_Proxy_Data *_pd)
+static void
+_proxy_resource_del(Elm_Atspi_Proxy_Data *pd)
{
- if (_pd->retry_timer)
+ if (pd->retry_timer)
{
- ecore_timer_del(_pd->retry_timer);
- _pd->retry_timer = NULL;
+ ecore_timer_del(pd->retry_timer);
+ pd->retry_timer = NULL;
}
- if (_pd->type == ELM_ATSPI_PROXY_TYPE_SOCKET)
- _socket_list = eina_list_remove(_socket_list, obj);
- if (_pd->bus)
+ if (pd->bus)
{
- eina_stringshare_del(_pd->bus);
- _pd->bus = NULL;
+ eina_stringshare_del(pd->bus);
+ pd->bus = NULL;
}
- if (_pd->path)
+
+ if (pd->path)
{
- eina_stringshare_del(_pd->path);
- _pd->path = NULL;
+ eina_stringshare_del(pd->path);
+ pd->path = NULL;
}
+}
+
+EOLIAN static void
+_elm_atspi_proxy_efl_object_destructor(Eo *obj, Elm_Atspi_Proxy_Data *_pd)
+{
+ if (_pd->type == ELM_ATSPI_PROXY_TYPE_SOCKET)
+ _socket_list = eina_list_remove(_socket_list, obj);
+
+ _proxy_resource_del(_pd);
efl_destructor(efl_super(obj, MY_CLASS));
}
_elm_atspi_proxy_efl_ui_widget_atspi(Eo *obj, Elm_Atspi_Proxy_Data *_pd, Eina_Bool is_atspi)
{
EINA_SAFETY_ON_NULL_RETURN(obj);
- if (is_atspi && _pd->type == ELM_ATSPI_PROXY_TYPE_PLUG)
+
+ if (_pd->type != ELM_ATSPI_PROXY_TYPE_PLUG) return;
+
+ if (is_atspi)
{
elm_atspi_bridge_utils_proxy_connect(obj);
}
+ else
+ {
+ /* elm_plug: need to remove resource for next connection
+ next connection means that the case of "atspi on > off > on"
+ see the timer callback checking path and bus. */
+ _proxy_resource_del(_pd);
+ }
}
#include "elm_atspi_proxy_eo.c"
{NULL, NULL}
};
+static Ecore_Event_Handler *_atspi_bridge_ready_handler = NULL;
+
static void
_sizing_eval(Evas_Object *obj EINA_UNUSED)
{
return wd->resize_obj;
}
+//TIZEN_ONLY(20210608): make plug and socket window work
+static void
+_proxy_widget_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+ Evas_Coord x, y;
+ Eo *proxy = data;
+
+ evas_object_geometry_get(obj, &x, &y, NULL, NULL);
+ elm_atspi_bridge_utils_proxy_offset_set(proxy, x, y);
+ evas_object_move(proxy, x, y);
+}
+
+static void
+_proxy_widget_resize_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+ Evas_Coord w, h;
+ Eo *proxy = data;
+
+ evas_object_geometry_get(obj, NULL, NULL, &w, &h);
+ evas_object_resize(proxy, w, h);
+}
+
+static void
+_on_widget_del(void *data, const Efl_Event *event)
+{
+ Eo *plug = data;
+ evas_object_event_callback_del_full(event->object, EVAS_CALLBACK_MOVE,
+ _proxy_widget_move_cb, plug);
+ evas_object_event_callback_del_full(event->object, EVAS_CALLBACK_RESIZE,
+ _proxy_widget_resize_cb, plug);
+ ecore_event_handler_del(_atspi_bridge_ready_handler);
+ efl_del(plug);
+}
+
+static void
+_on_proxy_connected_cb(void *data, const Efl_Event *event)
+{
+ Evas_Coord x, y, w, h;
+ Evas_Object *widget = data;
+
+ evas_object_geometry_get(widget, &x, &y, &w, &h);
+ elm_atspi_bridge_utils_proxy_offset_set(event->object, x, y);
+
+ evas_object_move(event->object, x, y);
+ evas_object_resize(event->object, w, h);
+
+ evas_object_event_callback_add(widget, EVAS_CALLBACK_MOVE, _proxy_widget_move_cb, event->object);
+ evas_object_event_callback_add(widget, EVAS_CALLBACK_RESIZE, _proxy_widget_resize_cb, event->object);
+}
+
+static Eina_Bool
+_atspi_bridge_state_changed(void *data, int type EINA_UNUSED, void *event)
+{
+ Eo *proxy = data;
+ Elm_Event_Atspi_Bridge_State_Changed *ev = event;
+
+ if (ev->state == ELM_ATSPI_BRIDGE_CONNECTED)
+ {
+ elm_atspi_bridge_utils_proxy_connect(proxy);
+ }
+
+ return ECORE_CALLBACK_PASS_ON;
+}
+//
+
EOLIAN static Eina_Bool
_elm_plug_connect(Eo *obj, void *sd EINA_UNUSED, const char *svcname, int svcnum, Eina_Bool svcsys)
{
if (_elm_config->atspi_mode)
{
Eo *proxy = _elm_atspi_bridge_utils_proxy_create(obj, svcname, svcnum, ELM_ATSPI_PROXY_TYPE_PLUG);
- elm_atspi_bridge_utils_proxy_connect(proxy);
+
+ efl_event_callback_add(obj, EFL_EVENT_DEL, _on_widget_del, proxy);
+ efl_event_callback_add(proxy, ELM_ATSPI_PROXY_EVENT_CONNECTED, _on_proxy_connected_cb, obj);
+
+ if (!elm_atspi_bridge_utils_proxy_connect(proxy))
+ {
+ if (_atspi_bridge_ready_handler) ecore_event_handler_del(_atspi_bridge_ready_handler);
+ _atspi_bridge_ready_handler = ecore_event_handler_add(ELM_EVENT_ATSPI_BRIDGE_STATE_CHANGED, _atspi_bridge_state_changed, proxy);
+ }
}
//
Edje_Signal_Cb func_cb);
//TIZEN_ONLY(20171108): make atspi_proxy work
Eo* _elm_atspi_bridge_utils_proxy_create(Eo *parent, const char *svcname, int svcnum, Elm_Atspi_Proxy_Type type);
-void elm_atspi_bridge_utils_proxy_listen(Eo *proxy);
-void elm_atspi_bridge_utils_proxy_connect(Eo *proxy);
+Eina_Bool elm_atspi_bridge_utils_proxy_listen(Eo *proxy);
+Eina_Bool elm_atspi_bridge_utils_proxy_connect(Eo *proxy);
void elm_atspi_bridge_utils_proxy_offset_set(Eo *proxy, int x, int y);
void elm_object_accessibility_highlight_set(void *obj, Eina_Bool val);
Eina_Bool _elm_atspi_bridge_plug_id_split(const char *plug_id, char **bus, char **path);
+//
//TIZEN_ONLY(20170621) handle atspi proxy connection at runtime
void _access_socket_proxy_listen(Eo * obj);
void _access_socket_proxy_del(Eo * obj);
//
-//
/* end of DEPRECATED */
/* DO NOT USE THIS this is only for performance optimization! */
EOLIAN static Eina_Rect
_elm_ctxpopup_efl_access_component_extents_get(const Eo *obj EINA_UNUSED, Elm_Ctxpopup_Data *sd, Eina_Bool screen_coords)
{
- int ee_x, ee_y;
Eina_Rect r;
if (!sd->scr)
if (screen_coords)
{
- Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(sd->scr));
- if (!ee) return r;
- ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
- r.x += ee_x;
- r.y += ee_y;
+ r = _efl_access_component_screen_coords_extents_get(obj, r);
}
return r;
}