summaryrefslogtreecommitdiff
path: root/src/lib/elementary/elc_naviframe.c
diff options
context:
space:
mode:
authorMike Blumenkrantz <zmike@samsung.com>2018-08-13 15:07:31 +0900
committerJaehyun Cho <jae_hyun.cho@samsung.com>2018-08-13 15:07:31 +0900
commita8421fc0c00238db476eaabd6115836adf1078d5 (patch)
treeb99831e32a6eb8c4382011b881c3a381d197a6e3 /src/lib/elementary/elc_naviframe.c
parentc77ba1672e19133448d2dcd9606b5f19c36a6ceb (diff)
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
Diffstat (limited to 'src/lib/elementary/elc_naviframe.c')
-rw-r--r--src/lib/elementary/elc_naviframe.c137
1 files changed, 74 insertions, 63 deletions
diff --git a/src/lib/elementary/elc_naviframe.c b/src/lib/elementary/elc_naviframe.c
index 1777a73..f8fbf37 100644
--- a/src/lib/elementary/elc_naviframe.c
+++ b/src/lib/elementary/elc_naviframe.c
@@ -177,44 +177,17 @@ static void
177_item_free(Elm_Naviframe_Item_Data *it) 177_item_free(Elm_Naviframe_Item_Data *it)
178{ 178{
179 Eina_Inlist *l; 179 Eina_Inlist *l;
180 Elm_Naviframe_Content_Item_Pair *content_pair;
181 Elm_Naviframe_Text_Item_Pair *text_pair; 180 Elm_Naviframe_Text_Item_Pair *text_pair;
182 181
183 ELM_NAVIFRAME_DATA_GET(WIDGET(it), sd);
184
185 eina_stringshare_del(it->title_label); 182 eina_stringshare_del(it->title_label);
186 eina_stringshare_del(it->subtitle_label); 183 eina_stringshare_del(it->subtitle_label);
187 184
188 EINA_INLIST_FOREACH_SAFE(it->content_list, l, content_pair) 185
189 {
190 if (content_pair->content)
191 {
192 evas_object_event_callback_del(content_pair->content,
193 EVAS_CALLBACK_DEL,
194 _title_content_del);
195 evas_object_del(content_pair->content);
196 }
197 eina_stringshare_del(content_pair->part);
198 free(content_pair);
199 }
200 EINA_INLIST_FOREACH_SAFE(it->text_list, l, text_pair) 186 EINA_INLIST_FOREACH_SAFE(it->text_list, l, text_pair)
201 { 187 {
202 eina_stringshare_del(text_pair->part); 188 eina_stringshare_del(text_pair->part);
203 free(text_pair); 189 free(text_pair);
204 } 190 }
205
206 if (it->content)
207 {
208 if ((sd->preserve) && (!sd->on_deletion))
209 {
210 /* so that elm does not delete the contents with the item's
211 * view after the destructor */
212 elm_object_part_content_unset(VIEW(it), CONTENT_PART);
213 evas_object_event_callback_del
214 (it->content, EVAS_CALLBACK_DEL, _item_content_del_cb);
215 evas_object_hide(it->content);
216 }
217 }
218} 191}
219 192
220static void 193static void
@@ -574,46 +547,12 @@ _elm_naviframe_item_efl_object_destructor(Eo *eo_item, Elm_Naviframe_Item_Data *
574{ 547{
575 Eina_List *l; 548 Eina_List *l;
576 Elm_Naviframe_Op *nfo; 549 Elm_Naviframe_Op *nfo;
577 Elm_Naviframe_Item_Data *nit = it, *prev_it = NULL; 550 Elm_Naviframe_Item_Data *nit = it;
578 Eina_Bool top;
579 551
580 ELM_NAVIFRAME_DATA_GET(WIDGET(nit), sd); 552 ELM_NAVIFRAME_DATA_GET(WIDGET(nit), sd);
581 553
582 nit->delete_me = EINA_TRUE; 554 nit->delete_me = EINA_TRUE;
583 555
584 top = (eo_item == elm_naviframe_top_item_get(WIDGET(nit)));
585 if (evas_object_data_get(VIEW(nit), "out_of_list"))
586 goto end;
587
588 sd->stack = eina_inlist_remove(sd->stack, EINA_INLIST_GET(nit));
589
590 if (top && !sd->on_deletion) /* must raise another one */
591 {
592 if (sd->stack && sd->stack->last)
593 prev_it = EINA_INLIST_CONTAINER_GET(sd->stack->last,
594 Elm_Naviframe_Item_Data);
595 if (!prev_it)
596 {
597 elm_widget_tree_unfocusable_set(VIEW(nit), EINA_TRUE);
598 goto end;
599 }
600
601 elm_widget_tree_unfocusable_set(VIEW(prev_it), EINA_FALSE);
602 elm_widget_tree_unfocusable_set(VIEW(nit), EINA_TRUE);
603
604 if (sd->freeze_events)
605 evas_object_freeze_events_set(VIEW(prev_it), EINA_FALSE);
606 _resize_object_reset(WIDGET(prev_it), prev_it);
607 evas_object_show(VIEW(prev_it));
608
609 _prev_page_focus_recover(prev_it);
610
611 elm_object_signal_emit(VIEW(prev_it), "elm,state,visible", "elm");
612
613 efl_event_callback_legacy_call(WIDGET(prev_it), ELM_NAVIFRAME_EVENT_ITEM_ACTIVATED, EO_OBJ(prev_it));
614 }
615
616end:
617 // This should not happen, but just in case and by security 556 // This should not happen, but just in case and by security
618 // make sure there is no more reference to this item. 557 // make sure there is no more reference to this item.
619 EINA_LIST_FOREACH(sd->ops, l, nfo) 558 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)
1247 return strdup(E_("Back")); 1186 return strdup(E_("Back"));
1248} 1187}
1249 1188
1189EOLIAN static void
1190_elm_naviframe_item_efl_object_invalidate(Eo *eo_item, Elm_Naviframe_Item_Data *it)
1191{
1192 Elm_Naviframe_Item_Data *prev_it = NULL;
1193 Elm_Naviframe_Content_Item_Pair *content_pair;
1194 Eina_Inlist *l;
1195
1196 ELM_NAVIFRAME_DATA_GET(WIDGET(it), sd);
1197 if (it->title_prev_btn)
1198 evas_object_event_callback_del(it->title_prev_btn, EVAS_CALLBACK_DEL, _item_title_prev_btn_del_cb);
1199 if (it->title_next_btn)
1200 evas_object_event_callback_del(it->title_next_btn, EVAS_CALLBACK_DEL, _item_title_next_btn_del_cb);
1201 if (it->title_icon)
1202 evas_object_event_callback_del(it->title_icon, EVAS_CALLBACK_DEL, _item_title_icon_del_cb);
1203 EINA_INLIST_FOREACH_SAFE(it->content_list, l, content_pair)
1204 {
1205 if (content_pair->content)
1206 {
1207 /* content object will be destroyed naturally */
1208 evas_object_event_callback_del(content_pair->content,
1209 EVAS_CALLBACK_DEL,
1210 _title_content_del);
1211 evas_object_del(content_pair->content);
1212 }
1213 eina_stringshare_del(content_pair->part);
1214 free(content_pair);
1215 }
1216 if (it->content)
1217 {
1218 evas_object_event_callback_del(it->content, EVAS_CALLBACK_DEL, _item_content_del_cb);
1219 if ((sd->preserve) && (!sd->on_deletion))
1220 {
1221 /* so that elm does not delete the contents with the item's
1222 * view after the destructor */
1223 elm_object_part_content_unset(VIEW(it), CONTENT_PART);
1224 evas_object_hide(it->content);
1225 }
1226 }
1227 if (evas_object_data_get(VIEW(it), "out_of_list"))
1228 goto end;
1229
1230 sd->stack = eina_inlist_remove(sd->stack, EINA_INLIST_GET(it));
1231
1232 if ((elm_naviframe_top_item_get(WIDGET(it)) == eo_item) && !sd->on_deletion) /* must raise another one */
1233 {
1234 if (sd->stack && sd->stack->last)
1235 prev_it = EINA_INLIST_CONTAINER_GET(sd->stack->last,
1236 Elm_Naviframe_Item_Data);
1237 if (!prev_it)
1238 {
1239 elm_widget_tree_unfocusable_set(VIEW(it), EINA_TRUE);
1240 goto end;
1241 }
1242
1243 elm_widget_tree_unfocusable_set(VIEW(prev_it), EINA_FALSE);
1244 elm_widget_tree_unfocusable_set(VIEW(it), EINA_TRUE);
1245
1246 if (sd->freeze_events)
1247 evas_object_freeze_events_set(VIEW(prev_it), EINA_FALSE);
1248 _resize_object_reset(WIDGET(prev_it), prev_it);
1249 evas_object_show(VIEW(prev_it));
1250
1251 _prev_page_focus_recover(prev_it);
1252
1253 elm_object_signal_emit(VIEW(prev_it), "elm,state,visible", "elm");
1254
1255 efl_event_callback_legacy_call(WIDGET(prev_it), ELM_NAVIFRAME_EVENT_ITEM_ACTIVATED, EO_OBJ(prev_it));
1256 }
1257end:
1258 efl_invalidate(efl_super(eo_item, ELM_NAVIFRAME_ITEM_CLASS));
1259}
1260
1250EOLIAN static Eo * 1261EOLIAN static Eo *
1251_elm_naviframe_item_efl_object_constructor(Eo *eo_item, Elm_Naviframe_Item_Data *it) 1262_elm_naviframe_item_efl_object_constructor(Eo *eo_item, Elm_Naviframe_Item_Data *it)
1252{ 1263{