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/ */
|
/* http://standards.freedesktop.org/desktop-entry-spec/ */
|
||||||
|
|
||||||
#include "apps-common.h"
|
#include "apps-common.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <stdio.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);
|
printf("Name:%s Icon:%s Exec:%s\n", entry.name, entry.icon, entry.exec);
|
||||||
fprintf(stdout, "\033[0m");
|
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
|
#ifndef APPS_COMMON_H
|
||||||
#define APPS_COMMON_H
|
#define APPS_COMMON_H
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
typedef struct DesktopEntry {
|
typedef struct DesktopEntry {
|
||||||
char *name;
|
char *name;
|
||||||
char *exec;
|
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.
|
// Empties DesktopEntry: releases the memory of the *members* of entry.
|
||||||
void free_desktop_entry(DesktopEntry *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
|
#endif
|
||||||
|
|
|
@ -20,11 +20,13 @@
|
||||||
|
|
||||||
#include "icon-theme-common.h"
|
#include "icon-theme-common.h"
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "apps-common.h"
|
#include "apps-common.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
#define ICON_DIR_TYPE_SCALABLE 0
|
#define ICON_DIR_TYPE_SCALABLE 0
|
||||||
#define ICON_DIR_TYPE_FIXED 1
|
#define ICON_DIR_TYPE_FIXED 1
|
||||||
|
@ -50,19 +52,22 @@ const GSList *get_icon_locations()
|
||||||
if (icon_locations)
|
if (icon_locations)
|
||||||
return icon_locations;
|
return icon_locations;
|
||||||
|
|
||||||
gchar *path;
|
icon_locations = load_locations_from_env(icon_locations, "XDG_DATA_HOME", ".icons", NULL);
|
||||||
path = g_build_filename(g_get_home_dir(), ".icons", NULL);
|
|
||||||
icon_locations = g_slist_append(icon_locations, g_strdup(path));
|
icon_locations = g_slist_append(icon_locations, g_build_filename(g_get_home_dir(), ".icons", NULL));
|
||||||
g_free(path);
|
icon_locations = g_slist_append(icon_locations, g_build_filename(g_get_home_dir(), ".local/share/icons", NULL));
|
||||||
path = g_build_filename(g_get_home_dir(), ".local/share/icons", NULL);
|
|
||||||
icon_locations = g_slist_append(icon_locations, g_strdup(path));
|
icon_locations = load_locations_from_env(icon_locations, "XDG_DATA_DIRS", ".icons", ".pixmaps", NULL);
|
||||||
g_free(path);
|
|
||||||
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/icons"));
|
||||||
icon_locations = g_slist_append(icon_locations, g_strdup("/usr/local/share/pixmaps"));
|
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/icons"));
|
||||||
icon_locations = g_slist_append(icon_locations, g_strdup("/usr/share/pixmaps"));
|
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/icons"));
|
||||||
icon_locations = g_slist_append(icon_locations, g_strdup("/opt/share/pixmaps"));
|
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;
|
return icon_locations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2893,10 +2893,10 @@ void create_launcher(GtkWidget *parent)
|
||||||
|
|
||||||
fprintf(stderr, "Loading .desktop files\n");
|
fprintf(stderr, "Loading .desktop files\n");
|
||||||
GList *entries = NULL;
|
GList *entries = NULL;
|
||||||
load_desktop_entries("/usr/share/applications", &entries);
|
for (location = get_apps_locations(); location; location = g_slist_next(location)) {
|
||||||
load_desktop_entries("/usr/local/share/applications", &entries);
|
const gchar *path = (gchar*) location->data;
|
||||||
gchar *path = g_build_filename(g_get_home_dir(), ".local/share/applications", NULL);
|
load_desktop_entries(path, &entries);
|
||||||
load_desktop_entries(path, &entries);
|
}
|
||||||
entries = g_list_sort(entries, compare_entries);
|
entries = g_list_sort(entries, compare_entries);
|
||||||
populate_from_entries(entries, FALSE);
|
populate_from_entries(entries, FALSE);
|
||||||
|
|
||||||
|
@ -2905,8 +2905,6 @@ void create_launcher(GtkWidget *parent)
|
||||||
}
|
}
|
||||||
g_list_free(entries);
|
g_list_free(entries);
|
||||||
|
|
||||||
g_free(path);
|
|
||||||
|
|
||||||
icon_theme_changed();
|
icon_theme_changed();
|
||||||
load_icons(launcher_apps);
|
load_icons(launcher_apps);
|
||||||
load_icons(all_apps);
|
load_icons(all_apps);
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
#include <X11/extensions/Xrender.h>
|
#include <X11/extensions/Xrender.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -591,3 +592,45 @@ GList *g_list_copy_deep(GList *list, GCopyFunc func, gpointer user_data)
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
#endif
|
#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)
|
// Clears the pixmap (with transparent color)
|
||||||
void clear_pixmap(Pixmap p, int x, int y, int w, int h);
|
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; }
|
#define free_and_null(p) { free(p); p = NULL; }
|
||||||
|
|
||||||
#if !GLIB_CHECK_VERSION (2, 33, 4)
|
#if !GLIB_CHECK_VERSION (2, 33, 4)
|
||||||
|
|
Loading…
Reference in a new issue