From 353b5883474bdde6631c94c55dc941db0a2c75f3 Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Wed, 12 Dec 2012 09:59:53 +0000 Subject: [PATCH] 10k files.... ok! :) oh and fix a segv people will get when queue process timeout is hit... and reduce timeout to 0.01 sec :) SVN revision: 80746 --- src/bin/e_fm.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 117 insertions(+), 16 deletions(-) diff --git a/src/bin/e_fm.c b/src/bin/e_fm.c index f4862a7..152e5d6 100644 --- a/src/bin/e_fm.c +++ b/src/bin/e_fm.c @@ -42,6 +42,7 @@ struct _E_Fm2_Smart_Data { int id; Evas_Coord x, y, w, h, pw, ph; + Eina_List *icons; Evas_Object *obj; Evas_Object *clip; Evas_Object *underlay; @@ -84,7 +85,6 @@ struct _E_Fm2_Smart_Data const char *filename; } new_file; - Eina_List *icons; E_Fm2_Icon *last_selected; Eina_List *selected_icons; Eina_List *icons_place; @@ -108,6 +108,7 @@ struct _E_Fm2_Smart_Data signed short icon_size; /* -1 = unset */ E_Fm2_View_Flags view_flags; + E_Fm2_Icon *last_placed; E_Fm2_Config *config; const char *custom_theme; const char *custom_theme_content; @@ -152,6 +153,7 @@ struct _E_Fm2_Smart_Data Eina_Bool drop_all : 1; Eina_Bool drag : 1; Eina_Bool selecting : 1; + Eina_Bool toomany : 1; struct { int ox, oy; @@ -175,17 +177,17 @@ struct _E_Fm2_Region struct _E_Fm2_Icon { + int saved_x, saved_y; + double selected_time; E_Fm2_Smart_Data *sd; E_Fm2_Region *region; Evas_Coord x, y, w, h, min_w, min_h; Evas_Object *obj, *obj_icon; - int saved_x, saved_y; - int saved_rel; E_Menu *menu; E_Entry_Dialog *entry_dialog; Evas_Object *entry_widget; - Eio_File *eio; - Ecore_X_Window keygrab; + Eio_File *eio; + Ecore_X_Window keygrab; E_Config_Dialog *prop_dialog; E_Dialog *dialog; @@ -201,8 +203,8 @@ struct _E_Fm2_Icon Eina_Bool hidden : 1; // dropped into different dir } drag; - double selected_time; - + int saved_rel; + Eina_Bool realized : 1; Eina_Bool selected : 1; Eina_Bool last_selected : 1; @@ -211,6 +213,8 @@ struct _E_Fm2_Icon Eina_Bool down_sel : 1; Eina_Bool removable_state_change : 1; Eina_Bool thumb_failed : 1; + Eina_Bool queued : 1; + Eina_Bool inserted : 1; }; struct _E_Fm2_Finfo @@ -593,12 +597,32 @@ _e_fm2_file_is_desktop(const char *file) return (p) && (_e_fm2_ext_is_desktop(p + 1)); } +static inline Eina_Bool +_e_fm2_toomany_get(const E_Fm2_Smart_Data *sd) +{ + char mode; + + mode = sd->config->view.mode; + if (sd->view_mode > -1) mode = sd->view_mode; + if (((mode >= E_FM2_VIEW_MODE_CUSTOM_ICONS) && + (mode <= E_FM2_VIEW_MODE_CUSTOM_SMART_GRID_ICONS)) && + (eina_list_count(sd->icons) >= 500)) + return EINA_TRUE; + return EINA_FALSE; +} + static inline char _e_fm2_view_mode_get(const E_Fm2_Smart_Data *sd) { - if (sd->view_mode > -1) - return sd->view_mode; - return sd->config->view.mode; + char mode; + + mode = sd->config->view.mode; + if (sd->view_mode > -1) mode = sd->view_mode; + if ((sd->toomany) && + ((mode >= E_FM2_VIEW_MODE_CUSTOM_ICONS) && + (mode <= E_FM2_VIEW_MODE_CUSTOM_SMART_GRID_ICONS))) + return E_FM2_VIEW_MODE_GRID_ICONS; + return mode; } static inline Evas_Coord @@ -3321,6 +3345,8 @@ _e_fm2_file_add(Evas_Object *obj, const char *file, int unique, Eina_Stringshare { if (!file_rel) { + if (ic->queued) abort(); + if (ic->inserted) abort(); /* respekt da ordah! */ if (sd->order_file) sd->queue = eina_list_append(sd->queue, ic); @@ -3329,9 +3355,12 @@ _e_fm2_file_add(Evas_Object *obj, const char *file, int unique, Eina_Stringshare /* insertion sort it here to spread the sort load into idle time */ sd->queue = eina_list_sorted_insert(sd->queue, _e_fm2_cb_icon_sort, ic); } + ic->queued = EINA_TRUE; } else { + if (ic->queued) abort(); + if (ic->inserted) abort(); EINA_LIST_FOREACH(sd->icons, l, ic2) { if (ic2->info.file == file_rel) @@ -3340,11 +3369,15 @@ _e_fm2_file_add(Evas_Object *obj, const char *file, int unique, Eina_Stringshare sd->icons = eina_list_append_relative(sd->icons, ic, ic2); else sd->icons = eina_list_prepend_relative(sd->icons, ic, ic2); + ic->inserted = EINA_TRUE; break; } } - if (!l) - sd->icons = eina_list_append(sd->icons, ic); + if (ic->inserted) + { + sd->icons = eina_list_append(sd->icons, ic); + ic->inserted = EINA_TRUE; + } sd->icons_place = eina_list_append(sd->icons_place, ic); } sd->tmp.last_insert = NULL; @@ -3365,7 +3398,9 @@ _e_fm2_file_del(Evas_Object *obj, const char *file) { if (!strcmp(ic->info.file, file)) { + if (!ic->inserted) abort(); sd->icons = eina_list_remove_list(sd->icons, l); + ic->inserted = EINA_FALSE; sd->icons_place = eina_list_remove(sd->icons_place, ic); if (ic->region) { @@ -3373,6 +3408,7 @@ _e_fm2_file_del(Evas_Object *obj, const char *file) ic->region = NULL; } _e_fm2_icon_free(ic); + printf("b: %i\n", eina_list_count(sd->icons)); return; } } @@ -3680,8 +3716,10 @@ _e_fm2_queue_process(Evas_Object *obj) } else l = sd->tmp.last_insert; - EINA_LIST_FREE(sd->queue, ic) + while (sd->queue) { + ic = sd->queue->data; + sd->queue = eina_list_remove_list(sd->queue, sd->queue); /* insertion sort - better than qsort for the way we are doing * things - incrimentally scan and sort as we go as we now know * that the queue files are in order, we speed up insertions to @@ -3698,6 +3736,10 @@ _e_fm2_queue_process(Evas_Object *obj) { if (_e_fm2_cb_icon_sort(ic, ic2) < 0) { + if (!ic->queued) abort(); + if (ic->inserted) abort(); + ic->queued = EINA_FALSE; + ic->inserted = EINA_TRUE; if (l == sd->icons) sd->icons = eina_list_prepend(sd->icons, ic); else @@ -3710,6 +3752,10 @@ _e_fm2_queue_process(Evas_Object *obj) } if (!l) { + if (!ic->queued) abort(); + if (ic->inserted) abort(); + ic->queued = EINA_FALSE; + ic->inserted = EINA_TRUE; sd->icons = eina_list_append(sd->icons, ic); sd->tmp.last_insert = eina_list_last(sd->icons); } @@ -3717,7 +3763,12 @@ _e_fm2_queue_process(Evas_Object *obj) added++; /* if we spent more than 1/20th of a second inserting - give up * for now */ - if ((ecore_time_get() - t) > 0.05) break; + if ((_e_fm2_toomany_get(sd)) && (!sd->toomany)) + { + sd->toomany = EINA_TRUE; + break; + } + if ((ecore_time_get() - t) > 0.01) break; } // printf("FM: SORT %1.3f (%i files) (%i queued, %i added) [%i iter]\n", // ecore_time_get() - tt, eina_list_count(sd->icons), queued, @@ -3726,6 +3777,7 @@ _e_fm2_queue_process(Evas_Object *obj) snprintf(buf, sizeof(buf), P_("%u file", "%u files", sd->overlay_count), sd->overlay_count); edje_object_part_text_set(sd->overlay, "e.text.busy_label", buf); if (sd->resize_job) ecore_job_del(sd->resize_job); + // this will handle a relayout if we have too many icons sd->resize_job = ecore_job_add(_e_fm2_cb_resize_job, obj); evas_object_smart_callback_call(sd->obj, "changed", NULL); sd->tmp.iter++; @@ -3741,7 +3793,12 @@ _e_fm2_queue_free(Evas_Object *obj) if (!sd) return; /* just free the icons in the queue and the queue itself */ EINA_LIST_FREE(sd->queue, ic) - _e_fm2_icon_free(ic); + { + if (!ic->queued) abort(); + if (ic->inserted) abort(); + ic->queued = EINA_FALSE; + _e_fm2_icon_free(ic); + } } static void @@ -3964,6 +4021,34 @@ _e_fm2_icons_place_icon(E_Fm2_Icon *ic) _e_fm2_icon_place_relative(ic, ic2, 0, 1, 1, 0); if (_e_fm2_icons_icon_row_ok(ic) && !_e_fm2_icons_icon_overlaps(ic)) return; */ + if ((ic->sd->last_placed) && (ic->sd->toomany)) + { + ic2 = ic->sd->last_placed; + // ###_ + _e_fm2_icon_place_relative(ic, ic2, 1, 0, 0, 2); + if (_e_fm2_icons_icon_row_ok(ic) && + !_e_fm2_icons_icon_overlaps(ic)) goto done; + // _### + _e_fm2_icon_place_relative(ic, ic2, -1, 0, 0, 2); + if (_e_fm2_icons_icon_row_ok(ic) && + !_e_fm2_icons_icon_overlaps(ic)) goto done; + // ### + // | + _e_fm2_icon_place_relative(ic, ic2, 0, 1, 1, 0); + if (_e_fm2_icons_icon_row_ok(ic) && + !_e_fm2_icons_icon_overlaps(ic)) goto done; + // | + // ### + _e_fm2_icon_place_relative(ic, ic2, 0, -1, 1, 0); + if (_e_fm2_icons_icon_row_ok(ic) && + !_e_fm2_icons_icon_overlaps(ic)) goto done; + // do this anyway - dont care. + // ### + // | + _e_fm2_icon_place_relative(ic, ic2, 0, 1, 1, 0); + ic->x = 0; + goto done; + } EINA_LIST_FOREACH(ic->sd->icons, l, ic2) { if ((ic2 != ic) && (ic2->saved_pos)) @@ -4001,6 +4086,7 @@ _e_fm2_icons_place_icon(E_Fm2_Icon *ic) } } done: + ic->sd->last_placed = ic; return; } @@ -4153,12 +4239,20 @@ static void _e_fm2_icons_free(Evas_Object *obj) { E_Fm2_Smart_Data *sd; + E_Fm2_Icon *ic; + sd = evas_object_smart_data_get(obj); if (!sd) return; _e_fm2_queue_free(obj); /* free all icons */ - E_FREE_LIST(sd->icons, _e_fm2_icon_free); + EINA_LIST_FREE(sd->icons, ic) + { + if (ic->queued) abort(); + if (!ic->inserted) abort(); + ic->inserted = EINA_FALSE; + _e_fm2_icon_free(ic); + } eina_list_free(sd->icons_place); sd->icons_place = NULL; sd->tmp.last_insert = NULL; @@ -4587,7 +4681,13 @@ _e_fm2_icon_fill(E_Fm2_Icon *ic, E_Fm2_Finfo *finf) static void _e_fm2_icon_free(E_Fm2_Icon *ic) { + if (ic->queued) abort(); + if (ic->inserted) abort(); /* free icon, object data etc. etc. */ + if (ic->sd->last_placed == ic) + { + ic->sd->last_placed = NULL; + } if (ic->sd->drop_icon == ic) { /* FIXME: call hide call */ @@ -4630,6 +4730,7 @@ _e_fm2_icon_free(E_Fm2_Icon *ic) eina_stringshare_del(ic->info.link); eina_stringshare_del(ic->info.real_link); eina_stringshare_del(ic->info.category); + memset(ic, 0xff, sizeof(*ic)); free(ic); } -- 2.7.4