diff --git a/po/ChangeLog b/po/ChangeLog deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/po/LINGUAS b/po/LINGUAS index 0a418cc6ce..c508050b27 100644 --- a/po/LINGUAS +++ b/po/LINGUAS @@ -1,2 +1 @@ -ca cs da de el eo es fi fr gl hu it ja ko lt nl pl pt ru sl sr tr vi zh_CN - +ar az_IR ca cs da de el eo es fa fi fr gl he hu it ja ko_KR ko lt nl pl ps pt ru sl sr tr ur vi yi zh_CN diff --git a/src/bin/elementary/test_win_stack.c b/src/bin/elementary/test_win_stack.c index 72510d0e6c..6bff88efc4 100644 --- a/src/bin/elementary/test_win_stack.c +++ b/src/bin/elementary/test_win_stack.c @@ -14,7 +14,7 @@ static void _bt_popto(void *data, Evas_Object *obj, void *event_info); static void _bt_pressed(void *data, Evas_Object *obj, void *event_info); static Evas_Object * -_win_new(Evas_Object* parent, Evas_Object *stack_top, const char *title) +_win_new(Evas_Object* parent, const char *title) { Evas_Object *bg, *bx, *bt, *lb, *win; @@ -87,7 +87,7 @@ _bt_pressed(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUS level++; snprintf(buf, sizeof(buf), "Level %i", level); - win = _win_new(win, obj, buf); + win = _win_new(win, buf); efl_ui_win_stack_master_id_set(win, efl_ui_win_stack_id_get(data)); } diff --git a/src/lib/edje/edje_entry.c b/src/lib/edje/edje_entry.c index 14696182d1..92bc0df031 100644 --- a/src/lib/edje/edje_entry.c +++ b/src/lib/edje/edje_entry.c @@ -4400,7 +4400,10 @@ Eina_Bool _edje_text_cursor_coord_set(Edje_Real_Part *rp, Efl_Text_Cursor_Handle *c, Evas_Coord x, Evas_Coord y) { + if ((rp->type != EDJE_RP_TYPE_TEXT) || + (!rp->typedata.text)) return EINA_FALSE; Entry *en = rp->typedata.text->entry_data; + if (!en) return EINA_FALSE; if ((c == _cursor_get(rp, EDJE_CURSOR_SELECTION_BEGIN)) || (c == _cursor_get(rp, EDJE_CURSOR_SELECTION_END))) { diff --git a/src/lib/elementary/efl_datetime_manager.c b/src/lib/elementary/efl_datetime_manager.c index 24daa34217..7445b8cdee 100644 --- a/src/lib/elementary/efl_datetime_manager.c +++ b/src/lib/elementary/efl_datetime_manager.c @@ -22,10 +22,9 @@ typedef struct { Efl_Time time; char format[MAX_FORMAT_LEN]; + Eina_Bool init; } Efl_Datetime_Manager_Data; -Eina_Bool init = EINA_FALSE; - static void _time_init(Efl_Time *curr_time) { @@ -33,8 +32,6 @@ _time_init(Efl_Time *curr_time) t = time(NULL); localtime_r(&t, curr_time); - - init = EINA_TRUE; } static char * @@ -162,7 +159,8 @@ _efl_datetime_manager_value_set(Eo *obj EINA_UNUSED, Efl_Datetime_Manager_Data * EOLIAN static Efl_Time _efl_datetime_manager_value_get(const Eo *obj EINA_UNUSED, Efl_Datetime_Manager_Data *pd) { - if (!init) _time_init(&pd->time); + if (!pd->init) _time_init(&pd->time); + pd->init = EINA_TRUE; return pd->time; } diff --git a/src/lib/elementary/efl_ui_collection.c b/src/lib/elementary/efl_ui_collection.c index 43b1b19521..53afb10743 100644 --- a/src/lib/elementary/efl_ui_collection.c +++ b/src/lib/elementary/efl_ui_collection.c @@ -438,6 +438,9 @@ _efl_ui_collection_efl_object_invalidate(Eo *obj, Efl_Ui_Collection_Data *pd EIN while(pd->items) efl_del(pd->items->data); + // pan is given to edje, which reparents it, which forces us to manually deleting it + efl_del(pd->pan); + efl_invalidate(efl_super(obj, MY_CLASS)); } @@ -704,6 +707,7 @@ unregister_item(Eo *obj, Efl_Ui_Collection_Data *pd, Efl_Ui_Item *item) efl_event_callback_array_del(item, active_item(), obj); efl_ui_position_manager_entity_item_removed(pd->pos_man, id, item); efl_ui_item_container_set(item, NULL); + efl_canvas_group_member_remove(pd->pan, item); return EINA_TRUE; } diff --git a/src/lib/elementary/efl_ui_collection_view.c b/src/lib/elementary/efl_ui_collection_view.c index dcf8f91462..2598849f36 100644 --- a/src/lib/elementary/efl_ui_collection_view.c +++ b/src/lib/elementary/efl_ui_collection_view.c @@ -2072,6 +2072,10 @@ _efl_ui_collection_view_efl_object_invalidate(Eo *obj, _all_cleanup(obj, pd); + //pd pan is given to edje, which reparents it, which forces us to manually deleting it + if (pd->pan) + efl_del(pd->pan); + efl_invalidate(efl_super(obj, EFL_UI_COLLECTION_VIEW_CLASS)); } diff --git a/src/lib/elementary/efl_ui_internal_text_interactive.c b/src/lib/elementary/efl_ui_internal_text_interactive.c index 017f2a884b..a0bbba6469 100644 --- a/src/lib/elementary/efl_ui_internal_text_interactive.c +++ b/src/lib/elementary/efl_ui_internal_text_interactive.c @@ -158,21 +158,25 @@ Eina_Bool _entry_hide_visible_password(Eo *obj) { Eina_Bool b_ret = EINA_FALSE; - const Evas_Object_Textblock_Node_Format *node; + const Evas_Object_Textblock_Node_Format *node, *node_next; node = evas_textblock_node_format_first_get(obj); - for (; node; node = evas_textblock_node_format_next_get(node)) + + if (!node) return EINA_FALSE; + + do { + node_next = evas_textblock_node_format_next_get(node); const char *text = evas_textblock_node_format_text_get(node); if (text) { if (!strcmp(text, "+ password=off")) { - evas_textblock_node_format_remove_pair(obj, - (Evas_Object_Textblock_Node_Format *)node); + evas_textblock_node_format_remove_pair(obj, (Evas_Object_Textblock_Node_Format *)node); b_ret = EINA_TRUE; } } - } + node = node_next; + } while (node); return b_ret; } diff --git a/src/lib/elementary/efl_ui_pan.c b/src/lib/elementary/efl_ui_pan.c index 72e5c60a93..b86d68bdc6 100644 --- a/src/lib/elementary/efl_ui_pan.c +++ b/src/lib/elementary/efl_ui_pan.c @@ -110,7 +110,9 @@ _efl_ui_pan_efl_object_constructor(Eo *obj, Efl_Ui_Pan_Data *_pd EINA_UNUSED) EOLIAN static void _efl_ui_pan_efl_object_destructor(Eo *obj, Efl_Ui_Pan_Data *sd EINA_UNUSED) { - efl_content_set(obj, NULL); + /* our implementation is a little bit incomplete, efl_content_set(obj, NULL) does not delete the content, However, if we do that, list grid and scroller would fail, because the assume ownership of the content */ + Eo *content = efl_content_unset(obj); + efl_del(content); efl_destructor(efl_super(obj, MY_CLASS)); } diff --git a/src/lib/elementary/efl_ui_scroller.c b/src/lib/elementary/efl_ui_scroller.c index 92b99527bf..5b0eca2fa5 100644 --- a/src/lib/elementary/efl_ui_scroller.c +++ b/src/lib/elementary/efl_ui_scroller.c @@ -278,15 +278,23 @@ _efl_ui_scroller_efl_object_finalize(Eo *obj, return obj; } +EOLIAN static void +_efl_ui_scroller_efl_object_invalidate(Eo *obj, Efl_Ui_Scroller_Data *pd) +{ + // pan is given to edje, which reparents it, which forces us to manually deleting it + efl_event_callback_del(pd->pan_obj, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, + _efl_ui_scroller_pan_resized_cb, obj); + efl_del(pd->pan_obj); + pd->pan_obj = NULL; + + efl_invalidate(efl_super(obj, MY_CLASS)); +} + EOLIAN static void _efl_ui_scroller_efl_object_destructor(Eo *obj, Efl_Ui_Scroller_Data *sd) { efl_ui_scroll_connector_unbind(obj); - efl_event_callback_del(sd->pan_obj, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, - _efl_ui_scroller_pan_resized_cb, obj); - efl_del(sd->pan_obj); - sd->pan_obj = NULL; sd->smanager = NULL; efl_destructor(efl_super(obj, MY_CLASS)); diff --git a/src/lib/elementary/efl_ui_scroller.eo b/src/lib/elementary/efl_ui_scroller.eo index 22a99b8a80..46f256382d 100644 --- a/src/lib/elementary/efl_ui_scroller.eo +++ b/src/lib/elementary/efl_ui_scroller.eo @@ -24,6 +24,7 @@ class Efl.Ui.Scroller extends Efl.Ui.Layout_Base implements Efl.Object.constructor; Efl.Object.finalize; Efl.Object.destructor; + Efl.Object.invalidate; Efl.Content.content { get; set; } Efl.Content.content_unset; Efl.Canvas.Group.group_calculate; diff --git a/src/lib/elementary/efl_ui_spotlight_manager_plain.c b/src/lib/elementary/efl_ui_spotlight_manager_plain.c index 83aab8fcce..d9c52ab3db 100644 --- a/src/lib/elementary/efl_ui_spotlight_manager_plain.c +++ b/src/lib/elementary/efl_ui_spotlight_manager_plain.c @@ -90,6 +90,8 @@ EOLIAN static void _efl_ui_spotlight_manager_plain_efl_ui_spotlight_manager_content_del(Eo *obj, Efl_Ui_Spotlight_Manager_Plain_Data *pd, Efl_Gfx_Entity *subobj, int index EINA_UNUSED) { efl_canvas_group_member_remove(pd->container, subobj); + if (pd->current_content == subobj) + pd->current_content = NULL; _content_changed(obj, pd); } EOLIAN static void diff --git a/src/lib/elementary/efl_ui_spotlight_manager_stack.c b/src/lib/elementary/efl_ui_spotlight_manager_stack.c index b286d75eab..d7d6d94c62 100644 --- a/src/lib/elementary/efl_ui_spotlight_manager_stack.c +++ b/src/lib/elementary/efl_ui_spotlight_manager_stack.c @@ -105,6 +105,11 @@ EOLIAN static void _efl_ui_spotlight_manager_stack_efl_ui_spotlight_manager_content_del(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Manager_Stack_Data *pd, Efl_Gfx_Entity *subobj, int index) { efl_canvas_group_member_remove(pd->container, subobj); + for (int i = 0; i < 2; ++i) + { + if (pd->content[i] == subobj) + pd->content[i] = NULL; + } _update_ids(obj, pd, index); } diff --git a/src/lib/elementary/efl_ui_widget.c b/src/lib/elementary/efl_ui_widget.c index 010c9fa9b6..768d934fae 100644 --- a/src/lib/elementary/efl_ui_widget.c +++ b/src/lib/elementary/efl_ui_widget.c @@ -691,7 +691,8 @@ _obj_mouse_up(void *data, Evas_Event_Mouse_Up *ev = event_info; if (sd->still_in && (ev->flags == EVAS_BUTTON_NONE) && - (sd->focus_move_policy == ELM_FOCUS_MOVE_POLICY_CLICK)) + (sd->focus_move_policy == ELM_FOCUS_MOVE_POLICY_CLICK) && + !efl_invalidated_get(data)) elm_widget_focus_mouse_up_handle(evas_object_widget_parent_find(obj)); sd->still_in = EINA_FALSE; @@ -704,7 +705,8 @@ _obj_mouse_in(void *data, void *event_info EINA_UNUSED) { ELM_WIDGET_DATA_GET(data, sd); - if (sd->focus_move_policy == ELM_FOCUS_MOVE_POLICY_IN) + if (sd->focus_move_policy == ELM_FOCUS_MOVE_POLICY_IN && + !efl_invalidated_get(data)) elm_widget_focus_mouse_up_handle(evas_object_widget_parent_find(obj)); } diff --git a/src/lib/evas/canvas/efl_canvas_textblock.eo b/src/lib/evas/canvas/efl_canvas_textblock.eo index 5d38ecfe6c..2c00967374 100644 --- a/src/lib/evas/canvas/efl_canvas_textblock.eo +++ b/src/lib/evas/canvas/efl_canvas_textblock.eo @@ -558,7 +558,6 @@ class @beta Efl.Canvas.Textblock extends Efl.Canvas.Object implements Efl.Text, } events { changed: void; [[Called when canvas text changed ]] - attributes,changed: void; [[Called when attributes change]] layout,finished: void; [[Called when the object has been layed out]] style_insets,changed: void; [[Called when the property @.style_insets changed.]] } diff --git a/src/lib/evas/canvas/evas_focus.c b/src/lib/evas/canvas/evas_focus.c index e11df7887d..83678fc64a 100644 --- a/src/lib/evas/canvas/evas_focus.c +++ b/src/lib/evas/canvas/evas_focus.c @@ -223,6 +223,8 @@ _efl_canvas_object_seat_focus_add(Eo *eo_obj, return EINA_FALSE; MAGIC_CHECK_END(); + EINA_SAFETY_ON_FALSE_RETURN_VAL(!efl_invalidating_get(eo_obj) && !efl_invalidated_get(eo_obj), EINA_FALSE); + event_id = _evas_event_counter; if (seat) default_seat = _default_seat_get(eo_obj); else default_seat = seat = _default_seat_get(eo_obj); diff --git a/src/lib/evas/canvas/evas_object_textblock.c b/src/lib/evas/canvas/evas_object_textblock.c index 019af5382d..e68f70351a 100644 --- a/src/lib/evas/canvas/evas_object_textblock.c +++ b/src/lib/evas/canvas/evas_object_textblock.c @@ -7330,6 +7330,10 @@ _layout_done(Ctxt *c, Evas_Coord *w_ret, Evas_Coord *h_ret) c->o->obstacle_changed = EINA_FALSE; } + else + { + efl_event_callback_call(c->obj, EFL_CANVAS_TEXTBLOCK_EVENT_LAYOUT_FINISHED, NULL); + } } static Eina_Bool @@ -8510,7 +8514,6 @@ _efl_canvas_textblock_efl_text_markup_markup_set(Eo *eo_obj, Efl_Canvas_Textbloc { ASYNC_BLOCK; _evas_object_textblock_text_markup_set(eo_obj, o, text); - efl_event_callback_call(eo_obj, EFL_CANVAS_TEXTBLOCK_EVENT_CHANGED, NULL); } static void @@ -8525,6 +8528,7 @@ _evas_object_textblock_text_markup_prepend(Eo *eo_obj, /* Stop calls for _evas_textblock_changed for each cursor_text_append or cursor_format_append * this should be done once, when markup_prepend finished */ o->pause_change = EINA_TRUE; + if (text) { char *s, *p; @@ -8657,6 +8661,7 @@ _evas_object_textblock_text_markup_prepend(Eo *eo_obj, p++; } } + o->pause_change = EINA_FALSE; _evas_textblock_changed(o, eo_obj); } @@ -11377,7 +11382,7 @@ _evas_textblock_changed(Efl_Canvas_Textblock_Data *o, Evas_Object *eo_obj) If format changed we need to refit content again. If content already fitting then ignore fitting (fitting cause fall to this callback) */ - if (!fit_is_fitting(eo_obj)) + if (!fit_is_fitting(eo_obj) && o->fit_content_config.options != TEXTBLOCK_FIT_MODE_NONE) { fit_cache_clear(&o->fit_content_config, FIT_CACHE_ALL); fit_text_block(eo_obj); @@ -11406,6 +11411,7 @@ _evas_textblock_cursor_text_append(Efl_Text_Cursor_Handle *cur, const char *_tex int len = 0; if (!cur) return 0; + if (!_text || !(*_text)) return 0; Evas_Object_Protected_Data *obj = efl_data_scope_get(cur->obj, EFL_CANVAS_OBJECT_CLASS); evas_object_async_block(obj); text = eina_unicode_utf8_to_unicode(_text, &len); @@ -11465,7 +11471,10 @@ _evas_textblock_cursor_text_append(Efl_Text_Cursor_Handle *cur, const char *_tex _evas_textblock_cursors_update_offset(cur, cur->node, cur->pos, len); if (!o->pause_change) - _evas_textblock_changed(o, cur->obj); + { + _evas_textblock_changed(o, cur->obj); + efl_event_callback_call(cur->obj, EFL_CANVAS_TEXTBLOCK_EVENT_CHANGED, NULL); + } n->dirty = EINA_TRUE; free(text); @@ -14238,7 +14247,7 @@ evas_object_textblock_init(Evas_Object *eo_obj) co->obj = eo_obj; evas_object_textblock_text_markup_set(eo_obj, ""); - o->multiline = EINA_FALSE; + o->multiline = EINA_TRUE; #ifdef BIDI_SUPPORT o->inherit_paragraph_direction = EINA_TRUE; #endif @@ -15654,7 +15663,7 @@ void fit_style_update(Evas_Object *object, int i_font_size, Eina_Bool disable_el } } - _canvas_text_format_changed(object,o); + _canvas_text_format_changed(object,o); } static void @@ -15806,12 +15815,28 @@ _efl_canvas_textblock_efl_text_text_set(Eo *eo_obj, Efl_Canvas_Textblock_Data *o const char *text) { ASYNC_BLOCK; + const char *old_txt = efl_text_get(eo_obj); + Eina_Bool was_empty = (!old_txt || !(*old_txt)); + + // Nothing to do + if (was_empty && (!text || !(*text))) + return; + + /* + * Reduce changed events to one time emit only, in the appending phase + */ + efl_event_freeze(eo_obj); evas_object_textblock_text_markup_set(eo_obj, ""); - _cursor_text_append(o->cursor, text); + efl_event_thaw(eo_obj); + + if (text && *text) + _cursor_text_append(o->cursor, text); + else if(!was_empty) + efl_event_callback_call(eo_obj, EFL_CANVAS_TEXTBLOCK_EVENT_CHANGED, NULL); + if (eo_obj) { _evas_textblock_changed(o, eo_obj); - efl_event_callback_call(eo_obj, EFL_CANVAS_TEXTBLOCK_EVENT_CHANGED, NULL); } } diff --git a/src/tests/elementary/spec/efl_test_basics.c b/src/tests/elementary/spec/efl_test_basics.c index 0985adb43c..b14e18a568 100644 --- a/src/tests/elementary/spec/efl_test_basics.c +++ b/src/tests/elementary/spec/efl_test_basics.c @@ -66,6 +66,8 @@ EFL_START_TEST(no_leaking_canvas_object) Eina_Iterator *iter = eo_objects_iterator_new(); Eo *obj; + if (efl_isa(widget, EFL_UI_FLIP_CLASS)) return; //FIXME Flip needs more work for this. However, flip should be redone as a spotlight manager, When this is done, we can add these classes to the check here. + EINA_ITERATOR_FOREACH(iter, obj) { if (!efl_alive_get(obj)) continue; @@ -75,6 +77,12 @@ EFL_START_TEST(no_leaking_canvas_object) } eina_iterator_free(iter); + //Just overwrite the widget pointer, and expect errors, if any error is happening here, we are not interested in it, another testcase will take care of them + EXPECT_ERROR_START; + widget = efl_add(widget_klass, win); + expect_error_start = EINA_TRUE; + EXPECT_ERROR_END; + //now try to will those widgets if (efl_isa(widget, EFL_PACK_LINEAR_INTERFACE)) { @@ -105,7 +113,10 @@ EFL_START_TEST(no_leaking_canvas_object) if (!efl_alive_get(obj)) continue; if (!efl_isa(obj, EFL_CANVAS_OBJECT_CLASS)) continue; - ck_assert_ptr_ne(eina_list_data_find(not_invalidate, obj), NULL); + if (eina_list_data_find(not_invalidate, obj) == NULL) + { + ck_abort_msg("Leak detected %s Evas-Parent: %s", efl_debug_name_get(obj), efl_class_name_get(efl_canvas_object_render_parent_get(obj))); + } } eina_iterator_free(iter); @@ -113,6 +124,13 @@ EFL_START_TEST(no_leaking_canvas_object) } EFL_END_TEST + +EFL_START_TEST(no_err_on_creation) +{ + widget = efl_add(widget_klass, win); +} +EFL_END_TEST + EFL_START_TEST(no_err_on_shutdown) { efl_ref(widget); @@ -193,4 +211,5 @@ efl_ui_widget_behavior_test(TCase *tc) tcase_add_test(tc, no_leaking_canvas_object); tcase_add_test(tc, no_err_on_shutdown); tcase_add_test(tc, correct_visibility_setting); + tcase_add_test(tc, no_err_on_creation); } diff --git a/src/tests/evas/evas_test_textblock.c b/src/tests/evas/evas_test_textblock.c index 1a75153dd9..16fd38f437 100644 --- a/src/tests/evas/evas_test_textblock.c +++ b/src/tests/evas/evas_test_textblock.c @@ -4472,11 +4472,20 @@ EFL_START_TEST(efl_text) } EFL_END_TEST +static void +_increment_int_changed(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED) +{ + int *value = data; + (*value)++; +} + EFL_START_TEST(efl_canvas_textblock_cursor) { START_EFL_CANVAS_TEXTBLOCK_TEST(); int pos; + int changed_emit = 0; + efl_event_callback_add(txt, EFL_CANVAS_TEXTBLOCK_EVENT_CHANGED, _increment_int_changed, &changed_emit); const char *buf = "abcdefghij"; efl_text_set(txt, buf); fail_if(strcmp(efl_text_get(txt), buf)); @@ -4501,6 +4510,12 @@ EFL_START_TEST(efl_canvas_textblock_cursor) pos = efl_text_cursor_position_get(cursor1); ck_assert_int_eq(pos, 1); + efl_text_set(txt, ""); + efl_text_set(txt, ""); + efl_text_cursor_text_insert(cursor1, "aa"); + + ck_assert_int_eq(changed_emit, 3); + END_EFL_CANVAS_TEXTBLOCK_TEST(); } EFL_END_TEST