Reduce memory footprint
This commit is contained in:
parent
1ff028e99f
commit
7bce19452e
3 changed files with 66 additions and 57 deletions
|
@ -536,6 +536,9 @@ char *get_icon_path_helper(GSList *themes, const char *icon_name, int size)
|
||||||
char *next_larger = NULL;
|
char *next_larger = NULL;
|
||||||
GSList *next_larger_theme = NULL;
|
GSList *next_larger_theme = NULL;
|
||||||
|
|
||||||
|
int file_name_size = 4096;
|
||||||
|
char *file_name = calloc(file_name_size, 1);
|
||||||
|
|
||||||
for (theme = themes; theme; theme = g_slist_next(theme)) {
|
for (theme = themes; theme; theme = g_slist_next(theme)) {
|
||||||
((IconTheme*)theme->data)->list_directories = g_slist_sort_with_data(((IconTheme*)theme->data)->list_directories,
|
((IconTheme*)theme->data)->list_directories = g_slist_sort_with_data(((IconTheme*)theme->data)->list_directories,
|
||||||
compare_theme_directories,
|
compare_theme_directories,
|
||||||
|
@ -560,8 +563,13 @@ char *get_icon_path_helper(GSList *themes, const char *icon_name, int size)
|
||||||
char *theme_name = ((IconTheme*)theme->data)->name;
|
char *theme_name = ((IconTheme*)theme->data)->name;
|
||||||
char *dir_name = ((IconThemeDir*)dir->data)->name;
|
char *dir_name = ((IconThemeDir*)dir->data)->name;
|
||||||
char *extension = (char*) ext->data;
|
char *extension = (char*) ext->data;
|
||||||
char *file_name = calloc(strlen(base_name) + strlen(theme_name) +
|
if (strlen(base_name) + strlen(theme_name) +
|
||||||
strlen(dir_name) + strlen(icon_name) + strlen(extension) + 100, 1);
|
strlen(dir_name) + strlen(icon_name) + strlen(extension) + 100 > file_name_size) {
|
||||||
|
file_name_size = strlen(base_name) + strlen(theme_name) +
|
||||||
|
strlen(dir_name) + strlen(icon_name) + strlen(extension) + 100;
|
||||||
|
file_name = realloc(file_name, file_name_size);
|
||||||
|
}
|
||||||
|
file_name[0] = 0;
|
||||||
// filename = directory/$(themename)/subdirectory/iconname.extension
|
// filename = directory/$(themename)/subdirectory/iconname.extension
|
||||||
sprintf(file_name, "%s/%s/%s/%s%s", base_name, theme_name, dir_name, icon_name, extension);
|
sprintf(file_name, "%s/%s/%s/%s%s", base_name, theme_name, dir_name, icon_name, extension);
|
||||||
if (DEBUG_ICON_SEARCH)
|
if (DEBUG_ICON_SEARCH)
|
||||||
|
@ -596,11 +604,12 @@ char *get_icon_path_helper(GSList *themes, const char *icon_name, int size)
|
||||||
printf("next_larger = %s; next_larger_size = %d\n", next_larger, next_larger_size);
|
printf("next_larger = %s; next_larger_size = %d\n", next_larger, next_larger_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
free(file_name);
|
free(file_name);
|
||||||
}
|
file_name = NULL;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (next_larger) {
|
if (next_larger) {
|
||||||
g_slist_free(extensions);
|
g_slist_free(extensions);
|
||||||
free(best_file_name);
|
free(best_file_name);
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <glib/gstdio.h>
|
#include <glib/gstdio.h>
|
||||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#ifdef HAVE_RSVG
|
#ifdef HAVE_RSVG
|
||||||
#include <librsvg/rsvg.h>
|
#include <librsvg/rsvg.h>
|
||||||
|
@ -150,8 +152,7 @@ void cleanup_launcher_theme(Launcher *launcher)
|
||||||
for (l = launcher->list_icons; l ; l = l->next) {
|
for (l = launcher->list_icons; l ; l = l->next) {
|
||||||
LauncherIcon *launcherIcon = (LauncherIcon*)l->data;
|
LauncherIcon *launcherIcon = (LauncherIcon*)l->data;
|
||||||
if (launcherIcon) {
|
if (launcherIcon) {
|
||||||
free_icon(launcherIcon->icon_scaled);
|
free_icon(launcherIcon->image);
|
||||||
free_icon(launcherIcon->icon_original);
|
|
||||||
free(launcherIcon->icon_name);
|
free(launcherIcon->icon_name);
|
||||||
free(launcherIcon->icon_path);
|
free(launcherIcon->icon_path);
|
||||||
free(launcherIcon->cmd);
|
free(launcherIcon->cmd);
|
||||||
|
@ -186,7 +187,7 @@ int resize_launcher(void *obj)
|
||||||
// Resize icons if necessary
|
// Resize icons if necessary
|
||||||
for (l = launcher->list_icons; l ; l = l->next) {
|
for (l = launcher->list_icons; l ; l = l->next) {
|
||||||
LauncherIcon *launcherIcon = (LauncherIcon *)l->data;
|
LauncherIcon *launcherIcon = (LauncherIcon *)l->data;
|
||||||
if (launcherIcon->icon_size != icon_size || !launcherIcon->icon_original) {
|
if (launcherIcon->icon_size != icon_size || !launcherIcon->image) {
|
||||||
launcherIcon->icon_size = icon_size;
|
launcherIcon->icon_size = icon_size;
|
||||||
launcherIcon->area.width = launcherIcon->icon_size;
|
launcherIcon->area.width = launcherIcon->icon_size;
|
||||||
launcherIcon->area.height = launcherIcon->icon_size;
|
launcherIcon->area.height = launcherIcon->icon_size;
|
||||||
|
@ -195,72 +196,72 @@ int resize_launcher(void *obj)
|
||||||
char *new_icon_path = get_icon_path(launcher->list_themes, launcherIcon->icon_name, launcherIcon->icon_size);
|
char *new_icon_path = get_icon_path(launcher->list_themes, launcherIcon->icon_name, launcherIcon->icon_size);
|
||||||
if (!new_icon_path) {
|
if (!new_icon_path) {
|
||||||
// Draw a blank icon
|
// Draw a blank icon
|
||||||
free_icon(launcherIcon->icon_original);
|
free_icon(launcherIcon->image);
|
||||||
launcherIcon->icon_original = NULL;
|
launcherIcon->image = NULL;
|
||||||
free_icon(launcherIcon->icon_scaled);
|
|
||||||
launcherIcon->icon_scaled = NULL;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (launcherIcon->icon_path && strcmp(new_icon_path, launcherIcon->icon_path) == 0) {
|
|
||||||
// If it's the same file just rescale
|
|
||||||
free_icon(launcherIcon->icon_scaled);
|
|
||||||
launcherIcon->icon_scaled = scale_icon(launcherIcon->icon_original, icon_size);
|
|
||||||
free(new_icon_path);
|
|
||||||
fprintf(stderr, "launcher.c %d: Using icon %s\n", __LINE__, launcherIcon->icon_path);
|
|
||||||
} else {
|
|
||||||
// Free the old files
|
// Free the old files
|
||||||
free_icon(launcherIcon->icon_original);
|
free_icon(launcherIcon->image);
|
||||||
free_icon(launcherIcon->icon_scaled);
|
launcherIcon->image = NULL;
|
||||||
launcherIcon->icon_original = launcherIcon->icon_scaled = NULL;
|
|
||||||
// Load the new file and scale
|
// Load the new file and scale
|
||||||
launcherIcon->icon_original = imlib_load_image_immediately(new_icon_path);
|
launcherIcon->image = imlib_load_image_immediately(new_icon_path);
|
||||||
#ifdef HAVE_RSVG
|
#ifdef HAVE_RSVG
|
||||||
if (!launcherIcon->icon_original && g_str_has_suffix(new_icon_path, ".svg")) {
|
if (!launcherIcon->image && g_str_has_suffix(new_icon_path, ".svg")) {
|
||||||
|
char suffix[128];
|
||||||
|
sprintf(suffix, "tmpicon-%d.png", getpid());
|
||||||
|
// We fork here because librsvg allocates memory like crazy
|
||||||
|
pid_t pid = fork();
|
||||||
|
if (pid == 0) {
|
||||||
|
// Child
|
||||||
GError* err = NULL;
|
GError* err = NULL;
|
||||||
RsvgHandle* svg = rsvg_handle_new_from_file(new_icon_path, &err);
|
RsvgHandle* svg = rsvg_handle_new_from_file(new_icon_path, &err);
|
||||||
|
|
||||||
if (err != NULL) {
|
if (err != NULL) {
|
||||||
fprintf(stderr, "Could not load svg image!: %s", err->message);
|
fprintf(stderr, "Could not load svg image!: %s", err->message);
|
||||||
g_error_free(err);
|
g_error_free(err);
|
||||||
launcherIcon->icon_original = NULL;
|
launcherIcon->image = NULL;
|
||||||
} else {
|
} else {
|
||||||
char suffix[128];
|
|
||||||
sprintf(suffix, "tmpicon-%d.png", getpid());
|
|
||||||
gchar *name = g_build_filename(g_get_user_config_dir(), "tint2", suffix, NULL);
|
gchar *name = g_build_filename(g_get_user_config_dir(), "tint2", suffix, NULL);
|
||||||
GdkPixbuf *pixbuf = rsvg_handle_get_pixbuf(svg);
|
GdkPixbuf *pixbuf = rsvg_handle_get_pixbuf(svg);
|
||||||
gdk_pixbuf_save(pixbuf, name, "png", NULL, NULL);
|
gdk_pixbuf_save(pixbuf, name, "png", NULL, NULL);
|
||||||
launcherIcon->icon_original = imlib_load_image_immediately_without_cache(name);
|
}
|
||||||
|
exit(0);
|
||||||
|
} else {
|
||||||
|
// Parent
|
||||||
|
waitpid(pid, 0, 0);
|
||||||
|
gchar *name = g_build_filename(g_get_user_config_dir(), "tint2", suffix, NULL);
|
||||||
|
launcherIcon->image = imlib_load_image_immediately_without_cache(name);
|
||||||
g_remove(name);
|
g_remove(name);
|
||||||
g_free(name);
|
g_free(name);
|
||||||
g_object_unref(G_OBJECT(pixbuf));
|
|
||||||
g_object_unref(G_OBJECT(svg));
|
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
launcherIcon->icon_original = imlib_load_image_immediately(new_icon_path);
|
launcherIcon->image = imlib_load_image_immediately(new_icon_path);
|
||||||
}
|
}
|
||||||
// On loading error, fallback to default
|
// On loading error, fallback to default
|
||||||
if (!launcherIcon->icon_original) {
|
if (!launcherIcon->image) {
|
||||||
free(new_icon_path);
|
free(new_icon_path);
|
||||||
new_icon_path = get_icon_path(launcher->list_themes, DEFAULT_ICON, launcherIcon->icon_size);
|
new_icon_path = get_icon_path(launcher->list_themes, DEFAULT_ICON, launcherIcon->icon_size);
|
||||||
if (new_icon_path)
|
if (new_icon_path)
|
||||||
launcherIcon->icon_original = imlib_load_image_immediately(new_icon_path);
|
launcherIcon->image = imlib_load_image_immediately(new_icon_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!launcherIcon->icon_original) {
|
if (!launcherIcon->image) {
|
||||||
// Loading default icon failed, draw a blank icon
|
// Loading default icon failed, draw a blank icon
|
||||||
free(new_icon_path);
|
free(new_icon_path);
|
||||||
} else {
|
} else {
|
||||||
// Loaded icon successfully
|
// Loaded icon successfully
|
||||||
launcherIcon->icon_scaled = scale_icon(launcherIcon->icon_original, launcherIcon->icon_size);
|
Imlib_Image original = launcherIcon->image;
|
||||||
|
launcherIcon->image = scale_icon(launcherIcon->image, launcherIcon->icon_size);
|
||||||
|
free_icon(original);
|
||||||
free(launcherIcon->icon_path);
|
free(launcherIcon->icon_path);
|
||||||
launcherIcon->icon_path = new_icon_path;
|
launcherIcon->icon_path = new_icon_path;
|
||||||
fprintf(stderr, "launcher.c %d: Using icon %s\n", __LINE__, launcherIcon->icon_path);
|
fprintf(stderr, "launcher.c %d: Using icon %s\n", __LINE__, launcherIcon->icon_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
count = g_slist_length(launcher->list_icons);
|
count = g_slist_length(launcher->list_icons);
|
||||||
|
|
||||||
|
@ -331,6 +332,7 @@ int resize_launcher(void *obj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,9 +357,8 @@ void draw_launcher_icon(void *obj, cairo_t *c)
|
||||||
{
|
{
|
||||||
LauncherIcon *launcherIcon = (LauncherIcon*)obj;
|
LauncherIcon *launcherIcon = (LauncherIcon*)obj;
|
||||||
|
|
||||||
Imlib_Image icon_scaled = launcherIcon->icon_scaled;
|
|
||||||
// Render
|
// Render
|
||||||
imlib_context_set_image(icon_scaled);
|
imlib_context_set_image(launcherIcon->image);
|
||||||
if (server.real_transparency) {
|
if (server.real_transparency) {
|
||||||
render_image(launcherIcon->area.pix, 0, 0);
|
render_image(launcherIcon->area.pix, 0, 0);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -23,8 +23,7 @@ typedef struct Launcher {
|
||||||
typedef struct LauncherIcon {
|
typedef struct LauncherIcon {
|
||||||
// always start with area
|
// always start with area
|
||||||
Area area;
|
Area area;
|
||||||
Imlib_Image icon_scaled;
|
Imlib_Image image;
|
||||||
Imlib_Image icon_original;
|
|
||||||
char *cmd;
|
char *cmd;
|
||||||
char *icon_name;
|
char *icon_name;
|
||||||
char *icon_path;
|
char *icon_path;
|
||||||
|
|
Loading…
Reference in a new issue