diff options
author | Mike Blumenkrantz <zmike@samsung.com> | 2018-08-13 15:07:31 +0900 |
---|---|---|
committer | Jaehyun Cho <jae_hyun.cho@samsung.com> | 2018-08-13 15:07:31 +0900 |
commit | a8421fc0c00238db476eaabd6115836adf1078d5 (patch) | |
tree | b99831e32a6eb8c4382011b881c3a381d197a6e3 | |
parent | c77ba1672e19133448d2dcd9606b5f19c36a6ceb (diff) | |
download | efl-a8421fc0c00238db476eaabd6115836adf1078d5.tar.gz |
elm/naviframe: implement invalidate method for naviframe items
Summary:
move most of the _item_free() calls to the invalidate method and unset some
delete callbacks on content items to avoid invalid calls during deletion
calling any of this during the object destructor is invalid because the parent
object can no longer be accessed at this time
fix T7236
Reviewers: Jaehyun_Cho
Reviewed By: Jaehyun_Cho
Subscribers: #reviewers, stefan_schmidt, cedric, #committers
Tags: #efl_widgets
Maniphest Tasks: T7236
Differential Revision: https://phab.enlightenment.org/D6759
-rw-r--r-- | src/lib/elementary/elc_naviframe.c | 137 | ||||
-rw-r--r-- | src/lib/elementary/elm_naviframe_item.eo | 1 |
2 files changed, 75 insertions, 63 deletions
diff --git a/src/lib/elementary/elc_naviframe.c b/src/lib/elementary/elc_naviframe.c index 1777a73576..f8fbf376f4 100644 --- a/src/lib/elementary/elc_naviframe.c +++ b/src/lib/elementary/elc_naviframe.c @@ -177,44 +177,17 @@ static void _item_free(Elm_Naviframe_Item_Data *it) { Eina_Inlist *l; - Elm_Naviframe_Content_Item_Pair *content_pair; Elm_Naviframe_Text_Item_Pair *text_pair; - ELM_NAVIFRAME_DATA_GET(WIDGET(it), sd); - eina_stringshare_del(it->title_label); eina_stringshare_del(it->subtitle_label); - EINA_INLIST_FOREACH_SAFE(it->content_list, l, content_pair) - { - if (content_pair->content) - { - evas_object_event_callback_del(content_pair->content, - EVAS_CALLBACK_DEL, - _title_content_del); - evas_object_del(content_pair->content); - } - eina_stringshare_del(content_pair->part); - free(content_pair); - } + EINA_INLIST_FOREACH_SAFE(it->text_list, l, text_pair) { eina_stringshare_del(text_pair->part); free(text_pair); } - - if (it->content) - { - if ((sd->preserve) && (!sd->on_deletion)) - { - /* so that elm does not delete the contents with the item's - * view after the destructor */ - elm_object_part_content_unset(VIEW(it), CONTENT_PART); - evas_object_event_callback_del - (it->content, EVAS_CALLBACK_DEL, _item_content_del_cb); - evas_object_hide(it->content); - } - } } static void @@ -574,46 +547,12 @@ _elm_naviframe_item_efl_object_destructor(Eo *eo_item, Elm_Naviframe_Item_Data * { Eina_List *l; Elm_Naviframe_Op *nfo; - Elm_Naviframe_Item_Data *nit = it, *prev_it = NULL; - Eina_Bool top; + Elm_Naviframe_Item_Data *nit = it; ELM_NAVIFRAME_DATA_GET(WIDGET(nit), sd); nit->delete_me = EINA_TRUE; - top = (eo_item == elm_naviframe_top_item_get(WIDGET(nit))); - if (evas_object_data_get(VIEW(nit), "out_of_list")) - goto end; - - sd->stack = eina_inlist_remove(sd->stack, EINA_INLIST_GET(nit)); - - if (top && !sd->on_deletion) /* must raise another one */ - { - if (sd->stack && sd->stack->last) - prev_it = EINA_INLIST_CONTAINER_GET(sd->stack->last, - Elm_Naviframe_Item_Data); - if (!prev_it) - { - elm_widget_tree_unfocusable_set(VIEW(nit), EINA_TRUE); - goto end; - } - - elm_widget_tree_unfocusable_set(VIEW(prev_it), EINA_FALSE); - elm_widget_tree_unfocusable_set(VIEW(nit), EINA_TRUE); - - if (sd->freeze_events) - evas_object_freeze_events_set(VIEW(prev_it), EINA_FALSE); - _resize_object_reset(WIDGET(prev_it), prev_it); - evas_object_show(VIEW(prev_it)); - - _prev_page_focus_recover(prev_it); - - elm_object_signal_emit(VIEW(prev_it), "elm,state,visible", "elm"); - - efl_event_callback_legacy_call(WIDGET(prev_it), ELM_NAVIFRAME_EVENT_ITEM_ACTIVATED, EO_OBJ(prev_it)); - } - -end: // This should not happen, but just in case and by security // make sure there is no more reference to this item. EINA_LIST_FOREACH(sd->ops, l, nfo) @@ -1247,6 +1186,78 @@ _access_prev_btn_info_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED) return strdup(E_("Back")); } +EOLIAN static void +_elm_naviframe_item_efl_object_invalidate(Eo *eo_item, Elm_Naviframe_Item_Data *it) +{ + Elm_Naviframe_Item_Data *prev_it = NULL; + Elm_Naviframe_Content_Item_Pair *content_pair; + Eina_Inlist *l; + + ELM_NAVIFRAME_DATA_GET(WIDGET(it), sd); + if (it->title_prev_btn) + evas_object_event_callback_del(it->title_prev_btn, EVAS_CALLBACK_DEL, _item_title_prev_btn_del_cb); + if (it->title_next_btn) + evas_object_event_callback_del(it->title_next_btn, EVAS_CALLBACK_DEL, _item_title_next_btn_del_cb); + if (it->title_icon) + evas_object_event_callback_del(it->title_icon, EVAS_CALLBACK_DEL, _item_title_icon_del_cb); + EINA_INLIST_FOREACH_SAFE(it->content_list, l, content_pair) + { + if (content_pair->content) + { + /* content object will be destroyed naturally */ + evas_object_event_callback_del(content_pair->content, + EVAS_CALLBACK_DEL, + _title_content_del); + evas_object_del(content_pair->content); + } + eina_stringshare_del(content_pair->part); + free(content_pair); + } + if (it->content) + { + evas_object_event_callback_del(it->content, EVAS_CALLBACK_DEL, _item_content_del_cb); + if ((sd->preserve) && (!sd->on_deletion)) + { + /* so that elm does not delete the contents with the item's + * view after the destructor */ + elm_object_part_content_unset(VIEW(it), CONTENT_PART); + evas_object_hide(it->content); + } + } + if (evas_object_data_get(VIEW(it), "out_of_list")) + goto end; + + sd->stack = eina_inlist_remove(sd->stack, EINA_INLIST_GET(it)); + + if ((elm_naviframe_top_item_get(WIDGET(it)) == eo_item) && !sd->on_deletion) /* must raise another one */ + { + if (sd->stack && sd->stack->last) + prev_it = EINA_INLIST_CONTAINER_GET(sd->stack->last, + Elm_Naviframe_Item_Data); + if (!prev_it) + { + elm_widget_tree_unfocusable_set(VIEW(it), EINA_TRUE); + goto end; + } + + elm_widget_tree_unfocusable_set(VIEW(prev_it), EINA_FALSE); + elm_widget_tree_unfocusable_set(VIEW(it), EINA_TRUE); + + if (sd->freeze_events) + evas_object_freeze_events_set(VIEW(prev_it), EINA_FALSE); + _resize_object_reset(WIDGET(prev_it), prev_it); + evas_object_show(VIEW(prev_it)); + + _prev_page_focus_recover(prev_it); + + elm_object_signal_emit(VIEW(prev_it), "elm,state,visible", "elm"); + + efl_event_callback_legacy_call(WIDGET(prev_it), ELM_NAVIFRAME_EVENT_ITEM_ACTIVATED, EO_OBJ(prev_it)); + } +end: + efl_invalidate(efl_super(eo_item, ELM_NAVIFRAME_ITEM_CLASS)); +} + EOLIAN static Eo * _elm_naviframe_item_efl_object_constructor(Eo *eo_item, Elm_Naviframe_Item_Data *it) { diff --git a/src/lib/elementary/elm_naviframe_item.eo b/src/lib/elementary/elm_naviframe_item.eo index 3bfceed416..15c94c9f7b 100644 --- a/src/lib/elementary/elm_naviframe_item.eo +++ b/src/lib/elementary/elm_naviframe_item.eo @@ -66,6 +66,7 @@ class Elm.Naviframe.Item(Elm.Widget.Item, Efl.Ui.Legacy) } implements { Efl.Object.constructor; + Efl.Object.invalidate; Efl.Object.destructor; Elm.Widget.Item.signal_emit; Elm.Widget.Item.part_text { get; set; } |