const Eo_Event_Description *desc EINA_UNUSED,
void *event_info EINA_UNUSED)
{
- ELM_WIDGET_DATA_GET(data, sd);
+ ELM_WIDGET_DATA_GET_OR_RETURN(data, sd, EINA_FALSE);
if (_elm_widget_is(obj))
{
eina_iterator_free(it);
if (_elm_atspi_enabled())
- elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_SHOWING, EINA_FALSE);
+ {
+ //TIZEN_ONLY(20161223) check if the parent of highlighted object is hide
+ Eo *highlighted_obj;
+ highlighted_obj = _elm_object_accessibility_currently_highlighted_get();
+ if (highlighted_obj && highlighted_obj != obj)
+ {
+ Eo *parent;
+ eo_do(highlighted_obj, parent = elm_interface_atspi_accessible_parent_get());
+ while (parent)
+ {
+ if (parent == obj)
+ {
+ elm_interface_atspi_accessible_state_changed_signal_emit(highlighted_obj, ELM_ATSPI_STATE_SHOWING, EINA_FALSE);
+ eo_do(highlighted_obj, elm_interface_atspi_component_highlight_clear());
+ break;
+ }
+ eo_do(parent, parent = elm_interface_atspi_accessible_parent_get());
+ }
+ }
+ //
+
+ elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_SHOWING, EINA_FALSE);
+ }
}
EOLIAN static void
break;
}
- if (!elm_widget_focus_region_get(o, &x, &y, &w, &h))
- {
- o = elm_widget_parent_get(o);
- continue;
- }
+ elm_widget_focus_region_get(o, &x, &y, &w, &h);
+ evas_object_geometry_get(o, &ox, &oy, NULL, NULL);
}
else
{
//TIZEN_ONLY(20160822): When atspi mode is dynamically switched on/off,
//register/unregister access objects accordingly.
+// TIZEN_ONLY(20170516): connect to at-spi dbus based on org.a11y.Status.IsEnabled property
EAPI Eina_Bool
-elm_widget_atspi(Evas_Object *obj,
- Eina_Bool is_atspi)
+elm_widget_screen_reader(Evas_Object *obj,
+ Eina_Bool is_screen_reader)
{
const Eina_List *l;
Evas_Object *child;
EINA_LIST_FOREACH(sd->subobjs, l, child)
{
if (elm_widget_is(child))
- ret &= elm_widget_atspi(child, is_atspi);
+ ret &= elm_widget_screen_reader(child, is_screen_reader);
+ }
+ eo_do(obj, elm_obj_widget_screen_reader(is_screen_reader));
+
+ return ret;
+}
+
+EOLIAN static void
+_elm_widget_screen_reader(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eina_Bool is_screen_reader EINA_UNUSED)
+{
+}
+
+//TIZEN_ONLY(20170621) handle atspi proxy connection at runtime
+EAPI Eina_Bool
+elm_widget_atspi(Evas_Object *obj, Eina_Bool is_atspi)
+{
+ Eina_List *l, *children;
+ Evas_Object *child;
+ Eina_Bool ret = EINA_TRUE;
+
+ API_ENTRY return EINA_FALSE;
+ eo_do(obj, children = elm_interface_atspi_accessible_children_get());
+ EINA_LIST_FOREACH(children, l, child)
+ {
+ ret &= elm_widget_atspi(child, is_atspi);
}
eo_do(obj, elm_obj_widget_atspi(is_atspi));
{
}
//
+//
+//
EOLIAN static void
_elm_widget_access(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eina_Bool is_access EINA_UNUSED)
}
}
}
+ /* TIZEN_ONLY(20161212): Some winsets should know whether it's focus target or not in _on_focus */
+ sd = eo_data_scope_get(obj, MY_CLASS);
+ sd->is_focus_target = EINA_TRUE;
+ //
_parent_focus(obj, item);
+ /* TIZEN_ONLY(20161212): Some winsets should know whether it's focus target or not in _on_focus */
+ sd->is_focus_target = EINA_FALSE;
+ //
elm_widget_focus_region_show(obj);
return;
}
Evas_Coord px, py, cx, cy, nx = 0, ny = 0;
+ /* TIZEN_ONLY(20161222): Update show region geometry when entry is resized
+ Move this code to the blow to update show region geometry properly.
evas_smart_objects_calculate(evas_object_evas_get(obj));
+ */
if (!forceshow && (x == sd->rx) && (y == sd->ry) &&
(w == sd->rw) && (h == sd->rh)) return;
sd->ry = y;
sd->rw = w;
sd->rh = h;
+
+ /* TIZEN_ONLY(20161222): Update show region geometry when entry is resized */
+ /* Block nested call for evas_smart_objects_calculate() and region showing works */
+ if (sd->on_show_region_set) return;
+
+ sd->on_show_region_set = EINA_TRUE;
+
+ evas_smart_objects_calculate(evas_object_evas_get(obj));
+
+ sd->on_show_region_set = EINA_FALSE;
+
+ /* show_region geometry could be changed during processing elm_widget_show_region_set().
+ evas_smart_objects_calculate() can trigger nested show_region_set calls */
+ x = sd->rx;
+ y = sd->ry;
+ w = sd->rw;
+ h = sd->rh;
+ /* END */
+
if (sd->on_show_region)
{
sd->on_show_region
return ELM_THEME_APPLY_SUCCESS;
}
+/* TIZEN_ONLY(20161223): add widget style set furnction for internal usage
+ this function is same with elm_widget_style_set
+ but it doesn't apply sub object's theme */
+Elm_Theme_Apply
+_elm_widget_style_set_internal(Evas_Object *obj, const char *style)
+{
+ Elm_Theme_Apply ret = ELM_THEME_APPLY_SUCCESS;
+
+ API_ENTRY return ELM_THEME_APPLY_FAILED;
+
+ if (eina_stringshare_replace(&sd->style, style))
+ {
+ const Eina_List *l;
+ Elm_Tooltip *tt;
+ Elm_Cursor *cur;
+
+ if (sd->hover_obj) ret &= elm_widget_theme(sd->hover_obj);
+
+ EINA_LIST_FOREACH(sd->tooltips, l, tt)
+ elm_tooltip_theme(tt);
+ EINA_LIST_FOREACH(sd->cursors, l, cur)
+ elm_cursor_theme(cur);
+
+ Elm_Theme_Apply ret2 = ELM_THEME_APPLY_FAILED;
+ eo_do(obj, ret2 = elm_obj_widget_theme_apply());
+ ret &= ret2;
+ }
+
+ return ret;
+}
+/* END */
+
EOLIAN static const char*
_elm_widget_style_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
{
elm_interface_atspi_accessible_description_cb_set(NULL, NULL),
elm_interface_atspi_accessible_name_cb_set(NULL, NULL),
//
+
+ //TIZEN_ONLY(20170405) Add gesture method to accessible interface
+ elm_interface_atspi_accessible_gesture_cb_set(NULL, NULL),
+ //
elm_interface_atspi_accessible_translation_domain_set(NULL),
elm_interface_atspi_accessible_relationships_clear(),
// TIZEN_ONLY(20160930) : endless recursion fix
return EINA_TRUE;
}
+const char*
+_elm_widget_accessible_plain_name_get(Evas_Object *obj, const char* name)
+{
+ char *accessible_plain_name;
+
+ API_ENTRY return NULL;
+
+ accessible_plain_name = _elm_util_mkup_to_text(name);
+ eina_stringshare_del(sd->accessible_name);
+ sd->accessible_name = eina_stringshare_add(accessible_plain_name);
+ free(accessible_plain_name);
+ return sd->accessible_name;
+}
+
+const char*
+_elm_widget_item_accessible_plain_name_get(Elm_Object_Item *item, const char* name)
+{
+ char *accessible_plain_name;
+
+ Elm_Widget_Item_Data *id = eo_data_scope_get(item, ELM_WIDGET_ITEM_CLASS);
+ if (!id) return NULL;
+
+ accessible_plain_name = _elm_util_mkup_to_text(name);
+ eina_stringshare_del(id->accessible_name);
+ id->accessible_name = eina_stringshare_add(accessible_plain_name);
+ free(accessible_plain_name);
+ return id->accessible_name;
+}
+
+//TIZEN_ONLY(20160929) : atspi: Improves how to find the can_highlight of the widget
+static Eina_Bool
+_elm_widget_can_highlight_get_by_class(Eo *obj)
+{
+ if (eo_isa(obj, ELM_WIDGET_ITEM_CLASS))
+ {
+ Elm_Widget_Item_Data *id = eo_data_scope_get(obj, ELM_WIDGET_ITEM_CLASS);
+ if (!id) return EINA_FALSE;
+ if (!id->can_highlight) return EINA_FALSE;
+ }
+ else
+ {
+ Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_WIDGET_CLASS);
+ if (!wd) return EINA_FALSE;
+ if (!wd->can_highlight) return EINA_FALSE;
+ }
+ return EINA_TRUE;
+}
+//
+
//TIZEN_ONLY(20161107): enhance elm_atspi_accessible_can_highlight_set to set can_hihglight property to its children
EAPI Eina_Bool
_elm_widget_item_highlightable(Elm_Object_Item *item)
{
+ Eo *parent;
+
Elm_Widget_Item_Data *id = eo_data_scope_get(item, ELM_WIDGET_ITEM_CLASS);
if (!id) return EINA_FALSE;
if (!id->can_highlight) return EINA_FALSE;
- Evas_Object *widget = id->widget;
- Evas_Object *parent = widget;
- Elm_Widget_Smart_Data *wd;
- if (parent && eo_isa(parent, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
+
+ eo_do(item, parent = elm_interface_atspi_accessible_parent_get());
+ while (parent && !eo_isa(parent, ELM_ATSPI_APP_OBJECT_CLASS))
{
- wd = eo_data_scope_get(parent, ELM_WIDGET_CLASS);
- if (!wd->can_highlight) return EINA_FALSE;
+ //TIZEN_ONLY(20160929) : atspi: Improves how to find the can_highlight of the widget
+ if (!_elm_widget_can_highlight_get_by_class(parent)) return EINA_FALSE;
+ //
+ eo_do(parent, parent = elm_interface_atspi_accessible_parent_get());
}
- do
+ return EINA_TRUE;
+}
+//
+
+//TIZEN_ONLY(20170206): Add check the object is in the scroller content size
+Eina_Bool
+_accessible_object_on_scroll_is(Eo* obj)
+{
+ /* in case of genlist item, the item->view is NULL if item is unrealized.
+ this function is used to check if obj could have HIGHLIGHTABLE or not.
+ the unrealized genlist item should have HIGHLIGHTABLE state.
+ so if obj is NULL return EINA_TRUE */
+ if(!obj) return EINA_TRUE;
+
+ Evas_Object *target = obj;
+ Evas_Object *parent = NULL;
+ Evas_Coord x, y, w, h, wx, wy, ww = 0, wh = 0, nx = 0, ny = 0;
+
+ evas_object_geometry_get(target, &x, &y ,&w, &h);
+
+ if (elm_widget_is(target))
+ parent = elm_widget_parent_get(target);
+ else
+ parent = elm_widget_parent_widget_get(target);
+
+ while (parent)
{
- parent = elm_widget_parent_get(parent);
- if (parent && eo_isa(parent, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
+ if (eo_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
{
- wd = eo_data_scope_get(parent, ELM_WIDGET_CLASS);
- if (!wd->can_highlight) return EINA_FALSE;
+ evas_object_geometry_get(parent, &wx, &wy, NULL, NULL);
+ eo_do(parent, elm_interface_scrollable_content_size_get(&ww, &wh));
+ eo_do(parent, elm_interface_scrollable_content_pos_get(&nx, &ny));
+
+ /* widget implements scrollable interface but does not use scoller
+ in this case, use widget geometry */
+ if (ww == 0 || wh == 0)
+ {
+ INF("%s is zero sized scrollable content", eo_class_name_get(eo_class_get(parent)));
+ evas_object_geometry_get(parent, NULL, NULL, &ww, &wh);
+ }
+
+ wx -= nx;
+ wy -= ny;
+
+ if (((wx < x) && (wx + ww < x)) || ((wx > x + w) && (wx + ww > x + w)) ||
+ ((wy < y) && (wy + wh < y)) || ((wy > y + h) && (wy + wh > y + h)))
+ return EINA_FALSE;
+
+ break;
}
+ parent = elm_widget_parent_get(parent);
}
- while (parent && (parent != elm_widget_top_get(widget)));
+
return EINA_TRUE;
}
//
{
STATE_TYPE_SET(states, ELM_ATSPI_STATE_ENABLED);
STATE_TYPE_SET(states, ELM_ATSPI_STATE_SENSITIVE);
- STATE_TYPE_SET(states, ELM_ATSPI_STATE_VISIBLE);
}
if (_elm_widget_item_onscreen_is(eo_item))
STATE_TYPE_SET(states, ELM_ATSPI_STATE_SHOWING);
+ //TIZEN_ONLY(20170207) : [ATSPI] enhance expose highlight information on atspi
+ /* unrealized genlist item does not have item->view,
+ and item cannot change its visibility, only widget can change the visibility */
+ if (evas_object_visible_get(item->widget))
+ STATE_TYPE_SET(states, ELM_ATSPI_STATE_VISIBLE);
+ //
+
//TIZEN_ONLY(20170717) : expose highlight information on atspi
- if (_elm_widget_item_highlightable(eo_item))
+ if (_elm_widget_item_highlightable(eo_item) && _accessible_object_on_scroll_is(item->view))
STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTABLE);
else
STATE_TYPE_UNSET(states, ELM_ATSPI_STATE_HIGHLIGHTABLE);
elm_interface_atspi_accessible_description_cb_set(NULL, NULL),
elm_interface_atspi_accessible_name_cb_set(NULL, NULL),
//
+ //TIZEN_ONLY(20170405) Add gesture method to accessible interface
+ elm_interface_atspi_accessible_gesture_cb_set(NULL, NULL),
+ //
elm_interface_atspi_accessible_translation_domain_set(NULL),
elm_interface_atspi_accessible_relationships_clear(),
// TIZEN_ONLY(20160930) : endless recursion fix
return EINA_FALSE;
}
+//TIZEN_ONLY(20170119): Show the object highlighted by highlight_grab when the object is completely out of the scroll
+void
+_elm_widget_showing_geometry_get(Eo *obj, int *x, int *y, int *w, int *h)
+{
+ Evas_Object *parent;
+ Evas_Coord px, py, sx, sy, sw, sh;
+
+ *x = 0;
+ *y = 0;
+ *w = 0;
+ *h = 0;
+
+ if (!obj) return;
+
+ evas_object_geometry_get(obj, x, y, w, h);
+
+ if (elm_widget_is(obj))
+ parent = elm_widget_parent_get(obj);
+ else
+ parent = elm_widget_parent_widget_get(obj);
+
+ while (parent)
+ {
+ if (eo_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
+ {
+ evas_object_geometry_get(parent, &sx, &sy, &sw, &sh);
+ px = *x;
+ py = *y;
+ *x = *x > sx ? *x : sx;
+ *y = *y > sy ? *y : sy;
+ *w = px + *w < sx + sw ? px + *w - *x : sx + sw - *x;
+ *h = py + *h < sy + sh ? py + *h - *y : sy + sh - *y;
+ }
+ parent = elm_widget_parent_get(parent);
+ }
+}
+
+Eina_Bool
+_accessible_object_on_screen_is(Eo *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, Eina_Bool is_complete)
+{
+ if(!obj) return EINA_FALSE;
+
+ Evas_Object *target = obj;
+ Evas_Object *parent = NULL;
+ Evas_Coord px, py, sx, sy, sw, sh, ox, oy, ow, oh;
+
+ /* uninitialized data could be read */
+ ow = 0;
+ oh = 0;
+
+ if (elm_widget_is(target))
+ parent = elm_widget_parent_get(target);
+ else
+ parent = elm_widget_parent_widget_get(target);
+
+ while (parent)
+ {
+ if (eo_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
+ {
+ evas_object_geometry_get(parent, &sx, &sy, &sw, &sh);
+ px = ox = x;
+ py = oy = y;
+ ow = w;
+ oh = h;
+ ox = is_complete ? ox : ox + ow;
+ oy = is_complete ? oy : oy + oh;
+ ox = ox > sx ? ox : sx;
+ oy = oy > sy ? oy : sy;
+ ow = px + ow < sx + sw ? px + ow - ox : sx + sw - ox;
+ oh = py + oh < sy + sh ? py + oh - oy : sy + sh - oy;
+ }
+ if (ow <= 0 || oh <= 0)
+ return EINA_FALSE;
+
+ parent = elm_widget_parent_get(parent);
+ }
+ return EINA_TRUE;
+}
+
+Eina_List *
+_accessible_scrollable_parent_list_get(Eo *obj)
+{
+ if(!obj) return NULL;
+
+ Evas_Object *parent = NULL;
+ Eina_List *plist = NULL;
+
+ if (elm_widget_is(obj))
+ parent = elm_widget_parent_get(obj);
+ else
+ parent = elm_widget_parent_widget_get(obj);
+
+ while (parent)
+ {
+ if (_elm_scrollable_is(parent))
+ plist = eina_list_append(plist, parent);
+
+ parent = elm_widget_parent_get(parent);
+ }
+ return plist;
+}
+
+void
+_accessible_highlight_region_show(Eo* obj)
+{
+ if (!obj) return;
+
+ Evas_Object *target = obj;
+ Evas_Object *parent = NULL;
+ Evas_Object *parent_sub = NULL;
+ Eina_List *plist, *plist_sub;
+ Eina_List *l, *l2;
+
+ Evas_Coord target_x, target_y, target_w, target_h;
+
+ evas_object_geometry_get(target, &target_x, &target_y, &target_w, &target_h);
+
+ plist = _accessible_scrollable_parent_list_get(target);
+ if (!plist) return;
+
+ EINA_LIST_FOREACH(plist, l, parent)
+ {
+ if(!_accessible_object_on_screen_is(target, target_x, target_y, target_w, target_h, EINA_TRUE))
+ {
+ plist_sub = _accessible_scrollable_parent_list_get(parent);
+ plist_sub = eina_list_prepend(plist_sub, parent);
+ EINA_LIST_FOREACH(plist_sub, l2, parent_sub)
+ {
+ Evas_Coord scroll_x = 0, scroll_y = 0;
+ Evas_Coord scroll_x_back = 0, scroll_y_back = 0;
+ Evas_Coord x, y, w, h;
+ Evas_Coord px, py;
+
+ eo_do(parent_sub, elm_interface_scrollable_content_region_get(&scroll_x_back, &scroll_y_back, NULL, NULL));
+ evas_object_geometry_get(parent_sub, &px, &py, NULL, NULL);
+ x = target_x; y = target_y; w = target_w; h = target_h;
+
+ x -= (px - scroll_x_back);
+ y -= (py - scroll_y_back);
+ switch (_elm_config->focus_autoscroll_mode)
+ {
+ case ELM_FOCUS_AUTOSCROLL_MODE_SHOW:
+ eo_do(parent_sub, elm_interface_scrollable_content_region_show(x, y, w, h));
+ break;
+ case ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN:
+ eo_do(parent_sub, elm_interface_scrollable_region_bring_in(x, y, w, h));
+ break;
+ default:
+ break;
+ }
+ eo_do(parent_sub, elm_interface_scrollable_content_region_get(&scroll_x, &scroll_y, NULL, NULL));
+
+ target_x -= (scroll_x - scroll_x_back);
+ target_y -= (scroll_y - scroll_y_back);
+
+ if(_accessible_object_on_screen_is(target, target_x, target_y, target_w, target_h, EINA_FALSE))
+ break;
+ }
+ eina_list_free(plist_sub);
+ }
+ }
+
+ eina_list_free(plist);
+}
+//
+
+//TIZEN_ONLY(20171011) : atspi : During the highlight grab, out signal is not sent.
+Eina_Bool
+_elm_widget_accessibility_highlight_grabbing_get(Eo *obj)
+{
+ ELM_WIDGET_DATA_GET(obj, wd);
+ return wd->highlight_grabbing;
+}
+
+void
+_elm_widget_accessibility_highlight_grabbing_set(Eo *obj, Eina_Bool grabbing)
+{
+ ELM_WIDGET_DATA_GET(obj, wd);
+ wd->highlight_grabbing = grabbing;
+}
+//
+
//TIZEN_ONLY(20160329): atspi: implement HighlightGrab and HighlightClear methods (29e253e2f7ef3c632ac3a64c489bf569df407f30)
EOLIAN static Eina_Bool
_elm_widget_elm_interface_atspi_component_highlight_grab(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
{
+ if(!obj) return EINA_FALSE;
if(!_elm_atspi_enabled())
return EINA_FALSE;
+ // TIZEN_ONLY(20171020) : atspi : Do not send signal, if current object and highlight object are same
+ if (_elm_object_accessibility_currently_highlighted_get() == obj)
+ return EINA_FALSE;
+ //
- elm_widget_focus_region_show(obj);
+ //TIZEN_ONLY(20171011) : atspi : During the highlight grab, out signal is not sent.
+ _elm_widget_accessibility_highlight_grabbing_set(obj, EINA_TRUE);
+ //
+
+ //TIZEN_ONLY(20170119): Show the object highlighted by highlight_grab when the object is completely out of the scroll
+ _accessible_highlight_region_show(obj);
+ //
elm_object_accessibility_highlight_set(obj, EINA_TRUE);
elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
// TIZEN_ONLY(20161018): add highlighted/unhighlighted signal for atspi
evas_object_smart_callback_call(obj, SIG_WIDGET_ATSPI_HIGHLIGHTED, NULL);
//
+ //TIZEN_ONLY(20171011) : atspi : During the highlight grab, out signal is not sent.
+ _elm_widget_accessibility_highlight_grabbing_set(obj, EINA_FALSE);
+ //
return EINA_TRUE;
}
//
EOLIAN static const char*
-_elm_widget_elm_interface_atspi_accessible_name_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd)
+_elm_widget_elm_interface_atspi_accessible_name_get(Eo *obj, Elm_Widget_Smart_Data *_pd)
{
- char *accessible_name;
//TIZEN_ONLY(20190922): add name callback, description callback.
const char *ret = NULL;
eo_do_super(obj, ELM_WIDGET_CLASS, ret = elm_interface_atspi_accessible_name_get());
}
//
+ //TIZEN_ONLY(20170110) : Ignore text from elm_object_text_set in accessible_name_get
+ Elm_Atspi_Role role;
+ eo_do(obj, role = elm_interface_atspi_accessible_role_get());
+ if(role == ELM_ATSPI_ROLE_DIALOG)
+ return NULL;
+ //
+
ret = elm_object_text_get(obj);
if (!ret) return NULL;
- accessible_name = _elm_util_mkup_to_text(ret);
- eina_stringshare_del(_pd->accessible_name);
- _pd->accessible_name = eina_stringshare_add(accessible_name);
- free(accessible_name);
- return _pd->accessible_name;
+ return _elm_widget_accessible_plain_name_get(obj, ret);
}
//TIZEN_ONLY(20161111) add widget/widget_item description get/set
EOLIAN void
evas_object_geometry_get(c, NULL, &y, NULL, &h);
/* remove child if its height == 0 */
- if (h == 0) continue;
+ if (h == 0 && !eo_isa(c, ELM_ATSPI_PROXY_CLASS)) continue;
if ((yl + (int)(0.25 * hl)) >= y)
{
//
// TIZEN ONLY - END
+//TIZEN_ONLY(20170621) handle atspi proxy connection at runtime
+static Eo *
+_plug_type_proxy_get(Eo *obj, Evas_Object *widget)
+{
+ Eo *proxy = NULL;
+ const char *plug_id;
+ char *svcname, *svcnum;
+
+ if ((plug_id = evas_object_data_get(widget, "___PLUGID")) != NULL)
+ {
+ // TIZEN_ONLY(20160930) : endless recursion fix
+ eo_do_super(obj, MY_CLASS, elm_interface_atspi_accessible_attribute_append("___PlugID", plug_id));
+
+ proxy = evas_object_data_get(widget, "__widget_proxy");
+ if (proxy) return proxy;
+
+ if (_elm_atspi_bridge_plug_id_split(plug_id, &svcname, &svcnum))
+ {
+ proxy = _elm_atspi_bridge_utils_proxy_create(obj, svcname, atoi(svcnum), ELM_ATSPI_PROXY_TYPE_PLUG);
+ evas_object_data_set(widget, "__widget_proxy", proxy);
+ eo_do(widget, eo_event_callback_add(EO_EV_DEL, _on_widget_del, proxy));
+ eo_do(proxy, eo_event_callback_add(ELM_ATSPI_PROXY_EVENT_CONNECTED, _on_proxy_connected_cb, widget));
+ elm_atspi_bridge_utils_proxy_connect(proxy);
+ free(svcname);
+ free(svcnum);
+ }
+ }
+
+ return proxy;
+}
+
+EAPI Eo *
+elm_widget_atspi_plug_type_proxy_get(Evas_Object *obj)
+{
+ Elm_Widget_Smart_Data *wd;
+ Evas_Object *widget;
+ Eina_List *l;
+
+ wd = eo_data_scope_get(obj, ELM_WIDGET_CLASS);
+ if (!wd) return NULL;
+
+ Eo *proxy = NULL;
+ EINA_LIST_FOREACH(wd->subobjs, l, widget)
+ {
+ if (evas_object_data_get(widget, "___PLUGID"))
+ proxy = _plug_type_proxy_get(obj, widget);
+ if (proxy) break;
+ }
+ return proxy;
+}
+//
+
EOLIAN static Eina_List*
_elm_widget_elm_interface_atspi_accessible_children_get(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
{
}
}
+ Eo *proxy = NULL;
EINA_LIST_FOREACH(wd->subobjs, l, widget)
{
// TIZEN_ONLY(20160824): Do not append a child, if its accessible parent is different with widget parent
}
// TIZEN_ONLY(20160705) - enable atspi_proxy to work
- const char *plug_id_2;
- if ((plug_id_2 = evas_object_data_get(widget, "___PLUGID")) != NULL)
+ /* This assumes that only one proxy exists in obj */
+ if (!proxy)
{
- // TIZEN_ONLY(20160930) : endless recursion fix
- eo_do_super(obj, MY_CLASS, elm_interface_atspi_accessible_attribute_append("___PlugID", plug_id_2));
-
- Eo *proxy;
- char *svcname, *svcnum;
-
- proxy = evas_object_data_get(widget, "__widget_proxy");
+ proxy = _plug_type_proxy_get(obj, widget);
if (proxy)
{
accs = eina_list_append(accs, proxy);
continue;
}
-
- if (_elm_atspi_bridge_plug_id_split(plug_id_2, &svcname, &svcnum))
- {
- proxy = _elm_atspi_bridge_utils_proxy_create(obj, svcname, atoi(svcnum), ELM_ATSPI_PROXY_TYPE_PLUG);
- evas_object_data_set(widget, "__widget_proxy", proxy);
- eo_do(widget, eo_event_callback_add(EO_EV_DEL, _on_widget_del, proxy));
- eo_do(proxy, eo_event_callback_add(ELM_ATSPI_PROXY_EVENT_CONNECTED, _on_proxy_connected_cb, widget));
- elm_atspi_bridge_utils_proxy_connect(proxy);
- accs = eina_list_append(accs, proxy);
- free(svcname);
- free(svcnum);
- }
- continue;
}
//
// TIZEN ONLY - END
EINA_LIST_FREE(lines, line)
accs = eina_list_merge(accs, eina_list_sort(line, -1, _sort_horizontally));
//
+
+ if (proxy)
+ {
+ Eo *deputy = NULL;
+ accs = eina_list_remove(accs, proxy);
+ EINA_LIST_FOREACH(accs, l, widget)
+ {
+ if (eo_isa(widget, ELM_ACCESS_CLASS))
+ {
+ Elm_Access_Info *info = _elm_access_info_get(widget);
+ if (!info) continue;
+ if (obj == info->part_object)
+ {
+ deputy = widget;
+ break;
+ }
+ }
+ }
+
+ if (deputy)
+ {
+ accs = eina_list_append_relative(accs, proxy, deputy);
+ }
+ }
return accs;
}
EAPI Eina_Bool
_elm_widget_highlightable(Evas_Object *obj)
{
+ Eo *parent;
+
Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_WIDGET_CLASS);
if (!wd) return EINA_FALSE;
if (!wd->can_highlight) return EINA_FALSE;
- Evas_Object *parent = elm_widget_parent_get(obj);
- if (parent && eo_isa(parent, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
- {
- wd = eo_data_scope_get(parent, ELM_WIDGET_CLASS);
- if (!wd->can_highlight) return EINA_FALSE;
- }
- do
+
+ eo_do(obj, parent = elm_interface_atspi_accessible_parent_get());
+ while (parent && !eo_isa(parent, ELM_ATSPI_APP_OBJECT_CLASS))
{
- parent = elm_widget_parent_get(parent);
- if (parent && eo_isa(parent, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
- {
- wd = eo_data_scope_get(parent, ELM_WIDGET_CLASS);
- if (!wd->can_highlight) return EINA_FALSE;
- }
+ //TIZEN_ONLY(20160929) : atspi: Improves how to find the can_highlight of the widget
+ if (!_elm_widget_can_highlight_get_by_class(parent)) return EINA_FALSE;
+ //
+ eo_do(parent, parent = elm_interface_atspi_accessible_parent_get());
}
- while (parent && (parent != elm_widget_top_get(obj)));
return EINA_TRUE;
}
//
}
//TIZEN_ONLY(20170717) : expose highlight information on atspi
- if (_elm_widget_highlightable(obj))
+ if (_elm_widget_highlightable(obj) && _accessible_object_on_scroll_is(obj))
STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTABLE);
else
STATE_TYPE_UNSET(states, ELM_ATSPI_STATE_HIGHLIGHTABLE);
{
return elm_atspi_relation_set_clone(&sd->atspi_custom_relations);
}
+
+EOLIAN static void
+_elm_widget_elm_interface_atspi_accessible_relationships_clear(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
+{
+ elm_atspi_relation_set_free(&sd->atspi_custom_relations);
+ sd->atspi_custom_relations = NULL;
+}
+//
+
+EOLIAN static void
+_elm_widget_item_elm_interface_atspi_accessible_relationships_clear(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd)
+{
+ elm_atspi_relation_set_free(&sd->atspi_custom_relations);
+ sd->atspi_custom_relations = NULL;
+}
//
EOLIAN static void
}
//TIZEN_ONLY(20160329): atspi: implement HighlightGrab and HighlightClear methods
+
EOLIAN static Eina_Bool
_elm_widget_item_elm_interface_atspi_component_highlight_grab(Eo *obj, Elm_Widget_Item_Data *sd)
{
+ if (!sd) return EINA_FALSE;
+ if (!sd->view) return EINA_FALSE;
+ // TIZEN_ONLY(20171020) : atspi : Do not send signal, if current object and highlight object are same
+ if (_elm_object_accessibility_currently_highlighted_get() == obj)
+ return EINA_FALSE;
+ //
- if (!obj) return EINA_FALSE;
+ //TIZEN_ONLY(20171011) : atspi : During the highlight grab, out signal is not sent.
+ _elm_widget_accessibility_highlight_grabbing_set(sd->view, EINA_TRUE);
+ //
- Evas_Object *o = elm_object_parent_widget_get(sd->view);
- if (_elm_scrollable_is(o))
- {
- Evas_Coord bx, by, bw, bh;
- Evas_Coord x, y, w, h;
- Evas_Object *w1 = elm_object_parent_widget_get(o);
- evas_object_geometry_get(sd->view, &x, &y, &w, &h);
- evas_object_geometry_get(o, &bx, &by, &bw, &bh);
- x -= bx;
- y -= by;
- switch (_elm_config->focus_autoscroll_mode)
- {
- case ELM_FOCUS_AUTOSCROLL_MODE_SHOW:
- eo_do(w1, elm_interface_scrollable_content_region_show(x, y, w, h));
- break;
- case ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN:
- eo_do(w1, elm_interface_scrollable_region_bring_in(x, y, w, h));
- break;
- default:
- break;
- }
- }
+ //TIZEN_ONLY(20170119): Show the object highlighted by highlight_grab when the object is completely out of the scroll
+ _accessible_highlight_region_show(sd->view);
+ //
+ if (!sd->eo_obj) return EINA_FALSE;
elm_object_accessibility_highlight_set(sd->eo_obj, EINA_TRUE);
+
+ if (!obj) return EINA_FALSE;
elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
+ //TIZEN_ONLY(20170412) Make atspi,(un)highlighted work on widget item
+ evas_object_smart_callback_call(sd->widget, SIG_WIDGET_ATSPI_HIGHLIGHTED, obj);
+ //
+ //TIZEN_ONLY(20171011) : atspi : During the highlight grab, out signal is not sent.
+ _elm_widget_accessibility_highlight_grabbing_set(sd->view, EINA_FALSE);
+ //
return EINA_TRUE;
-
}
EOLIAN static Eina_Bool
if (!obj) return EINA_FALSE;
elm_object_accessibility_highlight_set(sd->eo_obj, EINA_FALSE);
elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_HIGHLIGHTED, EINA_FALSE);
+
+ //TIZEN_ONLY(20170412) Make atspi,(un)highlighted work on widget item
+ evas_object_smart_callback_call(sd->widget, SIG_WIDGET_ATSPI_UNHIGHLIGHTED, obj);
+ //
return EINA_TRUE;
}
//
return ret;
}
+static int _sort_by_size(const void *data1, const void *data2)
+{
+ Evas_Coord w, h;
+ Evas_Coord w2, h2;
+
+ evas_object_geometry_get(data1, NULL, NULL, &w, &h);
+ evas_object_geometry_get(data2, NULL, NULL, &w2, &h2);
+
+ if ((w * h) > (w2 * h2)) return 1;
+ return -1;
+}
+
+Eina_Bool
+_elm_widget_atspi_role_acceptable_check(Eo *obj)
+{
+ Elm_Atspi_Role role;
+ eo_do(obj, role = elm_interface_atspi_accessible_role_get());
+
+ switch (role)
+ {
+ case ELM_ATSPI_ROLE_APPLICATION:
+ case ELM_ATSPI_ROLE_FILLER:
+ case ELM_ATSPI_ROLE_SCROLL_PANE:
+ case ELM_ATSPI_ROLE_SPLIT_PANE:
+ case ELM_ATSPI_ROLE_WINDOW:
+ case ELM_ATSPI_ROLE_IMAGE:
+ case ELM_ATSPI_ROLE_LIST:
+ case ELM_ATSPI_ROLE_ICON:
+ case ELM_ATSPI_ROLE_TOOL_BAR:
+ case ELM_ATSPI_ROLE_REDUNDANT_OBJECT:
+ case ELM_ATSPI_ROLE_COLOR_CHOOSER:
+ case ELM_ATSPI_ROLE_TREE_TABLE:
+ case ELM_ATSPI_ROLE_PAGE_TAB_LIST:
+ case ELM_ATSPI_ROLE_PAGE_TAB:
+ case ELM_ATSPI_ROLE_SPIN_BUTTON:
+ case ELM_ATSPI_ROLE_INPUT_METHOD_WINDOW:
+ case ELM_ATSPI_ROLE_EMBEDDED:
+ case ELM_ATSPI_ROLE_INVALID:
+ case ELM_ATSPI_ROLE_NOTIFICATION:
+ case ELM_ATSPI_ROLE_DATE_EDITOR:
+ return EINA_FALSE;
+ default:
+ break;
+ }
+
+ return EINA_TRUE;
+}
+
+static Eo *
+_child_object_at_point_get(Eo *obj, int x, int y)
+{
+ Eina_List *l, *l_next, *children, *valid_children = NULL;
+ Eo *child;
+ Eo *target;
+ int count;
+
+ eo_do(obj, children = elm_interface_atspi_accessible_children_get());
+
+ EINA_LIST_FOREACH(children, l, child)
+ {
+ if (_is_inside(child, x, y))
+ valid_children = eina_list_append(valid_children, child);
+ }
+
+ EINA_LIST_FOREACH_SAFE(valid_children, l, l_next, child)
+ {
+ eo_do(child, children = elm_interface_atspi_accessible_children_get());
+
+ /* do not use unacceptable leaf node */
+ if (!_elm_widget_atspi_role_acceptable_check(child) &&
+ eina_list_count(children) == 0)
+ valid_children = eina_list_remove_list(valid_children, l);
+ }
+
+ count = eina_list_count(valid_children);
+ if (count > 0)
+ {
+ valid_children = eina_list_sort(valid_children, -1, _sort_by_size);
+ target = eina_list_nth(valid_children, 0);
+
+ return _child_object_at_point_get(target, x, y);
+ }
+
+ return obj;
+}
+
+static Eina_Bool
+_acceptable_child_is(Eo *obj)
+{
+ Elm_Atspi_Role role;
+ Eina_List *children;
+ Elm_Atspi_State_Set ss;
+
+ eo_do(obj, role = elm_interface_atspi_accessible_role_get());
+ switch (role)
+ {
+ case ELM_ATSPI_ROLE_IMAGE:
+ case ELM_ATSPI_ROLE_ICON:
+ /* remove unacceptable leaf node */
+ eo_do(obj, children = elm_interface_atspi_accessible_children_get());
+ if (!children) return EINA_FALSE;
+ break;
+
+ case ELM_ATSPI_ROLE_PANEL:
+ /* remove closed panel fron children list */
+ eo_do(obj, ss = elm_interface_atspi_accessible_state_set_get());
+ if (!STATE_TYPE_GET(ss, ELM_ATSPI_STATE_SHOWING)) return EINA_FALSE;
+ break;
+
+ default:
+ break;
+ }
+
+ return EINA_TRUE;
+}
+
static Eo *
_accessible_at_point_top_down_get(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eina_Bool screen_coords, int x, int y)
{
EINA_LIST_FOREACH(children, l2, child)
{
- if (_is_inside(child, x, y))
+ if (_is_inside(child, x, y) && _acceptable_child_is(child))
valid_children = eina_list_append(valid_children, child);
}
+
+ /* If there is only one valid child at point, then return it.
+ The evas_tree_objects_at_xy_get could not find proper object,
+ if application does not have well aligned objects. */
+ if (eina_list_count(valid_children) == 1)
+ {
+ eina_list_free(children);
+ child = eina_list_nth(valid_children, 0);
+ return child;
+ }
+
/* Get evas_object stacked at given x,y coordinates starting from top */
Eina_List *stack = evas_tree_objects_at_xy_get(evas_object_evas_get(obj), NULL, x, y);
/* Foreach stacked object starting from top */
/* Foreach at-spi valid children traverse stack_item evas_objects hierarchy */
EINA_LIST_FOREACH(valid_children, l2, child)
{
- Elm_Atspi_Role role;
- eo_do(child, role = elm_interface_atspi_accessible_role_get());
- if (role == ELM_ATSPI_ROLE_REDUNDANT_OBJECT)
- {
- /* The redundant object ignores */
- continue;
- }
/* Compare object used to compare with stacked evas objects */
compare_obj = child;
/* In case of widget_items compare should be different then elm_widget_ item object */
{
Elm_Widget_Item_Data *id = eo_data_scope_get(child, ELM_WIDGET_ITEM_CLASS);
compare_obj = id->view;
+ if (TIZEN_PROFILE_WEARABLE)
+ {
+ Eo* it_view = evas_object_image_source_get(stack_item);
+ if (it_view && it_view == compare_obj)
+ {
+ eina_list_free(children);
+ eina_list_free(stack);
+ return child;
+ }
+ }
}
/* In case of access object compare should be 'wrapped' evas_object */
if (eo_isa(child, ELM_ACCESS_CLASS))
{
Elm_Access_Info *info = _elm_access_info_get(child);
+ if (!info) continue;
compare_obj = info->part_object;
}
/* In case of widget is registerd by elm_access_object_register */
static int _sort_by_repeat_events(const void *data1, const void *data2)
{
+ Evas_Object *ao1, *ao2;
Eina_Bool repeat1, repeat2;
+ ao1 = elm_access_object_get(data1);
+ ao2 = elm_access_object_get(data2);
+
repeat1 = evas_object_repeat_events_get(data1);
repeat2 = evas_object_repeat_events_get(data2);
- if (repeat1 != repeat2 && repeat1 == EINA_TRUE) return 1;
+ if (repeat1 != repeat2)
+ {
+ if (repeat1 && !ao1) return 1;
+ }
+ else
+ {
+ if (repeat1 && !ao1 && ao2) return 1;
+ }
+
return -1;
}
+static Eo *_item_at_point_get(Evas_Object *obj, int x, int y)
+{
+ Eo *child;
+ Eina_List *l, *children;
+
+ eo_do(obj, children = elm_interface_atspi_accessible_children_get());
+
+ EINA_LIST_FOREACH(children, l, child)
+ {
+ if (_is_inside(child, x, y)) return child;
+ }
+
+ ERR("No child at point (%d, %d) on object %p", x, y, obj);
+ return NULL;
+}
+
EOLIAN static Eo *
_elm_widget_elm_interface_atspi_component_accessible_at_point_get(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eina_Bool screen_coords, int x, int y)
{
Eina_List *l;
Evas_Object *stack_item;
- if(strcmp("Elm_Win", eo_class_name_get(eo_class_get(obj))))
+ if(strcmp("Elm_Win", eo_class_name_get(eo_class_get(obj))) &&
+ strcmp("Elm_Popup", eo_class_name_get(eo_class_get(obj))) &&
+ strcmp("Elm_Panel", eo_class_name_get(eo_class_get(obj))))
return _accessible_at_point_top_down_get(obj, _pd, screen_coords, x, y);
_coordinate_system_based_point_translate(obj, screen_coords, &x, &y);
Evas_Object *smart_parent = stack_item;
while (smart_parent)
{
+ /* If parent equals to obj, it is not necessary to go upper.
+ So the top down logic would be better than NULL return. */
+ if (smart_parent == obj)
+ return _accessible_at_point_top_down_get(obj, _pd, screen_coords, x, y);
+
Evas_Object *ao = elm_access_object_get(smart_parent);
if (ao) return ao;
if (eo_isa(smart_parent, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
{
Eina_Bool acceptable = EINA_FALSE;
-
+ Eo *item_child;
Elm_Atspi_Role role;
eo_do(smart_parent, role = elm_interface_atspi_accessible_role_get());
switch (role)
DBG("Go for parent: %s (%p)\n", evas_object_type_get(smart_parent), smart_parent);
break;
+ case ELM_ATSPI_ROLE_LIST:
+ item_child = _item_at_point_get(smart_parent, x, y);
+ if (TIZEN_PROFILE_WEARABLE)
+ {
+ item_child = _child_object_at_point_get(item_child, x, y);
+ return item_child;
+ }
+ return item_child;
+ break;
+
default:
acceptable = EINA_TRUE;
break;
smart_parent = _parent_get(smart_parent);
}
}
- return NULL;
+ return _accessible_at_point_top_down_get(obj, _pd, screen_coords, x, y);
}
//
{ r2, g2, b2, a2 },
{ r3, g3, b3, a3 } };
+ if (!color_class) return EINA_FALSE;
+
buf = _elm_widget_edje_class_get(eo_class_get(obj), NULL, color_class);
#define TEMP_COLOR(x, y) \
Eina_Bool int_ret = EINA_TRUE;
Eina_Stringshare *buf;
- buf = _elm_widget_edje_class_get(eo_class_get(obj), NULL, color_class);
+ if (!color_class) return EINA_FALSE;
+
+ buf = _elm_widget_edje_class_get(eo_class_get(obj), elm_widget_style_get(obj), color_class);
int_ret &= edje_object_color_class_get(edje, buf,
r, g, b, a,
return int_ret;
}
+EOLIAN void
+_elm_widget_class_color_del(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, const char *color_class)
+{
+ Eina_Stringshare *buf;
+
+ if (!eo_isa(obj, ELM_LAYOUT_CLASS)) return;
+
+ buf = _elm_widget_edje_class_get(eo_class_get(obj), NULL, color_class);
+ edje_object_color_class_del(sd->resize_obj, buf);
+ eina_stringshare_del(buf);
+}
+
+EOLIAN void
+_elm_widget_class_color_clear(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
+{
+ if (!eo_isa(obj, ELM_LAYOUT_CLASS)) return;
+ edje_object_color_class_clear(sd->resize_obj);
+}
+
#define ELM_COLOR_CLASS_UPDATE(obj, hash, cond) \
Evas_Object *edje = NULL; \
Eina_Iterator *itr; \
{
ELM_COLOR_CLASS_GET(obj, r3, g3, b3, a3);
}
+
+static Evas_Object *
+_elm_widget_item_edje_get(Eo *obj, Elm_Widget_Item_Data *sd)
+{
+ if (!sd)
+ sd = eo_data_scope_get(obj, ELM_WIDGET_ITEM_CLASS);
+
+ if (eo_isa(sd->view, ELM_LAYOUT_CLASS))
+ return elm_layout_edje_get(sd->view);
+ else if (eo_isa(sd->view, EDJE_OBJECT_CLASS))
+ return sd->view;
+
+ return NULL;
+}
+
+EOLIAN void
+_elm_widget_item_class_color_del(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd, const char *color_class)
+{
+ Eina_Stringshare *buf;
+ Evas_Object *edje;
+ Edje_Color_Class *cc = NULL;
+
+ if (!color_class) return;
+
+ buf = _elm_widget_edje_class_get(eo_class_get(obj), NULL, color_class);
+ eina_hash_del(sd->color_classes, buf, cc);
+
+ edje = _elm_widget_item_edje_get(obj, sd);
+ if (edje)
+ edje_object_color_class_del(edje, buf);
+
+ eina_stringshare_del(buf);
+}
+
+EOLIAN void
+_elm_widget_item_class_color_clear(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd)
+{
+ Evas_Object *edje;
+ ELM_SAFE_FREE(sd->color_classes, eina_hash_free);
+
+ edje = _elm_widget_item_edje_get(obj, sd);
+ if (!edje) return;
+
+ edje_object_color_class_clear(edje);
+}
//
/* TIZEN_ONLY(20161025): Apply color_class parent-child relationship */