mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 03:16:17 +01:00
app info: tweak default application algorithm
Always run the full algorithm for a given mime type before considering fallback types. This includes considering installed applications capable of handling a particular mimetype, even if such an app is not explicitly marked as default, and there is a default app for a less-specific type. Specifically, this often helps with cases of installing apps that can handle a particular subtype of text/plain. We want to take those apps in preference to a generic text editor, even if that editor is listed as the default for text/plain and there is no default listed for the more specific type. Because of the more holistic approach taken by the algorithm, it is now more complicated, but it also means that we can do more work while holding the lock. In turn, that lets us avoid duplicating some strings, which is nice. https://bugzilla.gnome.org/show_bug.cgi?id=744282
This commit is contained in:
parent
cf940b66bc
commit
2bb898c60f
@ -1162,7 +1162,7 @@ desktop_file_dir_unindexed_mime_lookup (DesktopFileDir *dir,
|
|||||||
|
|
||||||
if (!desktop_file_dir_app_name_is_masked (dir, app_name) &&
|
if (!desktop_file_dir_app_name_is_masked (dir, app_name) &&
|
||||||
!array_contains (blacklist, app_name) && !array_contains (hits, app_name))
|
!array_contains (blacklist, app_name) && !array_contains (hits, app_name))
|
||||||
g_ptr_array_add (hits, g_strdup (app_name));
|
g_ptr_array_add (hits, app_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1197,7 +1197,7 @@ desktop_file_dir_unindexed_default_lookup (DesktopFileDir *dir,
|
|||||||
gchar *app_name = tweaks->defaults[i];
|
gchar *app_name = tweaks->defaults[i];
|
||||||
|
|
||||||
if (!array_contains (results, app_name))
|
if (!array_contains (results, app_name))
|
||||||
g_ptr_array_add (results, g_strdup (app_name));
|
g_ptr_array_add (results, app_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3838,6 +3838,10 @@ g_desktop_app_info_get_desktop_ids_for_content_type (const gchar *content_type,
|
|||||||
for (j = 0; j < n_desktop_file_dirs; j++)
|
for (j = 0; j < n_desktop_file_dirs; j++)
|
||||||
desktop_file_dir_mime_lookup (&desktop_file_dirs[j], types[i], hits, blacklist);
|
desktop_file_dir_mime_lookup (&desktop_file_dirs[j], types[i], hits, blacklist);
|
||||||
|
|
||||||
|
/* We will keep the hits past unlocking, so we must dup them */
|
||||||
|
for (i = 0; i < hits->len; i++)
|
||||||
|
hits->pdata[i] = g_strdup (hits->pdata[i]);
|
||||||
|
|
||||||
desktop_file_dirs_unlock ();
|
desktop_file_dirs_unlock ();
|
||||||
|
|
||||||
g_ptr_array_add (hits, NULL);
|
g_ptr_array_add (hits, NULL);
|
||||||
@ -3848,30 +3852,6 @@ g_desktop_app_info_get_desktop_ids_for_content_type (const gchar *content_type,
|
|||||||
return (gchar **) g_ptr_array_free (hits, FALSE);
|
return (gchar **) g_ptr_array_free (hits, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gchar **
|
|
||||||
g_desktop_app_info_get_defaults_for_content_type (const gchar *content_type)
|
|
||||||
{
|
|
||||||
GPtrArray *results;
|
|
||||||
gchar **types;
|
|
||||||
gint i, j;
|
|
||||||
|
|
||||||
types = get_list_of_mimetypes (content_type, TRUE);
|
|
||||||
results = g_ptr_array_new ();
|
|
||||||
|
|
||||||
desktop_file_dirs_lock ();
|
|
||||||
|
|
||||||
for (i = 0; types[i]; i++)
|
|
||||||
for (j = 0; j < n_desktop_file_dirs; j++)
|
|
||||||
desktop_file_dir_default_lookup (&desktop_file_dirs[j], types[i], results);
|
|
||||||
|
|
||||||
desktop_file_dirs_unlock ();
|
|
||||||
|
|
||||||
g_ptr_array_add (results, NULL);
|
|
||||||
g_strfreev (types);
|
|
||||||
|
|
||||||
return (gchar **) g_ptr_array_free (results, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_app_info_get_recommended_for_type:
|
* g_app_info_get_recommended_for_type:
|
||||||
* @content_type: the content type to find a #GAppInfo for
|
* @content_type: the content type to find a #GAppInfo for
|
||||||
@ -4039,57 +4019,64 @@ GAppInfo *
|
|||||||
g_app_info_get_default_for_type (const char *content_type,
|
g_app_info_get_default_for_type (const char *content_type,
|
||||||
gboolean must_support_uris)
|
gboolean must_support_uris)
|
||||||
{
|
{
|
||||||
gchar **desktop_ids;
|
GPtrArray *blacklist;
|
||||||
|
GPtrArray *results;
|
||||||
GAppInfo *info;
|
GAppInfo *info;
|
||||||
gint i;
|
gchar **types;
|
||||||
|
gint i, j, k;
|
||||||
|
|
||||||
g_return_val_if_fail (content_type != NULL, NULL);
|
g_return_val_if_fail (content_type != NULL, NULL);
|
||||||
|
|
||||||
desktop_ids = g_desktop_app_info_get_defaults_for_content_type (content_type);
|
types = get_list_of_mimetypes (content_type, TRUE);
|
||||||
|
|
||||||
|
blacklist = g_ptr_array_new ();
|
||||||
|
results = g_ptr_array_new ();
|
||||||
info = NULL;
|
info = NULL;
|
||||||
for (i = 0; desktop_ids[i]; i++)
|
|
||||||
|
desktop_file_dirs_lock ();
|
||||||
|
|
||||||
|
for (i = 0; types[i]; i++)
|
||||||
{
|
{
|
||||||
info = (GAppInfo *) g_desktop_app_info_new (desktop_ids[i]);
|
/* Collect all the default apps for this type */
|
||||||
|
for (j = 0; j < n_desktop_file_dirs; j++)
|
||||||
|
desktop_file_dir_default_lookup (&desktop_file_dirs[j], types[i], results);
|
||||||
|
|
||||||
if (info)
|
/* Consider the associations as well... */
|
||||||
|
for (j = 0; j < n_desktop_file_dirs; j++)
|
||||||
|
desktop_file_dir_mime_lookup (&desktop_file_dirs[j], types[i], results, blacklist);
|
||||||
|
|
||||||
|
/* (If any), see if one of those apps is installed... */
|
||||||
|
for (j = 0; j < results->len; j++)
|
||||||
{
|
{
|
||||||
if (!must_support_uris || g_app_info_supports_uris (info))
|
const gchar *desktop_id = g_ptr_array_index (results, j);
|
||||||
break;
|
|
||||||
|
|
||||||
g_object_unref (info);
|
for (k = 0; k < n_desktop_file_dirs; k++)
|
||||||
info = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_strfreev (desktop_ids);
|
|
||||||
|
|
||||||
/* If we can't find a default app for this content type, pick one from
|
|
||||||
* the list of all supported apps. This will be ordered by the user's
|
|
||||||
* preference and by "recommended" apps first, so the first one we
|
|
||||||
* find is probably the best fallback.
|
|
||||||
*/
|
|
||||||
if (info == NULL)
|
|
||||||
{
|
|
||||||
desktop_ids = g_desktop_app_info_get_desktop_ids_for_content_type (content_type, TRUE);
|
|
||||||
|
|
||||||
for (i = 0; desktop_ids[i]; i++)
|
|
||||||
{
|
|
||||||
info = (GAppInfo *) g_desktop_app_info_new (desktop_ids[i]);
|
|
||||||
|
|
||||||
if (info)
|
|
||||||
{
|
{
|
||||||
if (!must_support_uris || g_app_info_supports_uris (info))
|
info = (GAppInfo *) desktop_file_dir_get_app (&desktop_file_dirs[k], desktop_id);
|
||||||
break;
|
|
||||||
|
|
||||||
g_object_unref (info);
|
if (info)
|
||||||
info = NULL;
|
{
|
||||||
|
if (!must_support_uris || g_app_info_supports_uris (info))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
g_clear_object (&info);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_strfreev (desktop_ids);
|
/* Reset the list, ready to try again with the next (parent)
|
||||||
|
* mimetype, but keep the blacklist in place.
|
||||||
|
*/
|
||||||
|
g_ptr_array_set_size (results, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
desktop_file_dirs_unlock ();
|
||||||
|
|
||||||
|
g_ptr_array_unref (blacklist);
|
||||||
|
g_ptr_array_unref (results);
|
||||||
|
g_strfreev (types);
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user