Use XDG paths in addition to the defaults when looking for icons and applications
o9000 mrovi9000@gmail.com
6 files changed,
95 insertions(+),
13 deletions(-)
M
src/launcher/apps-common.c
→
src/launcher/apps-common.c
@@ -19,6 +19,7 @@
/* http://standards.freedesktop.org/desktop-entry-spec/ */ #include "apps-common.h" +#include "common.h" #include <glib.h> #include <stdio.h>@@ -194,3 +195,25 @@ read_desktop_file("/usr/share/applications/firefox.desktop", &entry);
printf("Name:%s Icon:%s Exec:%s\n", entry.name, entry.icon, entry.exec); fprintf(stdout, "\033[0m"); } + +GSList *apps_locations = NULL; +// Do not free the result. +const GSList *get_apps_locations() +{ + if (apps_locations) + return apps_locations; + + apps_locations = load_locations_from_env(apps_locations, "XDG_DATA_HOME", "applications", NULL); + + apps_locations = g_slist_append(apps_locations, g_build_filename(g_get_home_dir(), ".local/share/applications", NULL)); + + apps_locations = load_locations_from_env(apps_locations, "XDG_DATA_DIRS", "applications", NULL); + + apps_locations = g_slist_append(apps_locations, g_strdup("/usr/local/share/applications")); + apps_locations = g_slist_append(apps_locations, g_strdup("/usr/share/applications")); + apps_locations = g_slist_append(apps_locations, g_strdup("/opt/share/applications")); + + apps_locations = slist_remove_duplicates(apps_locations, g_str_equal, g_free); + + return apps_locations; +}
M
src/launcher/apps-common.h
→
src/launcher/apps-common.h
@@ -7,6 +7,8 @@
#ifndef APPS_COMMON_H #define APPS_COMMON_H +#include <glib.h> + typedef struct DesktopEntry { char *name; char *exec;@@ -26,5 +28,9 @@ int read_desktop_file(const char *path, DesktopEntry *entry);
// Empties DesktopEntry: releases the memory of the *members* of entry. void free_desktop_entry(DesktopEntry *entry); + +// Returns a list of the directories used to store desktop files. +// Do not free the result, it is cached. +const GSList *get_apps_locations(); #endif
M
src/launcher/icon-theme-common.c
→
src/launcher/icon-theme-common.c
@@ -20,11 +20,13 @@ /* http://standards.freedesktop.org/icon-theme-spec/ */
#include "icon-theme-common.h" +#include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "apps-common.h" +#include "common.h" #define ICON_DIR_TYPE_SCALABLE 0 #define ICON_DIR_TYPE_FIXED 1@@ -50,19 +52,22 @@ {
if (icon_locations) return icon_locations; - gchar *path; - path = g_build_filename(g_get_home_dir(), ".icons", NULL); - icon_locations = g_slist_append(icon_locations, g_strdup(path)); - g_free(path); - path = g_build_filename(g_get_home_dir(), ".local/share/icons", NULL); - icon_locations = g_slist_append(icon_locations, g_strdup(path)); - g_free(path); + icon_locations = load_locations_from_env(icon_locations, "XDG_DATA_HOME", ".icons", NULL); + + icon_locations = g_slist_append(icon_locations, g_build_filename(g_get_home_dir(), ".icons", NULL)); + icon_locations = g_slist_append(icon_locations, g_build_filename(g_get_home_dir(), ".local/share/icons", NULL)); + + icon_locations = load_locations_from_env(icon_locations, "XDG_DATA_DIRS", ".icons", ".pixmaps", NULL); + icon_locations = g_slist_append(icon_locations, g_strdup("/usr/local/share/icons")); icon_locations = g_slist_append(icon_locations, g_strdup("/usr/local/share/pixmaps")); icon_locations = g_slist_append(icon_locations, g_strdup("/usr/share/icons")); icon_locations = g_slist_append(icon_locations, g_strdup("/usr/share/pixmaps")); icon_locations = g_slist_append(icon_locations, g_strdup("/opt/share/icons")); icon_locations = g_slist_append(icon_locations, g_strdup("/opt/share/pixmaps")); + + icon_locations = slist_remove_duplicates(icon_locations, g_str_equal, g_free); + return icon_locations; }
M
src/tint2conf/properties.c
→
src/tint2conf/properties.c
@@ -2893,10 +2893,10 @@ fprintf(stderr, "Icon themes loaded\n");
fprintf(stderr, "Loading .desktop files\n"); GList *entries = NULL; - load_desktop_entries("/usr/share/applications", &entries); - load_desktop_entries("/usr/local/share/applications", &entries); - gchar *path = g_build_filename(g_get_home_dir(), ".local/share/applications", NULL); - load_desktop_entries(path, &entries); + for (location = get_apps_locations(); location; location = g_slist_next(location)) { + const gchar *path = (gchar*) location->data; + load_desktop_entries(path, &entries); + } entries = g_list_sort(entries, compare_entries); populate_from_entries(entries, FALSE);@@ -2904,8 +2904,6 @@ for (GList *l = entries; l; l = l->next) {
free_desktop_entry((DesktopEntry*)l->data); } g_list_free(entries); - - g_free(path); icon_theme_changed(); load_icons(launcher_apps);
M
src/util/common.c
→
src/util/common.c
@@ -22,6 +22,7 @@ #include <X11/Xlib.h>
#include <X11/Xutil.h> #include <X11/Xatom.h> #include <X11/extensions/Xrender.h> +#include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h>@@ -591,3 +592,45 @@
return list; } #endif + +GSList *load_locations_from_env(GSList *locations, const char *var, ...) +{ + char *value = getenv(var); + if (value) { + value = strdup(value); + char *p = value; + for (char *token = strsep(&value, ":"); token; token = strsep(&value, ":")) { + va_list ap; + va_start(ap, var); + for (const char *suffix = va_arg(ap, const char *); suffix; suffix = va_arg(ap, const char *)) { + locations = g_slist_append(locations, g_build_filename(token, suffix, NULL)); + } + va_end(ap); + } + free(p); + } + return locations; +} + +GSList *slist_remove_duplicates(GSList *list, GCompareFunc eq, GDestroyNotify fr) +{ + GSList *new_list = NULL; + + for (GSList *l1 = list; l1; l1 = g_slist_next(l1)) { + gboolean duplicate = FALSE; + for (GSList *l2 = new_list; l2; l2 = g_slist_next(l2)) { + if (eq(l1->data, l2->data)) { + duplicate = TRUE; + break; + } + } + if (!duplicate) { + new_list = g_slist_append(new_list, l1->data); + l1->data = NULL; + } + } + + g_slist_free_full(list, fr); + + return new_list; +}
M
src/util/common.h
→
src/util/common.h
@@ -96,6 +96,13 @@
// Clears the pixmap (with transparent color) void clear_pixmap(Pixmap p, int x, int y, int w, int h); +// Appends to the list locations all the directories contained in the environment variable var (split by ":"). +// Optional suffixes are added to each directory. The suffix arguments MUST end with NULL. +// Returns the new value of the list. +GSList *load_locations_from_env(GSList *locations, const char *var, ...); + +GSList *slist_remove_duplicates(GSList *list, GCompareFunc eq, GDestroyNotify fr); + #define free_and_null(p) { free(p); p = NULL; } #if !GLIB_CHECK_VERSION (2, 33, 4)