Skip to content

Commit c64c662

Browse files
committed
move_icon_to_destination() based on icon size
1 parent bd2696a commit c64c662

File tree

1 file changed

+52
-23
lines changed

1 file changed

+52
-23
lines changed

shared.c

Lines changed: 52 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656

5757
#include <regex.h>
5858

59-
#include <cairo.h> // To get the size of icons, determine_icon_destination()
59+
#include <cairo.h> // To get the size of icons, move_icon_to_destination()
6060

6161
#define FNM_FILE_NAME 2
6262

@@ -127,16 +127,17 @@ char * get_thumbnail_path(char *path, char *thumbnail_size, gboolean verbose)
127127
return thumbnail_path;
128128
}
129129

130-
/* Return the path where a given icon can be installed in $HOME.
130+
/* Move an icon file to the path where a given icon can be installed in $HOME.
131131
* This is needed because png and xpm icons cannot be installed in a generic
132132
* location but are only picked up in directories that have the size of
133133
* the icon as part of their directory name, as specified in the theme.index
134134
* See https://github.com/probonopd/AppImageKit/issues/258
135135
*/
136136

137-
gchar* determine_icon_destination(gchar *icon_path)
137+
void move_icon_to_destination(gchar *icon_path, gboolean verbose)
138138
{
139-
gchar *dest_dir;
139+
// FIXME: This default location is most likely wrong, icons there will be ignored
140+
gchar *dest_dir = dest_dir = g_build_path("/", g_get_user_data_dir(), "/icons/hicolor/", NULL);;
140141

141142
if((g_str_has_suffix (icon_path, ".svg")) || (g_str_has_suffix (icon_path, ".svgz"))) {
142143
dest_dir = g_build_path("/", g_get_user_data_dir(), "/icons/hicolor/scalable", NULL);
@@ -145,36 +146,51 @@ gchar* determine_icon_destination(gchar *icon_path)
145146
if((g_str_has_suffix (icon_path, ".png")) || (g_str_has_suffix (icon_path, ".xpm"))) {
146147

147148
cairo_surface_t *image;
148-
149+
150+
int w = 0;
151+
int h = 0;
152+
149153
if(g_str_has_suffix (icon_path, ".xpm")) {
150154
// TODO: GdkPixbuf has a convenient way to load XPM data. Then you can call
151155
// gdk_cairo_set_source_pixbuf() to transfer the data to a Cairo surface.
152156
fprintf(stderr, "XPM size parsing not yet implemented\n");
153-
return NULL;
154157
}
155158

159+
156160
if(g_str_has_suffix (icon_path, ".png")) {
157161
image = cairo_image_surface_create_from_png(icon_path);
162+
w = cairo_image_surface_get_width (image);
163+
h = cairo_image_surface_get_height (image);
164+
cairo_surface_destroy (image);
158165
}
159-
160-
int w = cairo_image_surface_get_width (image);
161-
int h = cairo_image_surface_get_height (image);
162-
166+
163167
// FIXME: The following sizes are taken from the hicolor icon theme.
164168
// Probably the right thing to do would be to figure out at runtime which icon sizes are allowable.
165169
// Or could we put our own index.theme into .local/share/icons/ and have it observed?
166170
if((w != h) || ((w != 16) && (w != 24) && (w != 32) && (w != 36) && (w != 48) && (w != 64) && (w != 72) && (w != 96) && (w != 128) && (w != 192) && (w != 256) && (w != 512))){
167171
fprintf(stderr, "%s has nonstandard size w = %i, h = %i; please fix it\n", icon_path, w, h);
168-
return NULL;
172+
} else {
173+
dest_dir = g_build_path("/", g_get_user_data_dir(), "/icons/hicolor/", g_strdup_printf("%ix%i", w, h), NULL);
169174
}
170-
171-
cairo_surface_destroy (image);
172-
173-
dest_dir = g_build_path("/", g_get_user_data_dir(), "/icons/hicolor/", g_strdup_printf("%ix%i", w, h), NULL);
174175
}
175-
176-
return(dest_dir);
177-
176+
if(verbose)
177+
fprintf(stderr, "dest_dir %s\n", dest_dir);
178+
179+
gchar* icon_dest_path = g_build_path("/", dest_dir, g_path_get_basename(icon_path), NULL);
180+
if(verbose)
181+
fprintf(stderr, "Move from %s to %s\n", icon_path, icon_dest_path);
182+
if(g_mkdir_with_parents(g_path_get_dirname(dest_dir), 0755))
183+
fprintf(stderr, "Could not create directory: %s\n", dest_dir);
184+
GError *error = NULL;
185+
GFile *icon_file = g_file_new_for_path(icon_path);
186+
GFile *target_file = g_file_new_for_path(icon_dest_path);
187+
if (!g_file_move (icon_file, target_file, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &error)) {
188+
fprintf(stderr, "Error moving file: %s\n", error->message);
189+
g_error_free (error);
190+
}
191+
g_object_unref(icon_file);
192+
g_object_unref(target_file);
193+
178194
}
179195

180196
/* Check if a file is an AppImage. Returns the image type if it is, or -1 if it isn't */
@@ -279,12 +295,12 @@ gchar **squash_get_matching_files(sqfs *fs, char *pattern, gchar *desktop_icon_v
279295
* share/pixmaps is ONLY searched in /usr but not in $XDG_DATA_DIRS and hence $HOME and this seems to be true at least in XFCE */
280296
if(g_str_has_prefix (trv.path, "usr/share/pixmaps/")){
281297
dest_basename = g_strdup_printf("%s_%s_%s", vendorprefix, md5, g_path_get_basename(trv.path));
282-
dest = g_build_path("/", g_get_user_data_dir(), "/icons/hicolor/scalable/apps/", dest_basename, NULL);
298+
dest = g_build_path("/", "/tmp", dest_basename, NULL);
283299
}
284300
/* Some AppImages only have the icon in their root directory, so we have to get it from there */
285301
if((g_str_has_prefix(trv.path, desktop_icon_value_original)) && (! strstr(trv.path, "/")) && ( (g_str_has_suffix(trv.path, ".png")) || (g_str_has_suffix(trv.path, ".xpm")) || (g_str_has_suffix(trv.path, ".svg")) || (g_str_has_suffix(trv.path, ".svgz")))){
286302
dest_basename = g_strdup_printf("%s_%s_%s.%s", vendorprefix, md5, desktop_icon_value_original, get_file_extension(trv.path));
287-
dest = g_build_path("/", g_get_user_data_dir(), "/icons/hicolor/scalable/apps/", dest_basename, NULL);
303+
dest = g_build_path("/", "/tmp", dest_basename, NULL);
288304
}
289305

290306
if(dest){
@@ -315,6 +331,12 @@ gchar **squash_get_matching_files(sqfs *fs, char *pattern, gchar *desktop_icon_v
315331

316332
if(verbose)
317333
fprintf(stderr, "Installed: %s\n", dest);
334+
335+
// If we were unsure about the size of an icon, we temporarily installed
336+
// it to /tmp and now move it into the proper place
337+
if(g_str_has_prefix (dest, "/tmp/")) {
338+
move_icon_to_destination(dest, verbose);
339+
}
318340
}
319341
}
320342
}
@@ -660,13 +682,13 @@ bool appimage_type1_register_in_system(char *path, gboolean verbose)
660682
/* According to https://specifications.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html#install_icons
661683
* share/pixmaps is ONLY searched in /usr but not in $XDG_DATA_DIRS and hence $HOME and this seems to be true at least in XFCE */
662684
if(g_str_has_prefix (filename, "usr/share/pixmaps/")){
663-
dest = g_build_path("/", g_get_home_dir(), ".icons", dest_basename, NULL);
685+
dest = g_build_path("/", "/tmp", dest_basename, NULL);
664686
}
665687
/* Some AppImages only have the icon in their root directory, so we have to get it from there */
666688
if(desktop_icon_value_original){
667689
if((g_str_has_prefix(filename, desktop_icon_value_original)) && (! strstr(filename, "/")) && ( (g_str_has_suffix(filename, ".png")) || (g_str_has_suffix(filename, ".xpm")) || (g_str_has_suffix(filename, ".svg")) || (g_str_has_suffix(filename, ".svgz")))){
668690
dest_basename = g_strdup_printf("%s_%s_%s.%s", vendorprefix, md5, desktop_icon_value_original, get_file_extension(filename));
669-
dest = g_build_path("/", g_get_home_dir(), ".icons", dest_basename, NULL);
691+
dest = g_build_path("/", "/tmp", dest_basename, NULL);
670692
}
671693
}
672694

@@ -708,7 +730,14 @@ bool appimage_type1_register_in_system(char *path, gboolean verbose)
708730

709731

710732
if(verbose)
711-
fprintf(stderr, "Installed: %s\n", dest);
733+
fprintf(stderr, "Installed: %s\n", dest);
734+
735+
// If we were unsure about the size of an icon, we temporarily installed
736+
// it to /tmp and now move it into the proper place
737+
if(g_str_has_prefix (dest, "/tmp/")) {
738+
move_icon_to_destination(dest, verbose);
739+
}
740+
712741
}
713742
}
714743
archive_read_close(a);

0 commit comments

Comments
 (0)