diff --git a/legacy/efreet/src/lib/efreet_cache.c b/legacy/efreet/src/lib/efreet_cache.c index 5a62c46651..25a1bbb8b4 100644 --- a/legacy/efreet/src/lib/efreet_cache.c +++ b/legacy/efreet/src/lib/efreet_cache.c @@ -3,12 +3,21 @@ #endif #include +#include #include "Efreet.h" #include "efreet_private.h" /* TODO: Listen for changes for icon dirs */ -/* TODO: Transfer some of desktop cache to this file, to share some infrastructure */ + +typedef struct _Efreet_Old_Cache Efreet_Old_Cache; + +struct _Efreet_Old_Cache +{ + Eina_Hash *hash; + Eet_File *ef; +}; + /** * Data for cache files @@ -21,25 +30,44 @@ static Eet_File *icon_cache = NULL; static const char *icon_cache_name = NULL; static Eet_File *icon_fallback_cache = NULL; -static Ecore_File_Monitor *icon_cache_monitor = NULL; -static Ecore_Timer *icon_cache_timer = NULL; +static Eet_Data_Descriptor *desktop_edd = NULL; +static Eet_File *desktop_cache = NULL; +static const char *desktop_cache_dirs = NULL; +static const char *desktop_cache_file = NULL; + +static Ecore_File_Monitor *cache_monitor = NULL; + +static Ecore_Timer *cache_timer = NULL; + +static Ecore_Event_Handler *cache_exe_handler = NULL; +static Ecore_Job *icon_cache_job = NULL; static Ecore_Exe *icon_cache_exe = NULL; static int icon_cache_exe_lock = -1; -static Ecore_Event_Handler *icon_cache_exe_handler; +static Ecore_Job *desktop_cache_job = NULL; +static Ecore_Exe *desktop_cache_exe = NULL; +static int desktop_cache_exe_lock = -1; + +static Eina_List *old_desktop_caches = NULL; static void efreet_icon_edd_shutdown(void); +static void efreet_desktop_edd_shutdown(void); -static Eina_Bool icon_cache_exe_cb(void *data, int type, void *event); -static void icon_cache_update_cb(void *data, Ecore_File_Monitor *em, +static Eina_Bool cache_exe_cb(void *data, int type, void *event); +static void cache_update_cb(void *data, Ecore_File_Monitor *em, Ecore_File_Event event, const char *path); -static void icon_cache_timer_update(void); -static Eina_Bool icon_cache_timer_cb(void *data); +static void cache_timer_update(void); +static Eina_Bool cache_timer_cb(void *data); static void icon_cache_close(void); +static void desktop_cache_update_cache_job(void *data); +static void icon_cache_update_cache_job(void *data); +static void desktop_cache_update_free(void *data, void *ev); + EAPI int EFREET_EVENT_ICON_CACHE_UPDATE = 0; +EAPI int EFREET_EVENT_DESKTOP_CACHE_UPDATE = 0; int efreet_cache_init(void) @@ -47,55 +75,85 @@ efreet_cache_init(void) char buf[PATH_MAX]; if (!efreet_icon_edd_init()) - { - efreet_icon_edd_shutdown(); - return 0; - } + goto error; if (!efreet_icon_fallback_edd_init()) - { - efreet_icon_edd_shutdown(); - return 0; - } + goto error; + if (!efreet_desktop_edd_init()) + goto error; EFREET_EVENT_ICON_CACHE_UPDATE = ecore_event_type_new(); + EFREET_EVENT_DESKTOP_CACHE_UPDATE = ecore_event_type_new(); snprintf(buf, sizeof(buf), "%s/.efreet", efreet_home_dir_get()); - if (!ecore_file_mkpath(buf)) goto cache_error; + if (!ecore_file_mkpath(buf)) goto error; if (efreet_cache_update) { - icon_cache_exe_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, - icon_cache_exe_cb, NULL); - if (!icon_cache_exe_handler) goto cache_error; + cache_exe_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, + cache_exe_cb, NULL); + if (!cache_exe_handler) goto error; - icon_cache_monitor = ecore_file_monitor_add(buf, - icon_cache_update_cb, + cache_monitor = ecore_file_monitor_add(buf, + cache_update_cb, NULL); - if (!icon_cache_monitor) goto cache_error; + if (!cache_monitor) goto error; -#if 0 efreet_desktop_changes_listen(); +#if 0 + efreet_icon_changes_listen(); #endif - ecore_exe_run(PACKAGE_LIB_DIR "/efreet/efreet_icon_cache_create", NULL); + efreet_cache_icon_update(); + efreet_cache_desktop_update(); } return 1; -cache_error: - if (icon_cache_exe_handler) ecore_event_handler_del(icon_cache_exe_handler); - if (icon_cache_monitor) ecore_file_monitor_del(icon_cache_monitor); +error: + if (cache_exe_handler) ecore_event_handler_del(cache_exe_handler); + if (cache_monitor) ecore_file_monitor_del(cache_monitor); + efreet_icon_edd_shutdown(); + efreet_desktop_edd_shutdown(); return 0; } void efreet_cache_shutdown(void) { - if (icon_cache_timer) ecore_timer_del(icon_cache_timer); - icon_cache_close(); + Efreet_Old_Cache *d; - if (icon_cache_exe_handler) ecore_event_handler_del(icon_cache_exe_handler); - if (icon_cache_monitor) ecore_file_monitor_del(icon_cache_monitor); + if (cache_timer) ecore_timer_del(cache_timer); + icon_cache_close(); + if (desktop_cache) eet_close(desktop_cache); + IF_RELEASE(desktop_cache_file); + IF_RELEASE(desktop_cache_dirs); + + if (cache_exe_handler) ecore_event_handler_del(cache_exe_handler); + if (cache_monitor) ecore_file_monitor_del(cache_monitor); efreet_icon_edd_shutdown(); + efreet_desktop_edd_shutdown(); + if (desktop_cache_job) + { + ecore_job_del(desktop_cache_job); + desktop_cache_job = NULL; + } + if (icon_cache_exe) ecore_exe_terminate(icon_cache_exe); + if (desktop_cache_exe) ecore_exe_terminate(desktop_cache_exe); + if (icon_cache_exe_lock > 0) + { + close(icon_cache_exe_lock); + icon_cache_exe_lock = -1; + } + if (desktop_cache_exe_lock > 0) + { + close(desktop_cache_exe_lock); + desktop_cache_exe_lock = -1; + } + + EINA_LIST_FREE(old_desktop_caches, d) + { + eina_hash_free(d->hash); + free(d); + } } /* @@ -114,6 +172,51 @@ efreet_icon_cache_file(const char *theme) return cache_file; } +/* + * Needs EAPI because of helper binaries + */ +EAPI const char * +efreet_desktop_cache_file(void) +{ + char tmp[PATH_MAX] = { '\0' }; + const char *home, *lang, *country, *modifier; + + if (desktop_cache_file) return desktop_cache_file; + + home = efreet_home_dir_get(); + lang = efreet_lang_get(); + country = efreet_lang_country_get(); + modifier = efreet_lang_modifier_get(); + + if (lang && country && modifier) + snprintf(tmp, sizeof(tmp), "%s/.efreet/desktop_%s_%s@%s.cache", home, lang, country, modifier); + else if (lang && country) + snprintf(tmp, sizeof(tmp), "%s/.efreet/desktop_%s_%s.cache", home, lang, country); + else if (lang) + snprintf(tmp, sizeof(tmp), "%s/.efreet/desktop_%s.cache", home, lang); + else + snprintf(tmp, sizeof(tmp), "%s/.efreet/desktop.cache", home); + + desktop_cache_file = eina_stringshare_add(tmp); + return desktop_cache_file; +} + +/* + * Needs EAPI because of helper binaries + */ +EAPI const char * +efreet_desktop_cache_dirs(void) +{ + char tmp[PATH_MAX] = { '\0' }; + + if (desktop_cache_dirs) return desktop_cache_dirs; + + snprintf(tmp, sizeof(tmp), "%s/.efreet/desktop_dirs.cache", efreet_home_dir_get()); + + desktop_cache_dirs = eina_stringshare_add(tmp); + return desktop_cache_dirs; +} + /* * Needs EAPI because of helper binaries */ @@ -196,6 +299,52 @@ efreet_icon_edd_shutdown(void) cache_icon_fallback_edd = NULL; } +/* + * Needs EAPI because of helper binaries + */ +EAPI Eet_Data_Descriptor * +efreet_desktop_edd_init(void) +{ + if (!desktop_edd) + { + Eet_Data_Descriptor_Class eddc; + + EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Desktop); + desktop_edd = eet_data_descriptor_file_new(&eddc); + if (!desktop_edd) return NULL; + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "type", type, EET_T_INT); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "version", version, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "orig_path", orig_path, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "load_time", load_time, EET_T_LONG_LONG); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "name", name, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "generic_name", generic_name, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "comment", comment, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "icon", icon, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "try_exec", try_exec, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "exec", exec, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "path", path, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "startup_wm_class", startup_wm_class, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "url", url, EET_T_STRING); + eet_data_descriptor_element_add(desktop_edd, "only_show_in", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Desktop, only_show_in), 0, NULL, NULL); + eet_data_descriptor_element_add(desktop_edd, "not_show_in", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Desktop, not_show_in), 0, NULL, NULL); + eet_data_descriptor_element_add(desktop_edd, "categories", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Desktop, categories), 0, NULL, NULL); + eet_data_descriptor_element_add(desktop_edd, "mime_types", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Desktop, mime_types), 0, NULL, NULL); + eet_data_descriptor_element_add(desktop_edd, "x", EET_T_STRING, EET_G_HASH, offsetof(Efreet_Desktop, x), 0, NULL, NULL); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "no_display", no_display, EET_T_UCHAR); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "hidden", hidden, EET_T_UCHAR); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "terminal", terminal, EET_T_UCHAR); + EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "startup_notify", startup_notify, EET_T_UCHAR); + } + return desktop_edd; +} + +static void +efreet_desktop_edd_shutdown(void) +{ + if (desktop_edd) eet_data_descriptor_free(desktop_edd); + desktop_edd = NULL; +} + /* * Needs EAPI because of helper binaries */ @@ -263,7 +412,7 @@ efreet_cache_icon_find(Efreet_Icon_Theme *theme, const char *icon) if (icon_cache) { icon_cache_name = eina_stringshare_add(theme->name.internal); - icon_cache_timer_update(); + cache_timer_update(); } } if (icon_cache) @@ -281,67 +430,175 @@ efreet_cache_icon_fallback_find(const char *icon) path = efreet_icon_cache_file("_fallback"); icon_fallback_cache = eet_open(path, EET_FILE_MODE_READ); if (icon_fallback_cache) - icon_cache_timer_update(); + cache_timer_update(); } if (icon_fallback_cache) return eet_data_read(icon_fallback_cache, cache_icon_fallback_edd, icon); return NULL; } +Efreet_Desktop * +efreet_cache_desktop_find(const char *file) +{ + Efreet_Desktop *desktop; + char rp[PATH_MAX]; + + if (!realpath(file, rp)) return NULL; + + if (!desktop_cache) + desktop_cache = eet_open(efreet_desktop_cache_file(), EET_FILE_MODE_READ); + if (!desktop_cache) + return NULL; + + cache_timer_update(); + + desktop = eet_data_read(desktop_cache, desktop_edd, rp); + if (!desktop) return NULL; + desktop->ref = 1; + desktop->eet = 1; + return desktop; +} + +void +efreet_cache_desktop_update(void) +{ + if (!efreet_cache_update) return; + + /* TODO: Make sure we don't create a lot of execs, maybe use a timer? */ + if (desktop_cache_job) ecore_job_del(desktop_cache_job); + desktop_cache_job = ecore_job_add(desktop_cache_update_cache_job, NULL); +} + +void +efreet_cache_icon_update(void) +{ + if (!efreet_cache_update) return; + + /* TODO: Make sure we don't create a lot of execs, maybe use a timer? */ + if (icon_cache_job) ecore_job_del(icon_cache_job); + icon_cache_job = ecore_job_add(icon_cache_update_cache_job, NULL); +} + +void +efreet_cache_desktop_free(Efreet_Desktop *desktop) +{ + Efreet_Old_Cache *d; + Efreet_Desktop *curr; + Eina_List *l; + + if (!old_desktop_caches) return; + + EINA_LIST_FOREACH(old_desktop_caches, l, d) + { + curr = eina_hash_find(d->hash, desktop->orig_path); + if (curr && curr == desktop) + { + eina_hash_del_by_key(d->hash, desktop->orig_path); + if (eina_hash_population(d->hash) == 0) + { + eina_hash_free(d->hash); + d->hash = NULL; + } + break; + } + } +} + static Eina_Bool -icon_cache_exe_cb(void *data __UNUSED__, int type __UNUSED__, void *event) +cache_exe_cb(void *data __UNUSED__, int type __UNUSED__, void *event) { Ecore_Exe_Event_Del *ev; ev = event; - if (ev->exe != icon_cache_exe) return ECORE_CALLBACK_RENEW; - if (icon_cache_exe_lock > 0) + if (ev->exe == icon_cache_exe) { - close(icon_cache_exe_lock); - icon_cache_exe_lock = -1; + if (icon_cache_exe_lock > 0) + { + close(icon_cache_exe_lock); + icon_cache_exe_lock = -1; + } + icon_cache_exe = NULL; + } + else if (ev->exe == desktop_cache_exe) + { + if (desktop_cache_exe_lock > 0) + { + close(desktop_cache_exe_lock); + desktop_cache_exe_lock = -1; + } + desktop_cache_exe = NULL; } return ECORE_CALLBACK_RENEW; } static void -icon_cache_update_cb(void *data __UNUSED__, Ecore_File_Monitor *em __UNUSED__, +cache_update_cb(void *data __UNUSED__, Ecore_File_Monitor *em __UNUSED__, Ecore_File_Event event, const char *path) { - /* TODO: This is stupid, we should only emit event when the complete - * cache update process is done. Else we will reload icons several times - * during cache update */ - const char *file, *ext; + const char *file; Efreet_Event_Cache_Update *ev = NULL; + Eet_File *tmp = NULL; + Efreet_Old_Cache *d = NULL; + if (event != ECORE_FILE_EVENT_CREATED_FILE && event != ECORE_FILE_EVENT_MODIFIED) return; + file = ecore_file_file_get(path); - if (!file || strncmp(file, "icon_", 5)) return; - ext = strrchr(file, '.'); - if (!ext || strcmp(ext, ".cache")) return; + if (!file) return; + if (!strcmp(file, "icon_data.update")) + { + printf("update icon cache\n"); + icon_cache_close(); - icon_cache_close(); + ev = NEW(Efreet_Event_Cache_Update, 1); + if (!ev) return; + ecore_event_add(EFREET_EVENT_ICON_CACHE_UPDATE, ev, NULL, NULL); + } + else if (!strcmp(file, "desktop_data.update")) + { + printf("update desktop cache\n"); + tmp = eet_open(efreet_desktop_cache_file(), EET_FILE_MODE_READ); + if (!tmp) return; + ev = NEW(Efreet_Event_Cache_Update, 1); + if (!ev) goto error; + d = NEW(Efreet_Old_Cache, 1); + if (!d) goto error; - ev = NEW(Efreet_Event_Cache_Update, 1); - if (!ev) return; - ecore_event_add(EFREET_EVENT_ICON_CACHE_UPDATE, ev, NULL, NULL); + d->hash = efreet_desktop_cache; + d->ef = desktop_cache; + old_desktop_caches = eina_list_append(old_desktop_caches, d); + + efreet_desktop_cache = eina_hash_string_superfast_new(NULL); + desktop_cache = tmp; + + efreet_util_desktop_cache_reload(); + ecore_event_add(EFREET_EVENT_DESKTOP_CACHE_UPDATE, ev, desktop_cache_update_free, d); + return; + } +error: + IF_FREE(ev); + IF_FREE(d); + if(tmp) eet_close(tmp); } static void -icon_cache_timer_update(void) +cache_timer_update(void) { - if (icon_cache_timer) - ecore_timer_interval_set(icon_cache_timer, 60.0); + if (cache_timer) + ecore_timer_interval_set(cache_timer, 60.0); else - icon_cache_timer = ecore_timer_add(60.0, icon_cache_timer_cb, NULL); + cache_timer = ecore_timer_add(60.0, cache_timer_cb, NULL); } static Eina_Bool -icon_cache_timer_cb(void *data __UNUSED__) +cache_timer_cb(void *data __UNUSED__) { - icon_cache_timer = NULL; + cache_timer = NULL; icon_cache_close(); + if (desktop_cache) eet_close(desktop_cache); + desktop_cache = NULL; return ECORE_CALLBACK_DONE; } @@ -354,3 +611,119 @@ icon_cache_close(void) icon_fallback_cache = NULL; IF_RELEASE(icon_cache_name); } + +static void +desktop_cache_update_cache_job(void *data __UNUSED__) +{ + char file[PATH_MAX]; + struct flock fl; + + desktop_cache_job = NULL; + + /* TODO: Retry update cache later */ + if (desktop_cache_exe_lock > 0) return; + + if (!efreet_desktop_write_cache_dirs_file()) return; + + snprintf(file, sizeof(file), "%s/.efreet/desktop_exec.lock", efreet_home_dir_get()); + + desktop_cache_exe_lock = open(file, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); + if (desktop_cache_exe_lock < 0) return; + memset(&fl, 0, sizeof(struct flock)); + fl.l_type = F_WRLCK; + fl.l_whence = SEEK_SET; + if (fcntl(desktop_cache_exe_lock, F_SETLK, &fl) < 0) goto error; + desktop_cache_exe = ecore_exe_run(PACKAGE_LIB_DIR "/efreet/efreet_desktop_cache_create", NULL); + if (!desktop_cache_exe) goto error; + + return; + +error: + if (desktop_cache_exe_lock > 0) + { + close(desktop_cache_exe_lock); + desktop_cache_exe_lock = -1; + } +} + +static void +icon_cache_update_cache_job(void *data __UNUSED__) +{ + char file[PATH_MAX]; + struct flock fl; + + icon_cache_job = NULL; + + /* TODO: Retry update cache later */ + if (icon_cache_exe_lock > 0) return; + + snprintf(file, sizeof(file), "%s/.efreet/icon_exec.lock", efreet_home_dir_get()); + + icon_cache_exe_lock = open(file, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); + if (icon_cache_exe_lock < 0) return; + memset(&fl, 0, sizeof(struct flock)); + fl.l_type = F_WRLCK; + fl.l_whence = SEEK_SET; + if (fcntl(icon_cache_exe_lock, F_SETLK, &fl) < 0) goto error; + icon_cache_exe = ecore_exe_run(PACKAGE_LIB_DIR "/efreet/efreet_icon_cache_create", NULL); + if (!icon_cache_exe) goto error; + + return; + +error: + if (icon_cache_exe_lock > 0) + { + close(icon_cache_exe_lock); + icon_cache_exe_lock = -1; + } +} + +static void +desktop_cache_update_free(void *data, void *ev) +{ + Efreet_Old_Cache *d; + int dangling = 0; + + d = data; + /* + * All users should now had the chance to update their pointers, so we can now + * free the old cache + */ + if (d->hash) + { + Eina_Iterator *it; + Eina_Hash_Tuple *tuple; + + it = eina_hash_iterator_tuple_new(d->hash); + EINA_ITERATOR_FOREACH(it, tuple) + { + printf("Efreet: %d:%s still in cache on cache close!\n", + ((Efreet_Desktop *)tuple->data)->ref, (char *)tuple->key); + dangling++; + } + eina_iterator_free(it); + + eina_hash_free(d->hash); + } + /* + * If there are dangling references the eet file won't be closed - to + * avoid crashes, but this will leak instead. + */ + if (dangling == 0) + { + if (d->ef) eet_close(d->ef); + } + else + { + printf("Efreet: ERROR. There are still %i desktop files with old\n" + "dangling references to desktop files. This application\n" + "has not handled the EFREET_EVENT_DESKTOP_CACHE_UPDATE\n" + "fully and released its references. Please fix the application\n" + "so it does this.\n", + dangling); + } + old_desktop_caches = eina_list_remove(old_desktop_caches, d); + free(d); + free(ev); +} + diff --git a/legacy/efreet/src/lib/efreet_desktop.c b/legacy/efreet/src/lib/efreet_desktop.c index 4874b7b54a..5e156b0f57 100644 --- a/legacy/efreet/src/lib/efreet_desktop.c +++ b/legacy/efreet/src/lib/efreet_desktop.c @@ -2,16 +2,11 @@ # include #endif -#include -#include -#include -#include #include -#include +#include #include #include #include -#include #ifdef _WIN32 # include @@ -22,13 +17,11 @@ #define DESKTOP_VERSION "1.0" -typedef struct _Efreet_Old_Cache Efreet_Old_Cache; - -struct _Efreet_Old_Cache -{ - Eina_Hash *desktop_cache; - Eet_File *cache; -}; +/** + * A cache of all loaded desktops, hashed by file name. + * Values are Efreet_Desktop structures + */ +Eina_Hash *efreet_desktop_cache = NULL; /** * The current desktop environment (e.g. "Enlightenment" or "Gnome") @@ -36,41 +29,16 @@ struct _Efreet_Old_Cache static const char *desktop_environment = NULL; /** - * A cache of all loaded desktops, hashed by file name. - * Values are Efreet_Desktop structures + * A cache of all unknown desktop dirs */ -static Eina_Hash *efreet_desktop_cache = NULL; +static Eina_List *efreet_desktop_dirs = NULL; /** * A list of the desktop types available */ static Eina_List *efreet_desktop_types = NULL; -/** - * A cache of all unknown desktop dirs - */ -static Eina_List *efreet_desktop_dirs = NULL; - -/** - * A job pointer for cache updates - */ -static Ecore_Job *efreet_desktop_job = NULL; -static Ecore_Exe *efreet_desktop_exe = NULL; -static int efreet_desktop_exe_lock = -1; -static Ecore_Event_Handler *efreet_desktop_exe_handler = NULL; - -/** - * Data for cache files - */ -static const char *cache_dirs = NULL; -static const char *cache_file = NULL; -static Eet_File *cache = NULL; -static Eet_Data_Descriptor *desktop_edd = NULL; -static Ecore_File_Monitor *cache_monitor = NULL; - -static Eina_List *old_caches = NULL; - -static Eina_Hash *change_monitors = NULL; +static Eina_Hash *change_monitors = NULL; #ifdef EFREET_MODULE_LOG_DOM #undef EFREET_MODULE_LOG_DOM @@ -83,8 +51,6 @@ EAPI int EFREET_DESKTOP_TYPE_APPLICATION = 0; EAPI int EFREET_DESKTOP_TYPE_LINK = 0; EAPI int EFREET_DESKTOP_TYPE_DIRECTORY = 0; -EAPI int EFREET_EVENT_DESKTOP_CACHE_UPDATE = 0; - /** * @internal * Information about custom types @@ -125,18 +91,6 @@ static Eina_Bool efreet_desktop_x_fields_save(const Eina_Hash *hash, void *fdata); static int efreet_desktop_environment_check(Efreet_Desktop *desktop); -static void efreet_desktop_edd_shutdown(void); -static int efreet_desktop_write_cache_dirs_file(void); - -static void efreet_desktop_cache_update_cb(void *data, Ecore_File_Monitor *em, - Ecore_File_Event event, const char *path); -static void efreet_desktop_cache_update_free(void *data, void *ev); - -static void efreet_desktop_update_cache(void); -static void efreet_desktop_update_cache_job(void *data); -static Eina_Bool efreet_desktop_exe_cb(void *data, int type, void *event); - -static void efreet_desktop_changes_listen(void); static void efreet_desktop_changes_listen_recursive(const char *path); static void efreet_desktop_changes_monitor_add(const char *path); static void efreet_desktop_changes_cb(void *data, Ecore_File_Monitor *em, @@ -150,8 +104,6 @@ static void efreet_desktop_changes_cb(void *data, Ecore_File_Monitor *em, int efreet_desktop_init(void) { - char buf[PATH_MAX]; - _efreet_desktop_log_dom = eina_log_domain_register ("efreet_desktop", EFREET_DEFAULT_LOG_COLOR); if (_efreet_desktop_log_dom < 0) @@ -159,8 +111,6 @@ efreet_desktop_init(void) ERROR("Efreet: Could not create a log domain for efreet_desktop"); return 0; } - if (!efreet_desktop_edd_init()) - goto edd_error; efreet_desktop_cache = eina_hash_string_superfast_new(NULL); efreet_desktop_types = NULL; @@ -175,40 +125,7 @@ efreet_desktop_init(void) EFREET_DESKTOP_TYPE_DIRECTORY = efreet_desktop_type_add("Directory", NULL, NULL, NULL); - EFREET_EVENT_DESKTOP_CACHE_UPDATE = ecore_event_type_new(); - - snprintf(buf, sizeof(buf), "%s/.efreet", efreet_home_dir_get()); - if (!ecore_file_mkpath(buf)) goto cache_error; - - if (efreet_cache_update) - { - efreet_desktop_exe_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, - efreet_desktop_exe_cb, NULL); - if (!efreet_desktop_exe_handler) goto cache_error; - - cache_monitor = ecore_file_monitor_add(buf, - efreet_desktop_cache_update_cb, - NULL); - if (!cache_monitor) goto handler_error; - - efreet_desktop_changes_listen(); - - ecore_exe_run(PACKAGE_LIB_DIR "/efreet/efreet_desktop_cache_create", NULL); - - } - - /* TODO: Defer eet open until we actually need it open. */ - cache = eet_open(efreet_desktop_cache_file(), EET_FILE_MODE_READ); - return 1; - -handler_error: - if (efreet_desktop_exe_handler) ecore_event_handler_del(efreet_desktop_exe_handler); -cache_error: - if (efreet_desktop_cache) eina_hash_free(efreet_desktop_cache); -edd_error: - eina_log_domain_unregister(_efreet_desktop_log_dom); - return 0; } /** @@ -222,25 +139,14 @@ efreet_desktop_shutdown(void) Efreet_Desktop_Type_Info *info; char *dir; - if (efreet_desktop_exe_handler) ecore_event_handler_del(efreet_desktop_exe_handler); IF_RELEASE(desktop_environment); IF_FREE_HASH(efreet_desktop_cache); EINA_LIST_FREE(efreet_desktop_types, info) efreet_desktop_type_info_free(info); EINA_LIST_FREE(efreet_desktop_dirs, dir) eina_stringshare_del(dir); - if (cache_monitor) ecore_file_monitor_del(cache_monitor); if (change_monitors) eina_hash_free(change_monitors); - if (cache) eet_close(cache); - efreet_desktop_edd_shutdown(); eina_log_domain_unregister(_efreet_desktop_log_dom); - IF_RELEASE(cache_file); - IF_RELEASE(cache_dirs); - if (efreet_desktop_job) - { - ecore_job_del(efreet_desktop_job); - efreet_desktop_job = NULL; - } } /** @@ -299,7 +205,7 @@ efreet_desktop_get(const char *file) p = dirname(buf); if (!eina_list_search_unsorted(efreet_desktop_dirs, EINA_COMPARE_CB(strcmp), p)) efreet_desktop_dirs = eina_list_append(efreet_desktop_dirs, eina_stringshare_add(p)); - efreet_desktop_update_cache(); + efreet_cache_desktop_update(); } if (efreet_desktop_cache) eina_hash_add(efreet_desktop_cache, desktop->orig_path, desktop); @@ -356,16 +262,11 @@ efreet_desktop_new(const char *file) Efreet_Desktop *desktop = NULL; if (!file) return NULL; - if (cache) + desktop = efreet_cache_desktop_find(file); + if (desktop) { - char rp[PATH_MAX]; - if (!realpath(file, rp)) return NULL; - - desktop = eet_data_read(cache, desktop_edd, rp); - if (desktop && desktop->load_time == ecore_file_mod_time(desktop->orig_path)) + if (desktop->load_time == ecore_file_mod_time(desktop->orig_path)) { - desktop->ref = 1; - desktop->eet = 1; if (!efreet_desktop_environment_check(desktop)) { efreet_desktop_free(desktop); @@ -373,6 +274,7 @@ efreet_desktop_new(const char *file) } return desktop; } + efreet_desktop_free(desktop); } return efreet_desktop_uncached_new(file); } @@ -510,22 +412,7 @@ efreet_desktop_free(Efreet_Desktop *desktop) { eina_hash_del_by_key(efreet_desktop_cache, desktop->orig_path); } - else if (old_caches) - { - Efreet_Old_Cache *d; - Efreet_Desktop *curr; - Eina_List *l; - - EINA_LIST_FOREACH(old_caches, l, d) - { - curr = eina_hash_find(d->desktop_cache, desktop->orig_path); - if (curr && curr == desktop) - { - eina_hash_del_by_key(d->desktop_cache, desktop->orig_path); - break; - } - } - } + efreet_cache_desktop_free(desktop); } if (desktop->eet) @@ -838,49 +725,127 @@ efreet_desktop_string_list_join(Eina_List *list) return string; } -/* - * Needs EAPI because of helper binaries - */ -EAPI const char * -efreet_desktop_cache_file(void) +int +efreet_desktop_write_cache_dirs_file(void) { - char tmp[PATH_MAX] = { '\0' }; - const char *home, *lang, *country, *modifier; + char file[PATH_MAX]; + int fd = -1; + int cachefd = -1; + char *dir; + struct stat st; + struct flock fl; - if (cache_file) return cache_file; + if (!efreet_desktop_dirs) return 1; - home = efreet_home_dir_get(); - lang = efreet_lang_get(); - country = efreet_lang_country_get(); - modifier = efreet_lang_modifier_get(); + snprintf(file, sizeof(file), "%s/.efreet/desktop_data.lock", efreet_home_dir_get()); + fd = open(file, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); + if (fd < 0) return 0; + /* TODO: Retry update cache later */ + memset(&fl, 0, sizeof(struct flock)); + fl.l_type = F_WRLCK; + fl.l_whence = SEEK_SET; + if (fcntl(fd, F_SETLK, &fl) < 0) goto error; - if (lang && country && modifier) - snprintf(tmp, sizeof(tmp), "%s/.efreet/desktop_%s_%s@%s.cache", home, lang, country, modifier); - else if (lang && country) - snprintf(tmp, sizeof(tmp), "%s/.efreet/desktop_%s_%s.cache", home, lang, country); - else if (lang) - snprintf(tmp, sizeof(tmp), "%s/.efreet/desktop_%s.cache", home, lang); - else - snprintf(tmp, sizeof(tmp), "%s/.efreet/desktop.cache", home); + cachefd = open(efreet_desktop_cache_dirs(), O_CREAT | O_APPEND | O_RDWR, S_IRUSR | S_IWUSR); + if (cachefd < 0) goto error; + if (fstat(cachefd, &st) < 0) goto error; + if (st.st_size > 0) + { + Eina_List *l, *ln; + char *p; + char *map; - cache_file = eina_stringshare_add(tmp); - return cache_file; + map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, cachefd, 0); + if (map == MAP_FAILED) goto error; + p = map; + while (p < map + st.st_size) + { + unsigned int size = *(unsigned int *)p; + p += sizeof(unsigned int); + EINA_LIST_FOREACH_SAFE(efreet_desktop_dirs, l, ln, dir) + { + if (!strcmp(dir, p)) + { + efreet_desktop_dirs = eina_list_remove_list(efreet_desktop_dirs, l); + eina_stringshare_del(dir); + break; + } + } + p += size; + } + munmap(map, st.st_size); + } + EINA_LIST_FREE(efreet_desktop_dirs, dir) + { + unsigned int size = strlen(dir) + 1; + size_t count; + + count = write(cachefd, &size, sizeof(int)); + count += write(cachefd, dir, size); + + if (count != sizeof(int) + size) + DBG("Didn't write all data on cachefd"); + + efreet_desktop_changes_monitor_add(dir); + eina_stringshare_del(dir); + } + efreet_desktop_dirs = NULL; + if (fd >= 0) close(fd); + if (cachefd >= 0) close(cachefd); + return 1; + +error: + if (fd >= 0) close(fd); + if (cachefd >= 0) close(cachefd); + return 0; } -/* - * Needs EAPI because of helper binaries - */ -EAPI const char * -efreet_desktop_cache_dirs(void) +void +efreet_desktop_changes_listen(void) { - char tmp[PATH_MAX] = { '\0' }; + int dirsfd = -1; + Eina_List *dirs; + char *path; + struct stat st; - if (cache_dirs) return cache_dirs; + change_monitors = eina_hash_string_superfast_new(EINA_FREE_CB(ecore_file_monitor_del)); + if (!change_monitors) return; - snprintf(tmp, sizeof(tmp), "%s/.efreet/desktop_dirs.cache", efreet_home_dir_get()); + dirs = efreet_default_dirs_get(efreet_data_home_get(), + efreet_data_dirs_get(), "applications"); - cache_dirs = eina_stringshare_add(tmp); - return cache_dirs; + EINA_LIST_FREE(dirs, path) + { + efreet_desktop_changes_listen_recursive(path); + eina_stringshare_del(path); + } + + dirsfd = open(efreet_desktop_cache_dirs(), O_RDONLY, S_IRUSR | S_IWUSR); + if (dirsfd >= 0) + { + if ((fstat(dirsfd, &st) == 0) && (st.st_size > 0)) + { + char *p; + char *map; + + map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, dirsfd, 0); + if (map == MAP_FAILED) goto error; + p = map; + while (p < map + st.st_size) + { + unsigned int size = *(unsigned int *)p; + p += sizeof(unsigned int); + efreet_desktop_changes_monitor_add(p); + p += size; + } + munmap(map, st.st_size); + } + close(dirsfd); + } + + return; +error: + if (dirsfd >= 0) close(dirsfd); } /** @@ -1293,318 +1258,6 @@ efreet_desktop_environment_check(Efreet_Desktop *desktop) return 1; } -/* - * Needs EAPI because of helper binaries - */ -EAPI Eet_Data_Descriptor * -efreet_desktop_edd_init(void) -{ - if (!desktop_edd) - { - Eet_Data_Descriptor_Class eddc; - - EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Desktop); - desktop_edd = eet_data_descriptor_file_new(&eddc); - if (!desktop_edd) return NULL; - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "type", type, EET_T_INT); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "version", version, EET_T_STRING); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "orig_path", orig_path, EET_T_STRING); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "load_time", load_time, EET_T_LONG_LONG); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "name", name, EET_T_STRING); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "generic_name", generic_name, EET_T_STRING); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "comment", comment, EET_T_STRING); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "icon", icon, EET_T_STRING); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "try_exec", try_exec, EET_T_STRING); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "exec", exec, EET_T_STRING); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "path", path, EET_T_STRING); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "startup_wm_class", startup_wm_class, EET_T_STRING); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "url", url, EET_T_STRING); - eet_data_descriptor_element_add(desktop_edd, "only_show_in", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Desktop, only_show_in), 0, NULL, NULL); - eet_data_descriptor_element_add(desktop_edd, "not_show_in", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Desktop, not_show_in), 0, NULL, NULL); - eet_data_descriptor_element_add(desktop_edd, "categories", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Desktop, categories), 0, NULL, NULL); - eet_data_descriptor_element_add(desktop_edd, "mime_types", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Desktop, mime_types), 0, NULL, NULL); - eet_data_descriptor_element_add(desktop_edd, "x", EET_T_STRING, EET_G_HASH, offsetof(Efreet_Desktop, x), 0, NULL, NULL); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "no_display", no_display, EET_T_UCHAR); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "hidden", hidden, EET_T_UCHAR); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "terminal", terminal, EET_T_UCHAR); - EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Desktop, "startup_notify", startup_notify, EET_T_UCHAR); - } - return desktop_edd; -} - -static void -efreet_desktop_edd_shutdown(void) -{ - if (desktop_edd) eet_data_descriptor_free(desktop_edd); - desktop_edd = NULL; -} - -static int -efreet_desktop_write_cache_dirs_file(void) -{ - char file[PATH_MAX]; - int fd = -1; - int cachefd = -1; - char *dir; - struct stat st; - struct flock fl; - - if (!efreet_desktop_dirs) return 1; - - snprintf(file, sizeof(file), "%s/.efreet/desktop_data.lock", efreet_home_dir_get()); - fd = open(file, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); - if (fd < 0) return 0; - /* TODO: Retry update cache later */ - memset(&fl, 0, sizeof(struct flock)); - fl.l_type = F_WRLCK; - fl.l_whence = SEEK_SET; - if (fcntl(fd, F_SETLK, &fl) < 0) goto error; - - cachefd = open(efreet_desktop_cache_dirs(), O_CREAT | O_APPEND | O_RDWR, S_IRUSR | S_IWUSR); - if (cachefd < 0) goto error; - if (fstat(cachefd, &st) < 0) goto error; - if (st.st_size > 0) - { - Eina_List *l, *ln; - char *p; - char *map; - - map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, cachefd, 0); - if (map == MAP_FAILED) goto error; - p = map; - while (p < map + st.st_size) - { - unsigned int size = *(unsigned int *)p; - p += sizeof(unsigned int); - EINA_LIST_FOREACH_SAFE(efreet_desktop_dirs, l, ln, dir) - { - if (!strcmp(dir, p)) - { - efreet_desktop_dirs = eina_list_remove_list(efreet_desktop_dirs, l); - eina_stringshare_del(dir); - break; - } - } - p += size; - } - munmap(map, st.st_size); - } - EINA_LIST_FREE(efreet_desktop_dirs, dir) - { - unsigned int size = strlen(dir) + 1; - size_t count; - - count = write(cachefd, &size, sizeof(int)); - count += write(cachefd, dir, size); - - if (count != sizeof(int) + size) - DBG("Didn't write all data on cachefd"); - - efreet_desktop_changes_monitor_add(dir); - eina_stringshare_del(dir); - } - efreet_desktop_dirs = NULL; - if (fd >= 0) close(fd); - if (cachefd >= 0) close(cachefd); - return 1; - -error: - if (fd >= 0) close(fd); - if (cachefd >= 0) close(cachefd); - return 0; -} - -static void -efreet_desktop_cache_update_cb(void *data __UNUSED__, Ecore_File_Monitor *em __UNUSED__, - Ecore_File_Event event, const char *path) -{ - Eet_File *tmp; - Efreet_Event_Cache_Update *ev = NULL; - Efreet_Old_Cache *d = NULL; - - if (strcmp(path, efreet_desktop_cache_file())) return; - if (event != ECORE_FILE_EVENT_CREATED_FILE && - event != ECORE_FILE_EVENT_MODIFIED) return; - - tmp = eet_open(efreet_desktop_cache_file(), EET_FILE_MODE_READ); - if (!tmp) return; - ev = NEW(Efreet_Event_Cache_Update, 1); - if (!ev) goto error; - d = NEW(Efreet_Old_Cache, 1); - if (!d) goto error; - - d->desktop_cache = efreet_desktop_cache; - d->cache = cache; - old_caches = eina_list_append(old_caches, d); - - efreet_desktop_cache = eina_hash_string_superfast_new(NULL); - cache = tmp; - - efreet_util_desktop_cache_reload(); - ecore_event_add(EFREET_EVENT_DESKTOP_CACHE_UPDATE, ev, efreet_desktop_cache_update_free, d); - return; -error: - IF_FREE(ev); - IF_FREE(d); - eet_close(tmp); -} - -static void -efreet_desktop_cache_update_free(void *data, void *ev) -{ - Efreet_Old_Cache *d; - int dangling = 0; - - d = data; - /* - * All users should now had the chance to update their pointers, so we can now - * free the old cache - */ - if (d->desktop_cache) - { - Eina_Iterator *it; - Eina_Hash_Tuple *tuple; - - it = eina_hash_iterator_tuple_new(d->desktop_cache); - EINA_ITERATOR_FOREACH(it, tuple) - { - printf("Efreet: %d:%s still in cache on cache close!\n", - ((Efreet_Desktop *)tuple->data)->ref, (char *)tuple->key); - dangling++; - } - eina_iterator_free(it); - - eina_hash_free(d->desktop_cache); - } - /* - * If there are dangling references the eet file won't be closed - to - * avoid crashes, but this will leak instead. - */ - if (dangling == 0) - { - if (d->cache) eet_close(d->cache); - } - else - { - printf("Efreet: ERROR. There are still %i desktop files with old\n" - "dangling references to desktop files. This application\n" - "has not handled the EFREET_EVENT_DESKTOP_CACHE_UPDATE\n" - "fully and released its references. Please fix the application\n" - "so it does this.\n", - dangling); - } - old_caches = eina_list_remove(old_caches, d); - free(d); - free(ev); -} - -static void -efreet_desktop_update_cache(void) -{ - if (!efreet_cache_update) return; - - /* TODO: Make sure we don't create a lot of execs, maybe use a timer? */ - if (efreet_desktop_job) ecore_job_del(efreet_desktop_job); - efreet_desktop_job = ecore_job_add(efreet_desktop_update_cache_job, NULL); -} - -static void -efreet_desktop_update_cache_job(void *data __UNUSED__) -{ - char file[PATH_MAX]; - struct flock fl; - - efreet_desktop_job = NULL; - - /* TODO: Retry update cache later */ - if (efreet_desktop_exe_lock > 0) return; - - if (!efreet_desktop_write_cache_dirs_file()) return; - - snprintf(file, sizeof(file), "%s/.efreet/desktop_exec.lock", efreet_home_dir_get()); - - efreet_desktop_exe_lock = open(file, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); - if (efreet_desktop_exe_lock < 0) return; - memset(&fl, 0, sizeof(struct flock)); - fl.l_type = F_WRLCK; - fl.l_whence = SEEK_SET; - if (fcntl(efreet_desktop_exe_lock, F_SETLK, &fl) < 0) goto error; - efreet_desktop_exe = ecore_exe_run(PACKAGE_LIB_DIR "/efreet/efreet_desktop_cache_create", NULL); - if (!efreet_desktop_exe) goto error; - - return; - -error: - if (efreet_desktop_exe_lock > 0) - { - close(efreet_desktop_exe_lock); - efreet_desktop_exe_lock = -1; - } -} - -static Eina_Bool -efreet_desktop_exe_cb(void *data __UNUSED__, int type __UNUSED__, void *event) -{ - Ecore_Exe_Event_Del *ev; - - ev = event; - if (ev->exe != efreet_desktop_exe) return ECORE_CALLBACK_RENEW; - if (efreet_desktop_exe_lock > 0) - { - close(efreet_desktop_exe_lock); - efreet_desktop_exe_lock = -1; - } - return ECORE_CALLBACK_RENEW; -} - -static void -efreet_desktop_changes_listen(void) -{ - int dirsfd = -1; - Eina_List *dirs; - char *path; - struct stat st; - - change_monitors = eina_hash_string_superfast_new(EINA_FREE_CB(ecore_file_monitor_del)); - if (!change_monitors) return; - - dirs = efreet_default_dirs_get(efreet_data_home_get(), - efreet_data_dirs_get(), "applications"); - - EINA_LIST_FREE(dirs, path) - { - efreet_desktop_changes_listen_recursive(path); - eina_stringshare_del(path); - } - - dirsfd = open(efreet_desktop_cache_dirs(), O_RDONLY, S_IRUSR | S_IWUSR); - if (dirsfd >= 0) - { - if ((fstat(dirsfd, &st) == 0) && (st.st_size > 0)) - { - char *p; - char *map; - - map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, dirsfd, 0); - if (map == MAP_FAILED) goto error; - p = map; - while (p < map + st.st_size) - { - unsigned int size = *(unsigned int *)p; - p += sizeof(unsigned int); - efreet_desktop_changes_monitor_add(p); - p += size; - } - munmap(map, st.st_size); - } - close(dirsfd); - } - - return; -error: - if (dirsfd >= 0) close(dirsfd); -} - static void efreet_desktop_changes_listen_recursive(const char *path) { @@ -1653,18 +1306,18 @@ efreet_desktop_changes_cb(void *data __UNUSED__, Ecore_File_Monitor *em __UNUSED case ECORE_FILE_EVENT_CREATED_FILE: case ECORE_FILE_EVENT_DELETED_FILE: case ECORE_FILE_EVENT_MODIFIED: - efreet_desktop_update_cache(); + efreet_cache_desktop_update(); break; case ECORE_FILE_EVENT_DELETED_SELF: case ECORE_FILE_EVENT_DELETED_DIRECTORY: eina_hash_del_by_key(change_monitors, path); - efreet_desktop_update_cache(); + efreet_cache_desktop_update(); break; case ECORE_FILE_EVENT_CREATED_DIRECTORY: efreet_desktop_changes_monitor_add(path); - efreet_desktop_update_cache(); + efreet_cache_desktop_update(); break; } } diff --git a/legacy/efreet/src/lib/efreet_private.h b/legacy/efreet/src/lib/efreet_private.h index 676142dcee..fba3592b41 100644 --- a/legacy/efreet/src/lib/efreet_private.h +++ b/legacy/efreet/src/lib/efreet_private.h @@ -136,6 +136,8 @@ extern int _efreet_log_dom_global; #endif #define WRN(...) EINA_LOG_DOM_WARN(EFREET_MODULE_LOG_DOM, __VA_ARGS__) +extern Eina_Hash *efreet_desktop_cache; + #ifdef ICON_CACHE typedef struct Efreet_Cache_Icon Efreet_Cache_Icon; struct Efreet_Cache_Icon @@ -208,6 +210,16 @@ void efreet_util_desktop_cache_reload(void); EAPI const char *efreet_desktop_util_cache_file(void); EAPI const char *efreet_desktop_cache_file(void); EAPI const char *efreet_desktop_cache_dirs(void); +int efreet_desktop_write_cache_dirs_file(void); +void efreet_desktop_changes_listen(void); + +void efreet_cache_desktop_update(void); +void efreet_cache_icon_update(void); +void efreet_cache_desktop_free(Efreet_Desktop *desktop); +Efreet_Desktop *efreet_cache_desktop_find(const char *file); +#if 0 +void efreet_icon_update_cache(void); +#endif #ifdef ICON_CACHE EAPI const char *efreet_icon_cache_file(const char *theme);