efreet: Implement fields added by desktop spec 1.1

This commit is contained in:
Sebastian Dransfeld 2014-09-25 08:47:18 +02:00
parent c700192736
commit 793fd5e847
5 changed files with 206 additions and 1 deletions

View File

@ -40,6 +40,7 @@ static Eina_Hash *generic_name = NULL;
static Eina_Hash *comment = NULL;
static Eina_Hash *exec = NULL;
static Eina_Hash *environments = NULL;
static Eina_Hash *keywords = NULL;
static int
cache_add(const char *path, const char *file_id, int priority EINA_UNUSED, int *changed)
@ -112,6 +113,7 @@ cache_add(const char *path, const char *file_id, int priority EINA_UNUSED, int *
array->array[array->array_count++] = desk->orig_path; \
eina_hash_set((hash), data, array); \
}
/* Desktop Spec 1.0 */
ADD_LIST(desk->mime_types, mime_types);
ADD_LIST(desk->categories, categories);
ADD_ELEM(desk->startup_wm_class, startup_wm_class);
@ -123,6 +125,8 @@ cache_add(const char *path, const char *file_id, int priority EINA_UNUSED, int *
ADD_LIST(desk->not_show_in, environments);
eina_hash_add(file_ids, file_id, desk->orig_path);
eina_hash_add(desktops, desk->orig_path, desk);
/* Desktop Spec 1.1 */
ADD_LIST(desk->keywords, keywords);
}
else
efreet_desktop_free(desk);
@ -388,6 +392,7 @@ main(int argc, char **argv)
comment = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_array_string_free));
exec = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_array_string_free));
environments = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_array_string_free));
keywords = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_array_string_free));
dirs = efreet_default_dirs_get(efreet_data_home_get(), efreet_data_dirs_get(),
"applications");
@ -438,6 +443,7 @@ main(int argc, char **argv)
STORE_HASH_ARRAY(comment);
STORE_HASH_ARRAY(exec);
STORE_HASH_ARRAY(environments);
STORE_HASH_ARRAY(keywords);
if (eina_hash_population(file_ids) > 0)
{
hash.hash = file_ids;
@ -452,6 +458,7 @@ main(int argc, char **argv)
eina_hash_free(comment);
eina_hash_free(exec);
eina_hash_free(environments);
eina_hash_free(keywords);
if (old_file_ids)
{

View File

@ -71,6 +71,7 @@ static const char *theme_name = NULL;
static Eet_Data_Descriptor *version_edd = NULL;
static Eet_Data_Descriptor *desktop_edd = NULL;
static Eet_Data_Descriptor *desktop_action_edd = NULL;
static Eet_Data_Descriptor *hash_array_string_edd = NULL;
static Eet_Data_Descriptor *array_string_edd = NULL;
static Eet_Data_Descriptor *hash_string_edd = NULL;
@ -429,6 +430,7 @@ efreet_cache_edd_shutdown(void)
{
EDD_SHUTDOWN(version_edd);
EDD_SHUTDOWN(desktop_edd);
EDD_SHUTDOWN(desktop_action_edd);
EDD_SHUTDOWN(hash_array_string_edd);
EDD_SHUTDOWN(array_string_edd);
EDD_SHUTDOWN(hash_string_edd);
@ -607,10 +609,21 @@ efreet_desktop_edd(void)
if (desktop_edd) return desktop_edd;
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Desktop_Action);
desktop_action_edd = eet_data_descriptor_file_new(&eddc);
if (!desktop_action_edd) return NULL;
/* Desktop Spec 1.1 */
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_action_edd, Efreet_Desktop_Action, "key", key, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_action_edd, Efreet_Desktop_Action, "name", name, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_action_edd, Efreet_Desktop_Action, "icon", icon, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_action_edd, Efreet_Desktop_Action, "exec", exec, EET_T_STRING);
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Cache_Desktop);
desktop_edd = eet_data_descriptor_file_new(&eddc);
if (!desktop_edd) return NULL;
/* Desktop Spec 1.0 */
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Cache_Desktop, "type", desktop.type, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Cache_Desktop, "version", desktop.version, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Cache_Desktop, "orig_path", desktop.orig_path, EET_T_STRING);
@ -634,6 +647,13 @@ efreet_desktop_edd(void)
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Cache_Desktop, "terminal", desktop.terminal, EET_T_UCHAR);
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Cache_Desktop, "startup_notify", desktop.startup_notify, EET_T_UCHAR);
/* Desktop Spec 1.1 */
EET_DATA_DESCRIPTOR_ADD_BASIC(desktop_edd, Efreet_Cache_Desktop, "dbus_activatable", desktop.dbus_activatable, EET_T_UCHAR);
EET_DATA_DESCRIPTOR_ADD_LIST(desktop_edd, Efreet_Cache_Desktop,
"actions", desktop.actions, desktop_action_edd);
eet_data_descriptor_element_add(desktop_edd, "implements", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Cache_Desktop, desktop.implements), 0, NULL, NULL);
eet_data_descriptor_element_add(desktop_edd, "keywords", EET_T_STRING, EET_G_LIST, offsetof(Efreet_Cache_Desktop, desktop.keywords), 0, NULL, NULL);
return desktop_edd;
}
@ -886,11 +906,17 @@ efreet_cache_desktop_free(Efreet_Desktop *desktop)
}
}
/* Desktop Spec 1.0 */
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);
/* Desktop Spec 1.1 */
eina_list_free(desktop->actions);
eina_list_free(desktop->implements);
eina_list_free(desktop->keywords);
free(desktop);
eina_lock_release(&_lock);
}

