diff options
Diffstat (limited to 'swaybar/tray/icon.c')
-rw-r--r-- | swaybar/tray/icon.c | 68 |
1 files changed, 62 insertions, 6 deletions
diff --git a/swaybar/tray/icon.c b/swaybar/tray/icon.c index c146bf32..fc9b176d 100644 --- a/swaybar/tray/icon.c +++ b/swaybar/tray/icon.c | |||
@@ -80,6 +80,17 @@ static bool isdir(const char *path) { | |||
80 | 80 | ||
81 | } | 81 | } |
82 | 82 | ||
83 | static bool isfile(const char *path) { | ||
84 | struct stat statbuf; | ||
85 | if (stat(path, &statbuf) != -1) { | ||
86 | if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) { | ||
87 | return true; | ||
88 | } | ||
89 | } | ||
90 | return false; | ||
91 | |||
92 | } | ||
93 | |||
83 | /** | 94 | /** |
84 | * Returns the directory of a given theme if it exists. | 95 | * Returns the directory of a given theme if it exists. |
85 | * The returned pointer must be freed. | 96 | * The returned pointer must be freed. |
@@ -111,15 +122,28 @@ static char *find_theme_dir(const char *theme) { | |||
111 | } | 122 | } |
112 | 123 | ||
113 | if ((basedir = getenv("XDG_DATA_DIRS"))) { | 124 | if ((basedir = getenv("XDG_DATA_DIRS"))) { |
114 | if (snprintf(icon_dir, 1024, "%s/icons/%s", basedir, theme) >= 1024) { | 125 | if (!(basedir = strdup(basedir))) { |
115 | sway_log(L_ERROR, "Path too long to render"); | 126 | sway_log_errno(L_ERROR, "Path too long to render"); |
116 | // ditto | ||
117 | goto fail; | 127 | goto fail; |
118 | } | 128 | } |
129 | char *token = strtok(basedir, ":"); | ||
130 | while (token) { | ||
131 | // By peeking at the spec, there should be a slash at | ||
132 | // the end of the data dir. | ||
133 | if (snprintf(icon_dir, 1024, "%sicons/%s", token, theme) >= 1024) { | ||
134 | sway_log(L_ERROR, "Path too long to render"); | ||
135 | // ditto | ||
136 | free(basedir); | ||
137 | goto fail; | ||
138 | } | ||
119 | 139 | ||
120 | if (isdir(icon_dir)) { | 140 | if (isdir(icon_dir)) { |
121 | return icon_dir; | 141 | free(basedir); |
142 | return icon_dir; | ||
143 | } | ||
144 | token = strtok(NULL, ":"); | ||
122 | } | 145 | } |
146 | free(basedir); | ||
123 | } | 147 | } |
124 | 148 | ||
125 | // Spec says use "/usr/share/pixmaps/", but I see everything in | 149 | // Spec says use "/usr/share/pixmaps/", but I see everything in |
@@ -162,6 +186,15 @@ static list_t *find_all_theme_dirs(const char *theme) { | |||
162 | list_cat(dirs, inherits); | 186 | list_cat(dirs, inherits); |
163 | list_free(inherits); | 187 | list_free(inherits); |
164 | } | 188 | } |
189 | // 'default' usually inherits the default theme. I don't believe it has | ||
190 | // any icons, but look for them anyway | ||
191 | dir = find_theme_dir("default"); | ||
192 | if (dir) { | ||
193 | list_add(dirs, dir); | ||
194 | list_t *inherits = find_inherits(dir); | ||
195 | list_cat(dirs, inherits); | ||
196 | list_free(inherits); | ||
197 | } | ||
165 | dir = find_theme_dir("hicolor"); | 198 | dir = find_theme_dir("hicolor"); |
166 | if (dir) { | 199 | if (dir) { |
167 | list_add(dirs, dir); | 200 | list_add(dirs, dir); |
@@ -290,6 +323,24 @@ fail: | |||
290 | return dirs; | 323 | return dirs; |
291 | } | 324 | } |
292 | 325 | ||
326 | /* Returns true if full path and file exists */ | ||
327 | static bool is_valid_path(const char *file) { | ||
328 | if (strstr(file, "/") == NULL || !isfile(file)) { | ||
329 | return false; | ||
330 | } | ||
331 | #ifdef WITH_GDK_PIXBUF | ||
332 | if (strstr(file, ".png") == NULL && | ||
333 | strstr(file, ".xpm") == NULL && | ||
334 | strstr(file, ".svg") == NULL) { | ||
335 | #else | ||
336 | if (strstr(file, ".png") == NULL) { | ||
337 | #endif | ||
338 | return false; | ||
339 | } | ||
340 | |||
341 | return true; | ||
342 | } | ||
343 | |||
293 | /* Returns the file of an icon given its name and size */ | 344 | /* Returns the file of an icon given its name and size */ |
294 | static char *find_icon_file(const char *name, int size) { | 345 | static char *find_icon_file(const char *name, int size) { |
295 | int namelen = strlen(name); | 346 | int namelen = strlen(name); |
@@ -372,7 +423,12 @@ static char *find_icon_file(const char *name, int size) { | |||
372 | } | 423 | } |
373 | 424 | ||
374 | cairo_surface_t *find_icon(const char *name, int size) { | 425 | cairo_surface_t *find_icon(const char *name, int size) { |
375 | char *image_path = find_icon_file(name, size); | 426 | char *image_path; |
427 | if (is_valid_path(name)) { | ||
428 | image_path = strdup(name); | ||
429 | } else { | ||
430 | image_path = find_icon_file(name, size); | ||
431 | } | ||
376 | if (image_path == NULL) { | 432 | if (image_path == NULL) { |
377 | return NULL; | 433 | return NULL; |
378 | } | 434 | } |