proper shutdown of entries.

* must disconnect connected callbacks, particularly those to
   canvas. The object we previously connect will die anyway, but
   canvas continues alive, dispatching its
   EVAS_CALLBACK_CANVAS_FOCUS_IN and EVAS_CALLBACK_CANVAS_FOCUS_OUT,
   causing nasty segmentation faults!

 * must call _edje_clean_objects() *AFTER* the entry is shut
   down. Otherwise ed->evas will be NULL and
   evas_event_callback_del_full() will fail. I left extra checks on
   those, since this call will return the given data (in our case
   "ed") and NULL when callback connection was not found.

 * flag existence of entries and if they were already initalized and
   shutdown before, avoid redoing such work.

This fixes a stupid crash that bugged editje for a while now.



SVN revision: 46263
This commit is contained in:
Gustavo Sverzut Barbieri 2010-02-17 23:43:31 +00:00
parent a50bb3acf8
commit 1ad4337878
4 changed files with 26 additions and 12 deletions

View File

@ -1532,6 +1532,12 @@ _evas_focus_out_cb(void *data, Evas *e, void *event_info)
void
_edje_entry_init(Edje *ed)
{
if (!ed->has_entries)
return;
if (ed->entries_inited)
return;
ed->entries_inited = EINA_TRUE;
evas_object_event_callback_add(ed->obj, EVAS_CALLBACK_FOCUS_IN, _edje_focus_in_cb, ed);
evas_object_event_callback_add(ed->obj, EVAS_CALLBACK_FOCUS_OUT, _edje_focus_out_cb, ed);
evas_object_event_callback_add(ed->obj, EVAS_CALLBACK_KEY_DOWN, _edje_key_down_cb, ed);
@ -1543,12 +1549,20 @@ _edje_entry_init(Edje *ed)
void
_edje_entry_shutdown(Edje *ed)
{
if (!ed->has_entries)
return;
if (!ed->entries_inited)
return;
ed->entries_inited = EINA_FALSE;
evas_object_event_callback_del(ed->obj, EVAS_CALLBACK_FOCUS_IN, _edje_focus_in_cb);
evas_object_event_callback_del(ed->obj, EVAS_CALLBACK_FOCUS_OUT, _edje_focus_out_cb);
evas_object_event_callback_del(ed->obj, EVAS_CALLBACK_KEY_DOWN, _edje_key_down_cb);
evas_object_event_callback_del(ed->obj, EVAS_CALLBACK_KEY_UP, _edje_key_up_cb);
evas_event_callback_del_full(ed->evas, EVAS_CALLBACK_CANVAS_FOCUS_IN, _evas_focus_in_cb, ed);
evas_event_callback_del_full(ed->evas, EVAS_CALLBACK_CANVAS_FOCUS_OUT, _evas_focus_out_cb, ed);
if (evas_event_callback_del_full(ed->evas, EVAS_CALLBACK_CANVAS_FOCUS_IN, _evas_focus_in_cb, ed) != ed)
ERR("could not unregister EVAS_CALLBACK_FOCUS_IN");
if (evas_event_callback_del_full(ed->evas, EVAS_CALLBACK_CANVAS_FOCUS_OUT, _evas_focus_out_cb, ed) != ed)
ERR("could not unregister EVAS_CALLBACK_FOCUS_OUT");
}
void

View File

@ -281,7 +281,6 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
Eina_List *parts = NULL;
Eina_List *old_swallows;
int group_path_started = 0;
int entries = 0;
ed = _edje_fetch(obj);
if (!ed) return 0;
@ -291,8 +290,6 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
(ed->group) && (!strcmp(group, ed->group)))
return 1;
//**//
_edje_entry_shutdown(ed);
old_swallows = _edje_swallows_collect(ed);
if (_edje_script_only(ed)) _edje_script_only_shutdown(ed);
@ -321,6 +318,8 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
_edje_textblock_styles_add(ed);
_edje_textblock_style_all_update(ed);
ed->has_entries = EINA_FALSE;
if (ed->collection)
{
if (ed->collection->script_only)
@ -529,7 +528,8 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
{
_edje_entry_real_part_init(rp);
entries++;
if (!ed->has_entries)
ed->has_entries = EINA_TRUE;
}
}
}
@ -777,14 +777,13 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
}
}
}
//**//
if (entries > 0) _edje_entry_init(ed);
_edje_entry_init(ed);
return 1;
}
else
return 0;
ed->load_error = EDJE_LOAD_ERROR_NONE;
if (entries > 0) _edje_entry_init(ed);
_edje_entry_init(ed);
return 1;
}
@ -834,6 +833,7 @@ _edje_file_del(Edje *ed)
ed->freeze_calc = 0;
_edje_freeze_calc_count--;
}
_edje_entry_shutdown(ed);
_edje_message_del(ed);
_edje_block_violate(ed);
_edje_var_shutdown(ed);

View File

@ -804,6 +804,8 @@ struct _Edje
unsigned int delete_me : 1;
unsigned int postponed : 1;
unsigned int freeze_calc : 1;
unsigned int has_entries : 1;
unsigned int entries_inited : 1;
#ifdef EDJE_CALC_CACHE
unsigned int text_part_change : 1;
unsigned int all_part_change : 1;

View File

@ -68,7 +68,6 @@ _edje_smart_add(Evas_Object *obj)
evas_object_geometry_get(obj, &(ed->x), &(ed->y), &(ed->w), &(ed->h));
ed->obj = obj;
_edje_edjes = eina_list_append(_edje_edjes, obj);
//**// _edje_entry_init(ed);
/*
{
Eina_List *l;
@ -93,14 +92,13 @@ _edje_smart_del(Evas_Object * obj)
ed = evas_object_smart_data_get(obj);
if (!ed) return;
_edje_block_violate(ed);
//**// _edje_entry_shutdown(ed);
ed->delete_me = 1;
_edje_clean_objects(ed);
_edje_edjes = eina_list_remove(_edje_edjes, obj);
evas_object_smart_data_set(obj, NULL);
if (_edje_script_only(ed)) _edje_script_only_shutdown(ed);
if (_edje_lua_script_only(ed)) _edje_lua_script_only_shutdown(ed);
_edje_file_del(ed);
_edje_clean_objects(ed);
_edje_unref(ed);
}