From fd8d41a2a6f1dc374932f18e69daf485c1cb5a3e Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Mon, 31 Oct 2016 18:23:08 +0900 Subject: [PATCH] e fm - fix popup to not crash by referring to possibly deleted data fm icon info is transient because fm icons are transient. files may get deleted, added or removed on the fly. keeping icon info around for things like the popup is asking for tyrouble and does create trouble. so look it up each time based on filename string. safe! this fixes T4716 and fixes T4798 (they are the same bug basically). --- src/bin/e_fm.c | 16 ++++++++++++++++ src/bin/e_fm.h | 1 + src/modules/fileman/e_fwin.c | 30 +++++++++++++++++++----------- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/bin/e_fm.c b/src/bin/e_fm.c index f19015744..ef8dad084 100644 --- a/src/bin/e_fm.c +++ b/src/bin/e_fm.c @@ -1513,6 +1513,22 @@ e_fm2_all_list_get(Evas_Object *obj) return list; } +E_API E_Fm2_Icon_Info * +e_fm2_icon_file_get(Evas_Object *obj, const char *file) +{ + Eina_List *list = NULL, *l; + E_Fm2_Icon *ic; + + EFM_SMART_CHECK(NULL); + if (!file) return; + EINA_LIST_FOREACH(sd->icons, l, ic) + { + if ((ic->info.file) && (!strcmp(ic->info.file, file))) + return &(ic->info); + } + return NULL; +} + E_API void e_fm2_deselect_all(Evas_Object *obj) { diff --git a/src/bin/e_fm.h b/src/bin/e_fm.h index 76b0b5fe4..aff1b72d2 100644 --- a/src/bin/e_fm.h +++ b/src/bin/e_fm.h @@ -169,6 +169,7 @@ E_API void e_fm2_config_set(Evas_Object *obj, E_Fm2_Config *cfg); E_API E_Fm2_Config *e_fm2_config_get(Evas_Object *obj); E_API Eina_List *e_fm2_selected_list_get(Evas_Object *obj); E_API Eina_List *e_fm2_all_list_get(Evas_Object *obj); +E_API E_Fm2_Icon_Info *e_fm2_icon_file_get(Evas_Object *obj, const char *file); E_API void e_fm2_select_set(Evas_Object *obj, const char *file, int select); E_API void e_fm2_deselect_all(Evas_Object *obj); E_API void e_fm2_file_show(Evas_Object *obj, const char *file); diff --git a/src/modules/fileman/e_fwin.c b/src/modules/fileman/e_fwin.c index 0082098f7..ae7a3c450 100644 --- a/src/modules/fileman/e_fwin.c +++ b/src/modules/fileman/e_fwin.c @@ -41,11 +41,11 @@ struct _E_Fwin const char *overlay_file; const char *scrollframe_file; const char *theme_file; + const char *over_file; Ecore_Timer *popup_timer; Ecore_Job *popup_del_job; Eina_List *popup_handlers; - E_Fm2_Icon_Info *popup_icon; Evas_Object *popup; Ecore_Timer *spring_timer; @@ -760,7 +760,8 @@ _e_fwin_icon_popup_handler(void *data) evas_object_event_callback_del(fwin->win, EVAS_CALLBACK_MOUSE_IN, (Evas_Object_Event_Cb)_e_fwin_icon_popup_handler); evas_object_event_callback_del(fwin->win, EVAS_CALLBACK_MOUSE_OUT, (Evas_Object_Event_Cb)_e_fwin_icon_popup_handler); E_FREE_LIST(fwin->popup_handlers, ecore_event_handler_del); - fwin->popup_icon = NULL; + if (fwin->over_file) eina_stringshare_del(fwin->over_file); + fwin->over_file = NULL; return ECORE_CALLBACK_RENEW; } @@ -788,6 +789,7 @@ _e_fwin_free(E_Fwin *fwin) if (fwin->overlay_file) eina_stringshare_del(fwin->overlay_file); if (fwin->scrollframe_file) eina_stringshare_del(fwin->scrollframe_file); if (fwin->theme_file) eina_stringshare_del(fwin->theme_file); + if (fwin->over_file) eina_stringshare_del(fwin->over_file); if (fwin->fad) { e_object_del(E_OBJECT(fwin->fad->dia)); @@ -820,13 +822,15 @@ _e_fwin_icon_hints(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *even E_Zone *zone; Evas_Object *edje; E_Fwin *fwin = data; + E_Fm2_Icon_Info *popup_icon; - if (!fwin->popup_icon) return; + popup_icon = e_fm2_icon_file_get(fwin->cur_page->fm_obj, fwin->over_file); + if (!popup_icon) return; zone = fwin->zone ?: e_comp_object_util_zone_get(fwin->win); - e_fm2_icon_geometry_get(fwin->popup_icon->ic, &x, &y, &w, &h); + e_fm2_icon_geometry_get(popup_icon->ic, &x, &y, &w, &h); if (fwin->zone) { - evas_object_geometry_get(fwin->popup_icon->fm, &fx, &fy, NULL, NULL); + evas_object_geometry_get(popup_icon->fm, &fx, &fy, NULL, NULL); fx -= zone->x, fy -= zone->y; } else @@ -872,10 +876,12 @@ _e_fwin_icon_popup(void *data) E_Zone *zone; char buf[4096]; int mw, mh; + E_Fm2_Icon_Info *popup_icon; fwin->popup_timer = NULL; - if (!fwin->popup_icon) return EINA_FALSE; - snprintf(buf, sizeof(buf), "%s/%s", e_fm2_real_path_get(fwin->cur_page->fm_obj), fwin->popup_icon->file); + popup_icon = e_fm2_icon_file_get(fwin->cur_page->fm_obj, fwin->over_file); + if (!popup_icon) return EINA_FALSE; + snprintf(buf, sizeof(buf), "%s/%s", e_fm2_real_path_get(fwin->cur_page->fm_obj), popup_icon->file); if (!ecore_file_can_read(buf)) return EINA_FALSE; if (fwin->popup) { @@ -891,8 +897,8 @@ _e_fwin_icon_popup(void *data) mh = zone->h * fileman_config->tooltip.size / 100.0; edje_object_part_text_set(bg, "e.text.title", - fwin->popup_icon->label ? - fwin->popup_icon->label : fwin->popup_icon->file); + popup_icon->label ? + popup_icon->label : popup_icon->file); list = e_widget_list_add(e_comp->evas, 0, 0); if (fwin->win) @@ -900,7 +906,7 @@ _e_fwin_icon_popup(void *data) o = e_widget_filepreview_add(e_comp->evas, mw, mh, 0); e_widget_filepreview_clamp_video_set(o, fileman_config->tooltip.clamp_size); - e_widget_filepreview_path_set(o, buf, fwin->popup_icon->mime); + e_widget_filepreview_path_set(o, buf, popup_icon->mime); e_widget_list_object_append(list, o, 1, 0, 0.5); edje_object_part_swallow(bg, "e.swallow.content", list); @@ -952,7 +958,9 @@ _e_fwin_icon_mouse_in(void *data, Evas_Object *obj EINA_UNUSED, void *event_info fwin->popup_timer = NULL; if (!fileman_config->tooltip.enable) return; fwin->popup_timer = ecore_timer_add(fileman_config->tooltip.delay, _e_fwin_icon_popup, fwin); - fwin->popup_icon = ici; + if (fwin->over_file) eina_stringshare_del(fwin->over_file); + fwin->over_file = NULL; + if (ici->file) fwin->over_file = eina_stringshare_add(ici->file); #ifndef HAVE_WAYLAND_ONLY if (!fwin->popup_handlers) {