mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-12 07:26:15 +01:00
GDesktopAppInfo: Try to always correctly set id
Specs say that on Unix id should be desktop file id from the xdg menu specification, however, currently code just uses basename of .desktop file. Fix that by finding the .desktop file in all the desktop_file_dirs and use basename only as a fallback. See https://specifications.freedesktop.org/menu-spec/latest/go01.html#term-desktop-file-id and https://specifications.freedesktop.org/desktop-entry-spec/latest/ar01s02.html#desktop-file-id "To determine the ID of a desktop file, make its full path relative to the $XDG_DATA_DIRS component in which the desktop file is installed, remove the "applications/" prefix, and turn '/' into '-'." Also, add unit test that verifies Desktop Id is being correctly set Signed-off-by: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
This commit is contained in:
parent
62be185463
commit
f065497acf
@ -89,6 +89,7 @@ enum {
|
||||
static void g_desktop_app_info_iface_init (GAppInfoIface *iface);
|
||||
static gboolean g_desktop_app_info_ensure_saved (GDesktopAppInfo *info,
|
||||
GError **error);
|
||||
static gboolean g_desktop_app_info_load_file (GDesktopAppInfo *self);
|
||||
|
||||
/**
|
||||
* GDesktopAppInfo:
|
||||
@ -1002,6 +1003,19 @@ desktop_file_dir_unindexed_init (DesktopFileDir *dir)
|
||||
desktop_file_dir_unindexed_read_mimeapps_lists (dir);
|
||||
}
|
||||
|
||||
static GDesktopAppInfo *
|
||||
g_desktop_app_info_new_from_filename_unlocked (const char *filename)
|
||||
{
|
||||
GDesktopAppInfo *info = NULL;
|
||||
|
||||
info = g_object_new (G_TYPE_DESKTOP_APP_INFO, "filename", filename, NULL);
|
||||
|
||||
if (!g_desktop_app_info_load_file (info))
|
||||
g_clear_object (&info);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
static GDesktopAppInfo *
|
||||
desktop_file_dir_unindexed_get_app (DesktopFileDir *dir,
|
||||
const gchar *desktop_id)
|
||||
@ -1013,7 +1027,7 @@ desktop_file_dir_unindexed_get_app (DesktopFileDir *dir,
|
||||
if (!filename)
|
||||
return NULL;
|
||||
|
||||
return g_desktop_app_info_new_from_filename (filename);
|
||||
return g_desktop_app_info_new_from_filename_unlocked (filename);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1033,7 +1047,7 @@ desktop_file_dir_unindexed_get_all (DesktopFileDir *dir,
|
||||
if (desktop_file_dir_app_name_is_masked (dir, app_name))
|
||||
continue;
|
||||
|
||||
add_to_table_if_appropriate (apps, app_name, g_desktop_app_info_new_from_filename (filename));
|
||||
add_to_table_if_appropriate (apps, app_name, g_desktop_app_info_new_from_filename_unlocked (filename));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1754,6 +1768,56 @@ binary_from_exec (const char *exec)
|
||||
return g_strndup (start, p - start);
|
||||
}
|
||||
|
||||
/*< internal >
|
||||
* g_desktop_app_info_get_desktop_id_for_filename
|
||||
* @self: #GDesktopAppInfo to get desktop id of
|
||||
*
|
||||
* Tries to find the desktop ID for a particular `.desktop` filename, as per the
|
||||
* [Desktop Entry Specification](https://specifications.freedesktop.org/desktop-
|
||||
* entry-spec/desktop-entry-spec-latest.html#desktop-file-id).
|
||||
*
|
||||
* Returns: desktop id or basename if filename is unknown.
|
||||
*/
|
||||
static char *
|
||||
g_desktop_app_info_get_desktop_id_for_filename (GDesktopAppInfo *self)
|
||||
{
|
||||
guint i;
|
||||
gchar *desktop_id = NULL;
|
||||
|
||||
g_return_val_if_fail (self->filename != NULL, NULL);
|
||||
|
||||
for (i = 0; i < desktop_file_dirs->len; i++)
|
||||
{
|
||||
DesktopFileDir *dir = g_ptr_array_index (desktop_file_dirs, i);
|
||||
GHashTable *app_names;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
|
||||
app_names = dir->app_names;
|
||||
|
||||
if (!app_names)
|
||||
continue;
|
||||
|
||||
g_hash_table_iter_init (&iter, app_names);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
if (!strcmp (value, self->filename))
|
||||
{
|
||||
desktop_id = g_strdup (key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (desktop_id)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!desktop_id)
|
||||
desktop_id = g_path_get_basename (self->filename);
|
||||
|
||||
return g_steal_pointer (&desktop_id);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
g_desktop_app_info_load_from_keyfile (GDesktopAppInfo *info,
|
||||
GKeyFile *key_file)
|
||||
@ -1912,6 +1976,9 @@ g_desktop_app_info_load_from_keyfile (GDesktopAppInfo *info,
|
||||
g_free (basename);
|
||||
}
|
||||
|
||||
if (info->filename)
|
||||
info->desktop_id = g_desktop_app_info_get_desktop_id_for_filename (info);
|
||||
|
||||
info->keyfile = g_key_file_ref (key_file);
|
||||
|
||||
return TRUE;
|
||||
@ -1925,8 +1992,6 @@ g_desktop_app_info_load_file (GDesktopAppInfo *self)
|
||||
|
||||
g_return_val_if_fail (self->filename != NULL, FALSE);
|
||||
|
||||
self->desktop_id = g_path_get_basename (self->filename);
|
||||
|
||||
key_file = g_key_file_new ();
|
||||
|
||||
if (g_key_file_load_from_file (key_file, self->filename, G_KEY_FILE_NONE, NULL))
|
||||
@ -1953,11 +2018,14 @@ g_desktop_app_info_new_from_keyfile (GKeyFile *key_file)
|
||||
|
||||
info = g_object_new (G_TYPE_DESKTOP_APP_INFO, NULL);
|
||||
info->filename = NULL;
|
||||
|
||||
desktop_file_dirs_lock ();
|
||||
|
||||
if (!g_desktop_app_info_load_from_keyfile (info, key_file))
|
||||
{
|
||||
g_object_unref (info);
|
||||
return NULL;
|
||||
}
|
||||
g_clear_object (&info);
|
||||
|
||||
desktop_file_dirs_unlock ();
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
@ -1975,12 +2043,12 @@ g_desktop_app_info_new_from_filename (const char *filename)
|
||||
{
|
||||
GDesktopAppInfo *info = NULL;
|
||||
|
||||
info = g_object_new (G_TYPE_DESKTOP_APP_INFO, "filename", filename, NULL);
|
||||
if (!g_desktop_app_info_load_file (info))
|
||||
{
|
||||
g_object_unref (info);
|
||||
return NULL;
|
||||
}
|
||||
desktop_file_dirs_lock ();
|
||||
|
||||
info = g_desktop_app_info_new_from_filename_unlocked (filename);
|
||||
|
||||
desktop_file_dirs_unlock ();
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
|
@ -797,6 +797,18 @@ test_launch_as_manager (void)
|
||||
g_assert_finalize_object (context);
|
||||
}
|
||||
|
||||
/* Test if Desktop-File Id is correctly formed */
|
||||
static void
|
||||
test_id (void)
|
||||
{
|
||||
gchar *result;
|
||||
|
||||
result = run_apps ("default-for-type", "application/vnd.kde.okular-archive",
|
||||
TRUE, FALSE, NULL, NULL, NULL);
|
||||
g_assert_cmpstr (result, ==, "kde4-okular.desktop\n");
|
||||
g_free (result);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
@ -818,6 +830,7 @@ main (int argc,
|
||||
g_test_add_func ("/desktop-app-info/implements", test_implements);
|
||||
g_test_add_func ("/desktop-app-info/show-in", test_show_in);
|
||||
g_test_add_func ("/desktop-app-info/launch-as-manager", test_launch_as_manager);
|
||||
g_test_add_func ("/desktop-app-info/id", test_id);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user