View File

@ -1,7 +1,7 @@
#ifndef EFREET_CACHE_PRIVATE_H
#define EFREET_CACHE_PRIVATE_H
#define EFREET_DESKTOP_CACHE_MAJOR 1
#define EFREET_DESKTOP_CACHE_MAJOR 2
#define EFREET_DESKTOP_CACHE_MINOR 0
#define EFREET_DESKTOP_UTILS_CACHE_MAJOR 1
#define EFREET_DESKTOP_UTILS_CACHE_MINOR 0

View File

@ -52,8 +52,11 @@ static Efreet_Desktop_Type_Info *efreet_desktop_type_parse(const char *type_str)
static void efreet_desktop_type_info_free(Efreet_Desktop_Type_Info *info);
static void *efreet_desktop_application_fields_parse(Efreet_Desktop *desktop,
Efreet_Ini *ini);
static Eina_List *efreet_desktop_action_fields_parse(Efreet_Ini *ini, const char *val);
static void efreet_desktop_application_fields_save(Efreet_Desktop *desktop,
Efreet_Ini *ini);
static void efreet_desktop_action_fields_save(Efreet_Desktop *desktop,
Efreet_Ini *ini);
static void *efreet_desktop_link_fields_parse(Efreet_Desktop *desktop,
Efreet_Ini *ini);
static void efreet_desktop_link_fields_save(Efreet_Desktop *desktop,
@ -349,6 +352,9 @@ efreet_desktop_free(Efreet_Desktop *desktop)
}
else
{
Efreet_Desktop_Action *action;
/* Desktop Spec 1.0 */
IF_FREE(desktop->orig_path);
IF_FREE(desktop->version);
@ -378,6 +384,19 @@ efreet_desktop_free(Efreet_Desktop *desktop)
if (info->free_func)
info->free_func(desktop->type_data);
}
/* Desktop Spec 1.1 */
EINA_LIST_FREE(desktop->actions, action)
{
free(action->key);
free(action->name);
free(action->icon);
free(action->exec);
free(action);
}
IF_FREE_LIST(desktop->implements, eina_stringshare_del);
IF_FREE_LIST(desktop->keywords, eina_stringshare_del);
free(desktop);
}
eina_lock_release(&_lock);
@ -710,6 +729,7 @@ efreet_desktop_application_fields_parse(Efreet_Desktop *desktop, Efreet_Ini *ini
{
const char *val;
/* Desktop Spec 1.0 */
val = efreet_ini_string_get(ini, "TryExec");
if (val) desktop->try_exec = strdup(val);
@ -731,9 +751,59 @@ efreet_desktop_application_fields_parse(Efreet_Desktop *desktop, Efreet_Ini *ini
desktop->terminal = efreet_ini_boolean_get(ini, "Terminal");
desktop->startup_notify = efreet_ini_boolean_get(ini, "StartupNotify");
/* Desktop Spec 1.1 */
val = efreet_ini_string_get(ini, "Actions");
if (val)
desktop->actions = efreet_desktop_action_fields_parse(ini, val);
val = efreet_ini_string_get(ini, "Keywords");
if (val)
desktop->keywords = efreet_desktop_string_list_parse(val);
return NULL;
}
/**
* @internal
* @param key the key to look up Desktop Action entry
* @return list of Desktop Actions
*/
static Eina_List *
efreet_desktop_action_fields_parse(Efreet_Ini *ini, const char *actions)
{
Eina_List *l;
Eina_List *ret = NULL;
const char *section;
const char *key;
// TODO: section = efreet_ini_section_get(ini);
section = "Desktop Entry";
l = efreet_desktop_string_list_parse(actions);
EINA_LIST_FREE(l, key)
{
char entry[4096];
Efreet_Desktop_Action *act;
snprintf(entry, sizeof(entry), "Desktop Action %s", key);
if (!efreet_ini_section_set(ini, entry)) continue;
act = NEW(Efreet_Desktop_Action, 1);
if (!act) continue;
ret = eina_list_append(ret, act);
act->key = strdup(key);
act->name = eina_strdup(efreet_ini_localestring_get(ini, "Name"));
act->icon = eina_strdup(efreet_ini_localestring_get(ini, "Icon"));
act->exec = eina_strdup(efreet_ini_string_get(ini, "Exec"));
/* TODO: Non-standard keys OnlyShowIn, NotShowIn used by Unity */
eina_stringshare_del(key);
}
efreet_ini_section_set(ini, section);
return ret;
}
/**
* @internal
* @param desktop the Efreet_Desktop to save fields from
@ -746,6 +816,7 @@ efreet_desktop_application_fields_save(Efreet_Desktop *desktop, Efreet_Ini *ini)
{
char *val;
/* Desktop Spec 1.0 */
if (desktop->try_exec)
efreet_ini_string_set(ini, "TryExec", desktop->try_exec);
@ -780,6 +851,60 @@ efreet_desktop_application_fields_save(Efreet_Desktop *desktop, Efreet_Ini *ini)
efreet_ini_boolean_set(ini, "Terminal", desktop->terminal);
efreet_ini_boolean_set(ini, "StartupNotify", desktop->startup_notify);
/* Desktop Spec 1.1 */
if (desktop->actions)
efreet_desktop_action_fields_save(desktop, ini);
if (desktop->keywords)
{
val = efreet_desktop_string_list_join(desktop->keywords);
if (val)
{
efreet_ini_string_set(ini, "Keywords", val);
free(val);
}
}
}
/**
* @internal
* @param desktop the Efreet_Desktop to save fields from
* @param ini the Efreet_Ini to save fields to
* @return Returns no value
* @brief Save action specific desktop fields
*/
static void
efreet_desktop_action_fields_save(Efreet_Desktop *desktop, Efreet_Ini *ini)
{
Eina_List *actions = NULL, *l;
const char *section;
char *join;
Efreet_Desktop_Action *action;
// TODO: section = efreet_ini_section_get(ini);
section = "Desktop Entry";
EINA_LIST_FOREACH(desktop->actions, l, action)
{
char entry[4096];
actions = eina_list_append(actions, action->key);
snprintf(entry, sizeof(entry), "Desktop Action %s", action->key);
efreet_ini_section_add(ini, entry);
efreet_ini_section_set(ini, entry);
efreet_ini_localestring_set(ini, "Name", action->name);
efreet_ini_localestring_set(ini, "Icon", action->icon);
efreet_ini_string_set(ini, "Exec", action->exec);
}
efreet_ini_section_set(ini, section);
join = efreet_desktop_string_list_join(actions);
if (join)
{
efreet_ini_string_set(ini, "Actions", join);
free(join);
}
eina_list_free(actions);
}
/**
@ -824,6 +949,7 @@ efreet_desktop_generic_fields_parse(Efreet_Desktop *desktop, Efreet_Ini *ini)
{
const char *val;
/* Desktop Spec 1.0 */
val = efreet_ini_localestring_get(ini, "Name");
#ifndef STRICT_SPEC
if (!val) val = efreet_ini_localestring_get(ini, "_Name");
@ -855,6 +981,10 @@ efreet_desktop_generic_fields_parse(Efreet_Desktop *desktop, Efreet_Ini *ini)
val = efreet_ini_string_get(ini, "NotShowIn");
if (val) desktop->not_show_in = efreet_desktop_string_list_parse(val);
/* Desktop Spec 1.1 */
desktop->dbus_activatable = efreet_ini_boolean_get(ini, "DBusActivatable");
val = efreet_ini_string_get(ini, "Implements");
if (val) desktop->implements = efreet_desktop_string_list_parse(val);
return 1;
}
@ -870,6 +1000,7 @@ efreet_desktop_generic_fields_save(Efreet_Desktop *desktop, Efreet_Ini *ini)
{
const char *val;
/* Desktop Spec 1.0 */
if (desktop->name)
{
efreet_ini_localestring_set(ini, "Name", desktop->name);
@ -904,6 +1035,20 @@ efreet_desktop_generic_fields_save(Efreet_Desktop *desktop, Efreet_Ini *ini)
if (desktop->x) eina_hash_foreach(desktop->x, efreet_desktop_x_fields_save,
ini);
/* Desktop Spec 1.1 */
efreet_ini_boolean_set(ini, "DBusActivatable", desktop->dbus_activatable);
if (desktop->implements)
{
char *join;
join = efreet_desktop_string_list_join(desktop->implements);
if (join)
{
efreet_ini_string_set(ini, "Implements", join);
free(join);
}
}
}
/**
@ -997,3 +1142,4 @@ efreet_desktop_environment_check(Efreet_Desktop *desktop)
return 1;
}

View File

@ -29,6 +29,12 @@ EAPI extern int EFREET_EVENT_DESKTOP_CACHE_UPDATE;
*/
EAPI extern int EFREET_EVENT_DESKTOP_CACHE_BUILD;
/**
* Efreet_Desktop_Action
* @since 1.12
*/
typedef struct _Efreet_Desktop_Action Efreet_Desktop_Action;
/**
* Efreet_Desktop
*/
@ -61,12 +67,26 @@ typedef void (*Efreet_Desktop_Type_Save_Cb) (Efreet_Desktop *desktop, Efreet_Ini
*/
typedef void *(*Efreet_Desktop_Type_Free_Cb) (void *data);
/**
* Efreet_Desktop_Action
* @brief an action described in a .desktop file
* @since 1.12
*/
struct _Efreet_Desktop_Action
{
char *key; /**< Key to identify the action */
char *name; /**< Specific name of the action */
char *icon; /**< Icon to display */
char *exec; /**< Program to execute */
};
/**
* Efreet_Desktop
* @brief a parsed representation of a .desktop file
*/
struct _Efreet_Desktop
{
/* Desktop Spec 1.0 */
int type; /**< type of desktop file */
int ref; /**< reference count - internal */
@ -102,6 +122,12 @@ struct _Efreet_Desktop
Eina_Hash *x; /**< Keep track of all user extensions, keys that begin with X- */
void *type_data; /**< Type specific data for custom types */
/* Desktop Spec 1.1 */
unsigned char dbus_activatable; /**< Activate application by dbus, not Exec. @since 1.12 */
Eina_List *actions; /**< List of Efreet_Desktop_Actions, application actions. @since 1.12 */
Eina_List *implements; /**< Interfaces which is file implements. @since 1.12 */
Eina_List *keywords; /**< Keywords which describe this entry. @since 1.12 */
};