From 5a5e16e93c4f11e635918ecdb41681f63fd05a39 Mon Sep 17 00:00:00 2001 From: Ryan Lortie Date: Thu, 8 May 2014 08:57:50 -0400 Subject: [PATCH] AppInfo: use XDG_CURRENT_DESKTOP for OnlyShowIn Expand the functionality of g_desktop_app_info_set_desktop_env() to include the possibility of passing strings containing ':' characters (as some apps, such as gnome-session, are directly passing the value of XDG_CURRENT_DESKTOP). At the same time, deprecate it, since now we get the list from the environment variable for ourselves. Modify the checks in g_desktop_app_info_get_show_in() to deal with multiple items listed in XDG_CURRENT_DESKTOP. For example, if we find that we have XDG_CURRENT_DESKTOP=GNOME-Classic:GNOME and a desktop file contains: OnlyShowIn=GNOME then we will show this file because of the fallback to GNOME. If the file _also_ contains the line: NotShowIn=GNOME-Classic Then we will not show it, because GNOME-Classic comes before GNOME in XDG_CURRENT_DESKTOP. https://bugzilla.gnome.org/show_bug.cgi?id=729813 --- gio/gdesktopappinfo.c | 99 +++++++++++++++++++++++++-------------------------- gio/gdesktopappinfo.h | 2 +- 2 files changed, 50 insertions(+), 51 deletions(-) diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c index 913c872..1d38d4a 100644 --- a/gio/gdesktopappinfo.c +++ b/gio/gdesktopappinfo.c @@ -132,9 +132,6 @@ typedef enum { G_DEFINE_TYPE_WITH_CODE (GDesktopAppInfo, g_desktop_app_info, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (G_TYPE_APP_INFO, g_desktop_app_info_iface_init)) -G_LOCK_DEFINE_STATIC (g_desktop_env); -static gchar *g_desktop_env = NULL; - /* DesktopFileDir implementation {{{1 */ typedef struct @@ -243,6 +240,29 @@ get_lowercase_current_desktops (void) return (const gchar **) result; } +static const gchar * const * +get_current_desktops (const gchar *value) +{ + static gchar **result; + + if (g_once_init_enter (&result)) + { + gchar **tmp; + + if (!value) + value = g_getenv ("XDG_CURRENT_DESKTOP"); + + if (!value) + value = ""; + + tmp = g_strsplit (value, ":", 0); + + g_once_init_leave (&result, tmp); + } + + return (const gchar **) result; +} + /*< internal > * add_to_table_if_appropriate: * @apps: a string to GDesktopAppInfo hash table @@ -2040,14 +2060,16 @@ g_desktop_app_info_get_nodisplay (GDesktopAppInfo *info) /** * g_desktop_app_info_get_show_in: * @info: a #GDesktopAppInfo - * @desktop_env: a string specifying a desktop name + * @desktop_env: (nullable): a string specifying a desktop name * * Checks if the application info should be shown in menus that list available * applications for a specific name of the desktop, based on the * `OnlyShowIn` and `NotShowIn` keys. * - * If @desktop_env is %NULL, then the name of the desktop set with - * g_desktop_app_info_set_desktop_env() is used. + * @desktop_env should typically be given as %NULL, in which case the + * `XDG_CURRENT_DESKTOP` environment variable is consulted. If you want + * to override the default mechanism then you may specify @desktop_env, + * but this is not recommended. * * Note that g_app_info_should_show() for @info will include this check (with * %NULL for @desktop_env) as well as additional checks. @@ -2062,45 +2084,33 @@ gboolean g_desktop_app_info_get_show_in (GDesktopAppInfo *info, const gchar *desktop_env) { - gboolean found; - int i; + const gchar *specified_envs[] = { desktop_env, NULL }; + const gchar * const *envs; + gint i; g_return_val_if_fail (G_IS_DESKTOP_APP_INFO (info), FALSE); - if (!desktop_env) { - G_LOCK (g_desktop_env); - desktop_env = g_desktop_env; - G_UNLOCK (g_desktop_env); - } + if (desktop_env) + envs = specified_envs; + else + envs = get_current_desktops (NULL); - if (info->only_show_in) + for (i = 0; envs[i]; i++) { - if (desktop_env == NULL) - return FALSE; + gint j; - found = FALSE; - for (i = 0; info->only_show_in[i] != NULL; i++) - { - if (strcmp (info->only_show_in[i], desktop_env) == 0) - { - found = TRUE; - break; - } - } - if (!found) - return FALSE; - } + if (info->only_show_in) + for (j = 0; info->only_show_in[j]; j++) + if (g_str_equal (info->only_show_in[j], envs[i])) + return TRUE; - if (info->not_show_in && desktop_env) - { - for (i = 0; info->not_show_in[i] != NULL; i++) - { - if (strcmp (info->not_show_in[i], desktop_env) == 0) + if (info->not_show_in) + for (j = 0; info->not_show_in[j]; j++) + if (g_str_equal (info->not_show_in[j], envs[i])) return FALSE; - } } - return TRUE; + return info->only_show_in == NULL; } /* Launching... {{{2 */ @@ -2958,26 +2968,15 @@ g_desktop_app_info_launch_uris_as_manager (GDesktopAppInfo *appinfo, * `OnlyShowIn` and `NotShowIn` * desktop entry fields. * - * The - * [Desktop Menu specification](http://standards.freedesktop.org/menu-spec/latest/) - * recognizes the following: - * - GNOME - * - KDE - * - ROX - * - XFCE - * - LXDE - * - Unity - * - Old - * * Should be called only once; subsequent calls are ignored. + * + * Deprecated:2.42:do not use this API. Since 2.42 the value of the + * `XDG_CURRENT_DESKTOP` environment variable will be used. */ void g_desktop_app_info_set_desktop_env (const gchar *desktop_env) { - G_LOCK (g_desktop_env); - if (!g_desktop_env) - g_desktop_env = g_strdup (desktop_env); - G_UNLOCK (g_desktop_env); + get_current_desktops (desktop_env); } static gboolean diff --git a/gio/gdesktopappinfo.h b/gio/gdesktopappinfo.h index 877ce5d..7e09a76 100644 --- a/gio/gdesktopappinfo.h +++ b/gio/gdesktopappinfo.h @@ -71,7 +71,7 @@ GDesktopAppInfo *g_desktop_app_info_new (const char *desktop_ GLIB_AVAILABLE_IN_ALL gboolean g_desktop_app_info_get_is_hidden (GDesktopAppInfo *info); -GLIB_AVAILABLE_IN_ALL +GLIB_DEPRECATED_IN_2_42 void g_desktop_app_info_set_desktop_env (const char *desktop_env); GLIB_AVAILABLE_IN_2_36 -- 2.7.4