From: Enlightenment C. <no...@cv...> - 2006-09-29 08:55:41
|
Enlightenment CVS committal Author : onefang Project : e17 Module : apps/e Dir : e17/apps/e/src/bin Modified Files: e_apps.c e_apps.h Log Message: *Once an icon has been found, or found to not exist, save that info in the E_App, update related aE_Apps, and send trigger change callbacks. *Have all E_Apps stored in a hash of paths for faster lookup. *Don't read in all the details of every app at startup, but do scan the all directory so that we at least know the filenames. Read in details when needed. *When searching the non path info of apps, read in data as needed. Most app things should be faster now. Some things may be slower, and much more testing / tweaking will be done. =================================================================== RCS file: /cvs/e/e17/apps/e/src/bin/e_apps.c,v retrieving revision 1.200 retrieving revision 1.201 diff -u -3 -r1.200 -r1.201 --- e_apps.c 25 Sep 2006 15:19:09 -0000 1.200 +++ e_apps.c 29 Sep 2006 08:55:39 -0000 1.201 @@ -33,6 +33,7 @@ }; +static Evas_Bool _e_apps_hash_cb_init(Evas_Hash *hash, const char *key, void *data, void *fdata); static void _e_app_free (E_App *a); static E_App *_e_app_subapp_file_find (E_App *a, const char *file); static int _e_app_new_save (E_App *a); @@ -42,6 +43,7 @@ static void _e_app_subdir_rescan (E_App *app); static int _e_app_is_eapp (const char *path); static int _e_app_copy (E_App *dst, E_App *src); +static void _e_app_fields_save_others(E_App *a); static void _e_app_save_order (E_App *app); static int _e_app_cb_event_border_add(void *data, int type, void *event); static int _e_app_cb_expire_timer (void *data); @@ -66,6 +68,7 @@ static const char *_e_apps_path_all = NULL; static const char *_e_apps_path_trash = NULL; static Evas_List *_e_apps_start_pending = NULL; +static Evas_Hash *_e_apps_every_app = NULL; #define EAP_MIN_WIDTH 8 #define EAP_MIN_HEIGHT 8 @@ -115,8 +118,10 @@ EAPI int e_app_init(void) { + Ecore_List *_e_apps_all_filenames = NULL; const char *home; char buf[PATH_MAX]; + double begin; home = e_user_homedir_get(); snprintf(buf, sizeof(buf), "%s/.e/e/applications/trash", home); @@ -127,7 +132,25 @@ _e_apps_exit_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, _e_apps_cb_exit, NULL); _e_apps_border_add_handler = ecore_event_handler_add(E_EVENT_BORDER_ADD, _e_app_cb_event_border_add, NULL); ecore_desktop_instrumentation_reset(); - _e_apps_all = e_app_new(buf, 1); + begin = ecore_time_get(); + _e_apps_all_filenames = ecore_file_ls(_e_apps_path_all); + if (_e_apps_all_filenames) + { + const char *file; + + while ((file = ecore_list_next(_e_apps_all_filenames))) + { + E_App *app; + + app = e_app_empty_new(file); + if ((app) && (app->path)) + _e_apps_every_app = evas_hash_direct_add(_e_apps_every_app, app->path, app); + } + ecore_list_destroy(_e_apps_all_filenames); + } + _e_apps_all = e_app_new(_e_apps_path_all, 0); + evas_hash_foreach(_e_apps_every_app, _e_apps_hash_cb_init, NULL); + printf("INITIAL APP SCAN %3.3f\n", ecore_time_get() - begin); #if NO_APP_LIST /* The list already exists, and it doesn't care what order it is in. */ if (_e_apps_all) @@ -137,6 +160,23 @@ return 1; } +static Evas_Bool +_e_apps_hash_cb_init(Evas_Hash *hash, const char *key, void *data, void *fdata) +{ + E_App *a; + + a = data; + /* Link it in to all if needed. */ + if ((!a->parent) && (_e_apps_all) && strncmp(a->path, _e_apps_path_all, strlen(_e_apps_path_all)) == 0) + { + a->parent = _e_apps_all; + _e_apps_all->subapps = evas_list_append(_e_apps_all->subapps, a); + e_object_ref(E_OBJECT(a)); + } + return 1; +} + + EAPI int e_app_shutdown(void) { @@ -172,9 +212,12 @@ printf("BUG: References %d %s\n", E_OBJECT(a)->references, a->path); } } + evas_hash_free(_e_apps_every_app); + _e_apps_every_app = NULL; return 1; } + EAPI void e_app_unmonitor_all(void) { @@ -226,23 +269,13 @@ e_object_ref(E_OBJECT(a)); } - if (!a) + if ((!a) && (ecore_file_exists(path))) { - if (ecore_file_exists(path)) - { - a = E_OBJECT_ALLOC(E_App, E_APP_TYPE, _e_app_free); - - if (a) - { - /* no image for now */ - a->image = NULL; - a->width = 0; - a->height = 0; - /* record the path */ - a->path = evas_stringshare_add(path); - } - } - } + /* Create it and add it to the cache. */ + a = e_app_empty_new(path); + if (a) + _e_apps_every_app = evas_hash_direct_add(_e_apps_every_app, a->path, a); + } if ((a) && (a->path)) { @@ -265,9 +298,11 @@ if ((!stated) && (strcmp(_e_apps_path_all, a->path) != 0)) a->monitor = ecore_file_monitor_add(a->path, _e_app_cb_monitor, a); } - else if (_e_app_is_eapp(path)) + else if (_e_app_is_eapp(a->path)) { - e_app_fields_fill(a, path); + if (!a->filled) + e_app_fields_fill(a, a->path); +// _e_apps_hash_cb_init(_e_apps_every_app, a->path, a, NULL); /* no exe field.. not valid. drop it */ // if (!_e_app_exe_valid_get(a->exe)) @@ -308,15 +343,22 @@ E_App *a; a = E_OBJECT_ALLOC(E_App, E_APP_TYPE, _e_app_free); - a->image = NULL; - if (path) a->path = evas_stringshare_add(path); - else if ((_e_apps_all) && (_e_apps_all->path)) + if (a) { - char buf[4096]; + /* no image for now */ + a->image = NULL; + a->width = 0; + a->height = 0; + /* record the path, or make one up */ + if (path) + a->path = evas_stringshare_add(path); + else if (_e_apps_path_all) + { + char buf[PATH_MAX]; - snprintf(buf, sizeof(buf), "%s/_new_app_%1.1f.desktop", - _e_apps_all->path, ecore_time_get()); - a->path = evas_stringshare_add(buf); + snprintf(buf, sizeof(buf), "%s/_new_app_%1.1f.desktop", _e_apps_path_all, ecore_time_get()); + a->path = evas_stringshare_add(buf); + } } return a; } @@ -429,7 +471,6 @@ } ecore_list_destroy(files); } - } EAPI int @@ -695,8 +736,10 @@ if (ecore_file_exists(buf)) snprintf(buf, sizeof(buf), "%s/%s", parent->path, ecore_file_get_file(add->path)); ecore_file_mv(add->path, buf); + _e_apps_every_app = evas_hash_del(_e_apps_every_app, add->path, add); evas_stringshare_del(add->path); add->path = evas_stringshare_add(buf); + _e_apps_every_app = evas_hash_direct_add(_e_apps_every_app, add->path, add); } _e_app_save_order(parent); @@ -810,8 +853,10 @@ /* Move to trash */ snprintf(buf, sizeof(buf), "%s/%s", _e_apps_path_trash, ecore_file_get_file(a->path)); ecore_file_mv(a->path, buf); + _e_apps_every_app = evas_hash_del(_e_apps_every_app, a->path, a); evas_stringshare_del(a->path); a->path = evas_stringshare_add(buf); + _e_apps_every_app = evas_hash_direct_add(_e_apps_every_app, a->path, a); } _e_app_save_order(a->parent); for (l = a->references; l; l = l->next) @@ -928,6 +973,8 @@ a = l->data; E_OBJECT_CHECK_RETURN(a, NULL); E_OBJECT_TYPE_CHECK_RETURN(a, E_APP_TYPE, NULL); + if (!a->filled) + e_app_fields_fill(a, a->path); ok = 0; if ((a->win_name) || (a->win_class) || (a->win_title) || (a->win_role) || (a->exe)) { @@ -1023,31 +1070,11 @@ EAPI E_App * e_app_path_find(const char *path) { - Evas_List *l; - - if (!path) return NULL; + E_App *a = NULL; - if (_e_apps_list) - { - for (l = _e_apps_list; l; l = l->next) - { - E_App *a; - - a = l->data; - E_OBJECT_CHECK_RETURN(a, NULL); - E_OBJECT_TYPE_CHECK_RETURN(a, E_APP_TYPE, NULL); - if (a->path) - { - if (!strcmp(a->path, path)) - { -// _e_apps_list = evas_list_remove_list(_e_apps_list, l); -// _e_apps_list = evas_list_prepend(_e_apps_list, a); - return a; - } - } - } - } - return NULL; + if ((path) && (_e_apps_every_app)) + a = evas_hash_find(_e_apps_every_app, path); + return a; } EAPI E_App * @@ -1064,6 +1091,8 @@ a = l->data; E_OBJECT_CHECK_RETURN(a, NULL); E_OBJECT_TYPE_CHECK_RETURN(a, E_APP_TYPE, NULL); + if (!a->filled) + e_app_fields_fill(a, a->path); if (a->name) { if (!strcasecmp(a->name, name)) @@ -1091,6 +1120,8 @@ a = l->data; E_OBJECT_CHECK_RETURN(a, NULL); E_OBJECT_TYPE_CHECK_RETURN(a, E_APP_TYPE, NULL); + if (!a->filled) + e_app_fields_fill(a, a->path); if (a->generic) { if (!strcasecmp(a->generic, generic)) @@ -1118,6 +1149,8 @@ a = l->data; E_OBJECT_CHECK_RETURN(a, NULL); E_OBJECT_TYPE_CHECK_RETURN(a, E_APP_TYPE, NULL); + if (!a->filled) + e_app_fields_fill(a, a->path); if (a->exe) { if (!strcmp(a->exe, exe)) @@ -1147,6 +1180,8 @@ a = l->data; E_OBJECT_CHECK_RETURN(a, NULL); E_OBJECT_TYPE_CHECK_RETURN(a, E_APP_TYPE, NULL); + if (!a->filled) + e_app_fields_fill(a, a->path); if (a->name) { if (e_util_glob_case_match(a->name, name)) @@ -1170,6 +1205,8 @@ a = l->data; E_OBJECT_CHECK_RETURN(a, NULL); E_OBJECT_TYPE_CHECK_RETURN(a, E_APP_TYPE, NULL); + if (!a->filled) + e_app_fields_fill(a, a->path); if (a->generic) { if (e_util_glob_case_match(a->generic, generic)) @@ -1193,6 +1230,8 @@ a = l->data; E_OBJECT_CHECK_RETURN(a, NULL); E_OBJECT_TYPE_CHECK_RETURN(a, E_APP_TYPE, NULL); + if (!a->filled) + e_app_fields_fill(a, a->path); if (a->exe) { if (e_util_glob_match(a->exe, exe)) @@ -1216,6 +1255,8 @@ a = l->data; E_OBJECT_CHECK_RETURN(a, NULL); E_OBJECT_TYPE_CHECK_RETURN(a, E_APP_TYPE, NULL); + if (!a->filled) + e_app_fields_fill(a, a->path); if (a->comment) { if (e_util_glob_case_match(a->comment, comment)) @@ -1242,6 +1283,7 @@ lang = NULL; } if (!path) path = a->path; + if (!path) return; ext = strrchr(path, '.'); if ((ext) && (strcmp(ext, ".desktop") == 0)) @@ -1271,6 +1313,7 @@ a->startup_notify = desktop->startup; a->wait_exit = desktop->wait_exit; a->dirty_icon = 0; + a->filled = 1; // if (desktop->type) a->type = evas_stringshare_add(desktop->type); // if (desktop->categories) a->categories = evas_stringshare_add(desktop->categories); @@ -1329,6 +1372,7 @@ free(v); } eet_close(ef); + a->filled = 1; } } @@ -1358,6 +1402,7 @@ return eet_read(ef, field, size); } + EAPI void e_app_fields_save(E_App *a) { @@ -1372,7 +1417,7 @@ ext = ecore_file_get_file(a->path); if ( (!a->path) || ((strncmp(ext, "_new_app_", 9) == 0) && (!ecore_file_exists(a->path))) ) { - snprintf(buf, sizeof(buf), "%s/%s.desktop", _e_apps_all->path, a->name); + snprintf(buf, sizeof(buf), "%s/%s.desktop", _e_apps_path_all, a->name); if (a->path) evas_stringshare_del(a->path); a->path = evas_stringshare_add(buf); } @@ -1381,15 +1426,15 @@ if (!ecore_file_exists(a->path)) { /* Force it to be in all. */ - snprintf(buf, sizeof(buf), "%s/%s", _e_apps_all->path, ecore_file_get_file(a->path)); + snprintf(buf, sizeof(buf), "%s/%s", _e_apps_path_all, ecore_file_get_file(a->path)); if (a->path) evas_stringshare_del(a->path); a->path = evas_stringshare_add(buf); } if (!a->path) return; - if (!ecore_file_exists(a->path)) - { - new_eap = 1; - } + if (ecore_file_exists(a->path)) + _e_apps_every_app = evas_hash_del(_e_apps_every_app, a->path, a); + else + new_eap = 1; ext = strrchr(a->path, '.'); if ((ext) && (strcmp(ext, ".desktop") == 0)) @@ -1540,6 +1585,7 @@ eet_close(ef); } + _e_apps_every_app = evas_hash_direct_add(_e_apps_every_app, a->path, a); if (new_eap) { /* Careful, if this is being created from the border icon, this E_App is already part of the border. */ @@ -1550,39 +1596,45 @@ _e_app_change(a, E_APP_ADD); } else - { - Evas_List *l; + _e_app_fields_save_others(a); +} - for (l = a->references; l; l = l->next) - { - E_App *a2; +static void +_e_app_fields_save_others(E_App *a) +{ + Evas_List *l; + char buf[PATH_MAX]; + + for (l = a->references; l; l = l->next) + { + E_App *a2; - a2 = l->data; - if (_e_app_copy(a2, a)) _e_app_change(a2, E_APP_CHANGE); - } - if (a->orig) - { - E_App *a2; + a2 = l->data; + if (_e_app_copy(a2, a)) _e_app_change(a2, E_APP_CHANGE); + } + if (a->orig) + { + E_App *a2; - a2 = a->orig; - if (_e_app_copy(a2, a)) _e_app_change(a2, E_APP_CHANGE); - } - _e_app_change(a, E_APP_CHANGE); - if (a->parent) - { - snprintf(buf, sizeof(buf), "%s/.eap.cache.cfg", a->parent->path); - ecore_file_unlink(buf); - _e_app_change(a->parent, E_APP_CHANGE); - /* I don't think we need to rescan. - * A) we should be changing all the relevant stuff here. - * B) monitoring will catch other changes. - * C) it's a waste of time. - _e_app_subdir_rescan(a->parent); - */ - } - } + a2 = a->orig; + if (_e_app_copy(a2, a)) _e_app_change(a2, E_APP_CHANGE); + } + _e_app_change(a, E_APP_CHANGE); + if (a->parent) + { + snprintf(buf, sizeof(buf), "%s/.eap.cache.cfg", a->parent->path); + ecore_file_unlink(buf); + _e_app_change(a->parent, E_APP_CHANGE); + /* I don't think we need to rescan. + * A) we should be changing all the relevant stuff here. + * B) monitoring will catch other changes. + * C) it's a waste of time. + _e_app_subdir_rescan(a->parent); + */ + } } + EAPI void e_app_fields_empty(E_App *a) { @@ -1614,6 +1666,7 @@ a->win_title = NULL; a->win_role = NULL; a->dirty_icon = 0; + a->filled = 0; } EAPI Ecore_List * @@ -1740,6 +1793,33 @@ e_menu_item_icon_file_set(mi, a->icon_path); } +static void +_e_app_fdo_icon_search(E_App *a) +{ + if ((!a->no_icon) && (a->icon_class)) + { + char *v = NULL; + + /* FIXME: Use a real icon size. */ + v = (char *)ecore_desktop_icon_find(a->icon_class, NULL, e_config->icon_theme); + if (v) + { + if (a->icon_path) evas_stringshare_del(a->icon_path); + a->icon_path = evas_stringshare_add(v); + if (e_config->icon_theme) + { + if (a->icon_theme) evas_stringshare_del(a->icon_theme); + a->icon_theme = evas_stringshare_add(e_config->icon_theme); + } + a->dirty_icon = 1; + free(v); + } + else + a->no_icon = 1; + /* Copy the new found icon data to the original. */ + _e_app_fields_save_others(a); + } +} EAPI Evas_Object * e_app_icon_add(Evas *evas, E_App *a) @@ -1773,25 +1853,8 @@ { ; /* It's a bit more obvious this way. */ } - else if (a->icon_class) /* If that fails, then this might be an FDO icon. */ - { - char *v = NULL; - - /* FIXME: Use a real icon size. */ - v = (char *)ecore_desktop_icon_find(a->icon_class, NULL, e_config->icon_theme); - if (v) - { - if (a->icon_path) evas_stringshare_del(a->icon_path); - a->icon_path = evas_stringshare_add(v); - if (e_config->icon_theme) - { - if (a->icon_theme) evas_stringshare_del(a->icon_theme); - a->icon_theme = evas_stringshare_add(e_config->icon_theme); - } - a->dirty_icon = 1; - free(v); - } - } + else /* If that fails, then this might be an FDO icon. */ + _e_app_fdo_icon_search(a); if (a->icon_path) { @@ -1843,28 +1906,9 @@ if (!e_util_menu_item_edje_icon_list_set(mi, a->icon_class)) { if (edje_file_group_exists(a->path, "icon")) - { - e_menu_item_icon_edje_set(mi, a->path, "icon"); - } - else if ((a->icon_class)) /* If that fails, then this might be an FDO icon. */ - { - char *v; - - /* FIXME: Use a real icon size. */ - v = (char *) ecore_desktop_icon_find(a->icon_class, NULL, e_config->icon_theme); - if (v) - { - if (a->icon_path) evas_stringshare_del(a->icon_path); - a->icon_path = evas_stringshare_add(v); - if (e_config->icon_theme) - { - if (a->icon_theme) evas_stringshare_del(a->icon_theme); - a->icon_theme = evas_stringshare_add(e_config->icon_theme); - } - a->dirty_icon = 1; - free(v); - } - } + e_menu_item_icon_edje_set(mi, a->path, "icon"); + else /* If that fails, then this might be an FDO icon. */ + _e_app_fdo_icon_search(a); if (a->icon_path) _e_app_icon_path_add_to_menu_item(mi, a); @@ -2049,7 +2093,11 @@ _e_apps_list = evas_list_remove(_e_apps_list, a); #endif e_app_fields_empty(a); - if (a->path) evas_stringshare_del(a->path); + if (a->path) + { + _e_apps_every_app = evas_hash_del(_e_apps_every_app, a->path, a); + evas_stringshare_del(a->path); + } free(a); } } @@ -2087,7 +2135,7 @@ for (l = _e_apps_change_callbacks; l; l = l->next) { E_App_Callback *cb; - + cb = l->data; if (!cb->delete_me) cb->func(cb->data, a, ch); } @@ -2458,6 +2506,7 @@ dst->starting = src->starting; dst->scanned = src->scanned; dst->dirty_icon = src->dirty_icon; + dst->filled = src->filled; return 1; } @@ -2487,7 +2536,7 @@ { char buf[PATH_MAX]; - snprintf(buf, sizeof(buf), "%s/.eap.cache.cfg", app ->parent->path); + snprintf(buf, sizeof(buf), "%s/.eap.cache.cfg", app->parent->path); ecore_file_unlink(buf); } } =================================================================== RCS file: /cvs/e/e17/apps/e/src/bin/e_apps.h,v retrieving revision 1.44 retrieving revision 1.45 diff -u -3 -r1.44 -r1.45 --- e_apps.h 25 Sep 2006 14:17:42 -0000 1.44 +++ e_apps.h 29 Sep 2006 08:55:39 -0000 1.45 @@ -68,6 +68,8 @@ unsigned char deleted : 1; /* this app's file is deleted from disk */ + unsigned char filled : 1; /* this app has had its data filled in */ + unsigned char no_icon : 1; /* this app's icon has not been found in the current theme, future searhes should give up early . */ unsigned char dirty_icon : 1; /* this app's icon has been found, and the on disk cache needs to be updated. */ /* Actually calling this st_mtime causes compile issues, must be some strange macros at work. */ |