forked from enlightenment/efl
fix hide/del bug if thumb generation was pending, reuse objects if possible.
As spotted by Brian, we were not cancelling the thumbnail generation on hide/delete, when the generation finished garbage would be used and we'd segv. This commit fixes this, also removing the useless is_generating, as it can be interpreted from wd->id (-1 is not generating). As an optimization, we now just delete the view object if it changed between image and edje (video), otherwise we reuse it. SVN revision: 50268
This commit is contained in:
parent
974c982095
commit
9d7be6a1f4
|
@ -51,7 +51,7 @@ struct _Widget_Data
|
||||||
Elm_Thumb_Animation_Setting anim_setting;
|
Elm_Thumb_Animation_Setting anim_setting;
|
||||||
Eina_Bool on_hold : 1;
|
Eina_Bool on_hold : 1;
|
||||||
Eina_Bool is_video : 1;
|
Eina_Bool is_video : 1;
|
||||||
Eina_Bool is_generating : 1;
|
Eina_Bool was_video : 1;
|
||||||
Eina_Bool keep_aspect : 1;
|
Eina_Bool keep_aspect : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -93,10 +93,15 @@ static void
|
||||||
_del_hook(Evas_Object *obj)
|
_del_hook(Evas_Object *obj)
|
||||||
{
|
{
|
||||||
Widget_Data *wd = elm_widget_data_get(obj);
|
Widget_Data *wd = elm_widget_data_get(obj);
|
||||||
|
|
||||||
|
#ifdef HAVE_ELEMENTARY_ETHUMB
|
||||||
|
if (wd->id >= 0)
|
||||||
|
ethumb_client_generate_cancel(_elm_ethumb_client, wd->id, NULL, NULL, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
eina_stringshare_del(wd->file);
|
eina_stringshare_del(wd->file);
|
||||||
eina_stringshare_del(wd->key);
|
eina_stringshare_del(wd->key);
|
||||||
if (wd->eeh)
|
if (wd->eeh) ecore_event_handler_del(wd->eeh);
|
||||||
ecore_event_handler_del(wd->eeh);
|
|
||||||
free(wd);
|
free(wd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,26 +148,34 @@ _mouse_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_finished_thumb(Widget_Data *wd, int id, const char *thumb_path, const char *thumb_key)
|
_finished_thumb(Widget_Data *wd, const char *thumb_path, const char *thumb_key)
|
||||||
{
|
{
|
||||||
|
Eina_Bool new_view = EINA_FALSE;
|
||||||
int r;
|
int r;
|
||||||
Evas *evas;
|
Evas *evas;
|
||||||
|
|
||||||
evas = evas_object_evas_get(wd->self);
|
evas = evas_object_evas_get(wd->self);
|
||||||
if (wd->children.view)
|
if ((wd->children.view) && (wd->is_video ^ wd->was_video))
|
||||||
evas_object_del(wd->children.view);
|
{
|
||||||
wd->children.view = NULL;
|
evas_object_del(wd->children.view);
|
||||||
wd->id = id;
|
wd->children.view = NULL;
|
||||||
|
}
|
||||||
if (wd->is_video &&
|
wd->was_video = wd->is_video;
|
||||||
ethumb_client_format_get(_elm_ethumb_client) == ETHUMB_THUMB_EET)
|
|
||||||
|
if ((wd->is_video) &&
|
||||||
|
(ethumb_client_format_get(_elm_ethumb_client) == ETHUMB_THUMB_EET))
|
||||||
{
|
{
|
||||||
wd->children.view = edje_object_add(evas);
|
|
||||||
if (!wd->children.view)
|
if (!wd->children.view)
|
||||||
{
|
{
|
||||||
ERR("could not create edje object");
|
wd->children.view = edje_object_add(evas);
|
||||||
goto err;
|
if (!wd->children.view)
|
||||||
|
{
|
||||||
|
ERR("could not create edje object");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
new_view = EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!edje_object_file_set(wd->children.view, thumb_path, "movie/thumb"))
|
if (!edje_object_file_set(wd->children.view, thumb_path, "movie/thumb"))
|
||||||
{
|
{
|
||||||
ERR("could not set file=%s key=%s for %s", thumb_path, thumb_key,
|
ERR("could not set file=%s key=%s for %s", thumb_path, thumb_key,
|
||||||
|
@ -172,12 +185,17 @@ _finished_thumb(Widget_Data *wd, int id, const char *thumb_path, const char *thu
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wd->children.view = evas_object_image_filled_add(evas);
|
|
||||||
if (!wd->children.view)
|
if (!wd->children.view)
|
||||||
{
|
{
|
||||||
ERR("could not create image object");
|
wd->children.view = evas_object_image_filled_add(evas);
|
||||||
goto err;
|
if (!wd->children.view)
|
||||||
|
{
|
||||||
|
ERR("could not create image object");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
new_view = EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
evas_object_image_file_set(wd->children.view, thumb_path, thumb_key);
|
evas_object_image_file_set(wd->children.view, thumb_path, thumb_key);
|
||||||
r = evas_object_image_load_error_get(wd->children.view);
|
r = evas_object_image_load_error_get(wd->children.view);
|
||||||
if (r != EVAS_LOAD_ERROR_NONE)
|
if (r != EVAS_LOAD_ERROR_NONE)
|
||||||
|
@ -187,7 +205,7 @@ _finished_thumb(Widget_Data *wd, int id, const char *thumb_path, const char *thu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
elm_widget_sub_object_add(wd->self, wd->children.view);
|
if (new_view) elm_widget_sub_object_add(wd->self, wd->children.view);
|
||||||
edje_object_part_swallow(wd->children.frm, "elm.swallow.content",
|
edje_object_part_swallow(wd->children.frm, "elm.swallow.content",
|
||||||
wd->children.view);
|
wd->children.view);
|
||||||
eina_stringshare_replace(&(wd->thumb.file), thumb_path);
|
eina_stringshare_replace(&(wd->thumb.file), thumb_path);
|
||||||
|
@ -209,12 +227,14 @@ _finished_thumb_cb(void *data, Ethumb_Client *c __UNUSED__, int id, const char *
|
||||||
{
|
{
|
||||||
Widget_Data *wd = data;
|
Widget_Data *wd = data;
|
||||||
|
|
||||||
|
EINA_SAFETY_ON_FALSE_RETURN(wd->id == id);
|
||||||
|
wd->id = -1;
|
||||||
|
|
||||||
edje_object_signal_emit(wd->children.frm, EDJE_SIGNAL_PULSE_STOP, "elm");
|
edje_object_signal_emit(wd->children.frm, EDJE_SIGNAL_PULSE_STOP, "elm");
|
||||||
wd->is_generating = EINA_FALSE;
|
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
_finished_thumb(wd, id, thumb_path, thumb_key);
|
_finished_thumb(wd, thumb_path, thumb_key);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,13 +250,14 @@ _thumb_apply(Widget_Data *wd)
|
||||||
if (ethumb_client_thumb_exists(_elm_ethumb_client))
|
if (ethumb_client_thumb_exists(_elm_ethumb_client))
|
||||||
{
|
{
|
||||||
const char *thumb_path, *thumb_key;
|
const char *thumb_path, *thumb_key;
|
||||||
|
wd->id = -1;
|
||||||
ethumb_client_thumb_path_get(_elm_ethumb_client, &thumb_path,
|
ethumb_client_thumb_path_get(_elm_ethumb_client, &thumb_path,
|
||||||
&thumb_key);
|
&thumb_key);
|
||||||
_finished_thumb(wd, 0, thumb_path, thumb_key);
|
_finished_thumb(wd, thumb_path, thumb_key);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (ethumb_client_generate(_elm_ethumb_client, _finished_thumb_cb, wd,
|
else if ((wd->id = ethumb_client_generate
|
||||||
NULL) != -1)
|
(_elm_ethumb_client, _finished_thumb_cb, wd, NULL)) != -1)
|
||||||
{
|
{
|
||||||
edje_object_signal_emit(wd->children.frm, EDJE_SIGNAL_PULSE_START,
|
edje_object_signal_emit(wd->children.frm, EDJE_SIGNAL_PULSE_START,
|
||||||
"elm");
|
"elm");
|
||||||
|
@ -246,11 +267,11 @@ _thumb_apply(Widget_Data *wd)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
wd->id = -1;
|
||||||
edje_object_signal_emit(wd->children.frm, EDJE_SIGNAL_GENERATE_ERROR,
|
edje_object_signal_emit(wd->children.frm, EDJE_SIGNAL_GENERATE_ERROR,
|
||||||
"elm");
|
"elm");
|
||||||
evas_object_smart_callback_call(wd->self, SIG_GENERATE_ERROR, NULL);
|
evas_object_smart_callback_call(wd->self, SIG_GENERATE_ERROR, NULL);
|
||||||
}
|
}
|
||||||
wd->is_generating = EINA_FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
|
@ -282,20 +303,6 @@ _thumb_show_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void
|
||||||
_thumb_show(data);
|
_thumb_show(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
_cancel_cb(void *data, Eina_Bool success)
|
|
||||||
{
|
|
||||||
Widget_Data *wd = data;
|
|
||||||
|
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
wd->is_generating = EINA_FALSE;
|
|
||||||
edje_object_signal_emit(wd->children.frm, EDJE_SIGNAL_GENERATE_STOP,
|
|
||||||
"elm");
|
|
||||||
evas_object_smart_callback_call(wd->self, SIG_GENERATE_STOP, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_thumb_hide_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
|
_thumb_hide_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
|
||||||
{
|
{
|
||||||
|
@ -303,9 +310,17 @@ _thumb_hide_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void
|
||||||
|
|
||||||
evas_object_hide(wd->children.frm);
|
evas_object_hide(wd->children.frm);
|
||||||
|
|
||||||
if (wd->is_generating)
|
if (wd->id >= 0)
|
||||||
ethumb_client_generate_cancel(_elm_ethumb_client, wd->id, _cancel_cb, wd, NULL);
|
{
|
||||||
else if (wd->eeh)
|
ethumb_client_generate_cancel
|
||||||
|
(_elm_ethumb_client, wd->id, NULL, NULL, NULL);
|
||||||
|
wd->id = -1;
|
||||||
|
|
||||||
|
edje_object_signal_emit(wd->children.frm, EDJE_SIGNAL_GENERATE_STOP, "elm");
|
||||||
|
evas_object_smart_callback_call(wd->self, SIG_GENERATE_STOP, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wd->eeh)
|
||||||
{
|
{
|
||||||
ecore_event_handler_del(wd->eeh);
|
ecore_event_handler_del(wd->eeh);
|
||||||
wd->eeh = NULL;
|
wd->eeh = NULL;
|
||||||
|
@ -422,9 +437,10 @@ elm_thumb_add(Evas_Object *parent)
|
||||||
wd->eeh = NULL;
|
wd->eeh = NULL;
|
||||||
wd->children.align.x = 0.5;
|
wd->children.align.x = 0.5;
|
||||||
wd->children.align.y = 0.5;
|
wd->children.align.y = 0.5;
|
||||||
|
wd->id = -1;
|
||||||
wd->on_hold = EINA_FALSE;
|
wd->on_hold = EINA_FALSE;
|
||||||
wd->is_video = EINA_FALSE;
|
wd->is_video = EINA_FALSE;
|
||||||
wd->is_generating = EINA_FALSE;
|
wd->was_video = EINA_FALSE;
|
||||||
wd->keep_aspect = EINA_FALSE;
|
wd->keep_aspect = EINA_FALSE;
|
||||||
|
|
||||||
#ifdef HAVE_ELEMENTARY_ETHUMB
|
#ifdef HAVE_ELEMENTARY_ETHUMB
|
||||||
|
|
Loading…
Reference in New Issue