static Eet_Data_Descriptor *array_string_edd = NULL;
static Eet_Data_Descriptor *hash_string_edd = NULL;
+static Eina_Hash *desktops = NULL;
static Efreet_Cache_Array_String *desktop_dirs = NULL;
static Eet_File *desktop_cache = NULL;
static const char *desktop_cache_file = NULL;
themes = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_icon_theme_free));
icons = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_icon_free));
fallbacks = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_icon_fallback_free));
+ desktops = eina_hash_string_superfast_new(NULL);
snprintf(buf, sizeof(buf), "%s/efreet", efreet_cache_home_get());
if (!ecore_file_exists(buf))
icons = NULL;
if (fallbacks) eina_hash_free(fallbacks);
fallbacks = NULL;
+ if (desktops) eina_hash_free(desktops);
+ desktops = NULL;
if (cache_exe_handler) ecore_event_handler_del(cache_exe_handler);
cache_exe_handler = NULL;
IF_FREE_HASH(icons);
IF_FREE_HASH(fallbacks);
+ IF_FREE_HASH_CB(desktops, EINA_FREE_CB(efreet_cache_desktop_free));
efreet_cache_array_string_free(desktop_dirs);
desktop_dirs = NULL;
desktop_cache = efreet_cache_close(desktop_cache);
Efreet_Desktop *
efreet_cache_desktop_find(const char *file)
{
- Efreet_Desktop *desktop;
+ Efreet_Desktop *cache;
char rp[PATH_MAX];
if (!realpath(file, rp)) return NULL;
if (!efreet_cache_check(&desktop_cache, efreet_desktop_cache_file(), EFREET_DESKTOP_CACHE_MAJOR)) return NULL;
- desktop = eet_data_read(desktop_cache, efreet_desktop_edd(), rp);
- if (!desktop) return NULL;
- desktop->ref = 1;
- desktop->eet = 1;
- return desktop;
+ cache = eina_hash_find(desktops, rp);
+ if (cache == NON_EXISTING) return NULL;
+ if (cache) return cache;
+
+ cache = eet_data_read(desktop_cache, efreet_desktop_edd(), rp);
+ if (cache)
+ {
+ cache->eet = 1;
+ eina_hash_add(desktops, cache->orig_path, cache);
+ }
+ else
+ eina_hash_add(desktops, rp, NON_EXISTING);
+ return cache;
}
void
Efreet_Desktop *curr;
Eina_List *l;
- if (!old_desktop_caches) return;
+ if (!desktop ||
+ desktop == NON_EXISTING ||
+ !desktop->eet) return;
+
+ curr = eina_hash_find(desktops, desktop->orig_path);
+ if (curr == desktop)
+ eina_hash_del_by_key(desktops, desktop->orig_path);
EINA_LIST_FOREACH(old_desktop_caches, l, d)
{
break;
}
}
+
+ eina_list_free(desktop->only_show_in);
+ eina_list_free(desktop->not_show_in);
+ eina_list_free(desktop->categories);
+ eina_list_free(desktop->mime_types);
+ IF_FREE_HASH(desktop->x);
+ free(desktop);
}
void
d = NEW(Efreet_Old_Cache, 1);
if (!d) goto error;
- d->hash = efreet_desktop_cache;
+ d->hash = desktops;
d->ef = desktop_cache;
old_desktop_caches = eina_list_append(old_desktop_caches, d);
efreet_cache_array_string_free(desktop_dirs);
desktop_dirs = NULL;
- efreet_desktop_cache = eina_hash_string_superfast_new(NULL);
+ desktops = eina_hash_string_superfast_new(NULL);
desktop_cache = NULL;
efreet_cache_array_string_free(util_cache_names);
it = eina_hash_iterator_tuple_new(d->hash);
EINA_ITERATOR_FOREACH(it, tuple)
{
+ if (tuple->data == NON_EXISTING) continue;
printf("Efreet: %d:%s still in cache on cache close!\n",
((Efreet_Desktop *)tuple->data)->ref, (char *)tuple->key);
dangling++;
#define DESKTOP_VERSION "1.0"
/**
- * 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")
*/
static const char *desktop_environment = NULL;
}
#endif
- efreet_desktop_cache = eina_hash_string_superfast_new(NULL);
efreet_desktop_types = NULL;
EFREET_DESKTOP_TYPE_APPLICATION = efreet_desktop_type_add("Application",
Efreet_Desktop_Type_Info *info;
IF_RELEASE(desktop_environment);
- IF_FREE_HASH(efreet_desktop_cache);
EINA_LIST_FREE(efreet_desktop_types, info)
efreet_desktop_type_info_free(info);
IF_FREE_HASH(change_monitors);
/**
* @param file The file to get the Efreet_Desktop from
* @return Returns a reference to a cached Efreet_Desktop on success, NULL
- * on failure. This reference should not be freed.
+ * on failure
* @brief Gets a reference to an Efreet_Desktop structure representing the
* contents of @a file or NULL if @a file is not a valid .desktop file.
*
* By using efreet_desktop_get the Efreet_Desktop will be saved in an internal
- * cache, and changes will be signalled by events.
- *
- * Efreet will also try to save all files fetched by efreet_desktop_get in a
- * cache to speed up further requests.
+ * cache for quicker loading.
*/
EAPI Efreet_Desktop *
efreet_desktop_get(const char *file)
{
- /* TODO: Check if we need to differentiate between desktop_new and desktop_get */
Efreet_Desktop *desktop;
- if (!file) return NULL;
- if (efreet_desktop_cache)
- {
- char rp[PATH_MAX];
-
- if (!realpath(file, rp)) return NULL;
- desktop = eina_hash_find(efreet_desktop_cache, rp);
- if (desktop)
- {
- if (efreet_desktop_cache_check(desktop))
- {
- desktop->ref++;
- return desktop;
- }
-
- desktop->cached = 0;
- eina_hash_del_by_key(efreet_desktop_cache, rp);
- }
- }
-
desktop = efreet_desktop_new(file);
if (!desktop) return NULL;
+ /* If we didn't find this file in the eet cache, add path to search path */
if (!desktop->eet)
efreet_cache_desktop_add(desktop);
- if (efreet_desktop_cache) eina_hash_direct_add(efreet_desktop_cache, desktop->orig_path, desktop);
- desktop->cached = 1;
return desktop;
}
}
/**
- * @param file The file to create the Efreet_Desktop from
- * @return Returns a new Efreet_Desktop on success, NULL on failure
- * @brief Creates a new Efreet_Desktop structure initialized from the
- * contents of @a file or NULL on failure
- *
- * By using efreet_desktop_new the caller will get a unique copy of a
- * Efreet_Desktop. The Efreet_Desktop should immidiatly after use be free'd,
- * as there is no guarantee how long the pointers will be valid.
+ * @param file The file to get the Efreet_Desktop from
+ * @return Returns a reference to a cached Efreet_Desktop on success, NULL
+ * on failure
+ * @brief Gets a reference to an Efreet_Desktop structure representing the
+ * contents of @a file or NULL if @a file is not a valid .desktop file.
*/
EAPI Efreet_Desktop *
efreet_desktop_new(const char *file)
desktop = efreet_cache_desktop_find(file);
if (desktop)
{
- if (desktop->load_time == ecore_file_mod_time(desktop->orig_path))
+ desktop->ref++;
+ if (efreet_desktop_cache_check(desktop))
{
if (!efreet_desktop_environment_check(desktop))
{
* @param file The filename to save as
* @return Returns 1 on success or 0 on failure
* @brief Saves @a desktop to @a file
+ *
+ * Please use efreet_desktop_uncached_new() on an existing file
+ * before using efreet_desktop_save_as()
*/
EAPI int
efreet_desktop_save_as(Efreet_Desktop *desktop, const char *file)
{
- if (desktop->cached && efreet_desktop_cache &&
- desktop == eina_hash_find(efreet_desktop_cache, desktop->orig_path))
- {
- desktop->cached = 0;
- eina_hash_del_by_key(efreet_desktop_cache, desktop->orig_path);
- }
- FREE(desktop->orig_path);
+ /* If we save data from eet as new, we will be in trouble */
+ if (desktop->eet) return 0;
+
+ IF_FREE(desktop->orig_path);
desktop->orig_path = strdup(file);
return efreet_desktop_save(desktop);
}
desktop->ref--;
if (desktop->ref > 0) return;
- if (desktop->cached)
- {
- if (efreet_desktop_cache &&
- desktop == eina_hash_find(efreet_desktop_cache, desktop->orig_path))
- {
- eina_hash_del_by_key(efreet_desktop_cache, desktop->orig_path);
- }
- efreet_cache_desktop_free(desktop);
- }
-
if (desktop->eet)
{
- eina_list_free(desktop->only_show_in);
- eina_list_free(desktop->not_show_in);
- eina_list_free(desktop->categories);
- eina_list_free(desktop->mime_types);
- IF_FREE_HASH(desktop->x);
+ efreet_cache_desktop_free(desktop);
}
else
{
if (info->free_func)
info->free_func(desktop->type_data);
}
+ free(desktop);
}
- FREE(desktop);
}
/**