Use XDG paths in addition to the defaults when looking for icons and applications
This commit is contained in:
parent
edbf9f4437
commit
fcbc006e43
6 changed files with 95 additions and 13 deletions
|
@ -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 @@ void test_read_desktop_file()
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#ifndef APPS_COMMON_H
|
||||
#define APPS_COMMON_H
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
typedef struct DesktopEntry {
|
||||
char *name;
|
||||
char *exec;
|
||||
|
@ -27,4 +29,8 @@ 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
|
||||
|
|
|
@ -20,11 +20,13 @@
|
|||
|
||||
#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 @@ const GSList *get_icon_locations()
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -2893,10 +2893,10 @@ void create_launcher(GtkWidget *parent)
|
|||
|
||||
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);
|
||||
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);
|
||||
|
||||
|
@ -2905,8 +2905,6 @@ void create_launcher(GtkWidget *parent)
|
|||
}
|
||||
g_list_free(entries);
|
||||
|
||||
g_free(path);
|
||||
|
||||
icon_theme_changed();
|
||||
load_icons(launcher_apps);
|
||||
load_icons(all_apps);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#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 @@ GList *g_list_copy_deep(GList *list, GCopyFunc func, gpointer user_data)
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -96,6 +96,13 @@ void draw_rect(cairo_t *c, double x, double y, double w, double h, double r);
|
|||
// 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)
|
||||
|
|
Loading…
Reference in a new issue