]> Dogcows Code - chaz/openbox/commitdiff
Rework the code provided by Kadlcik Libor for loading/showing icons in Openbox menus.
authorDana Jansens <danakj@orodu.net>
Fri, 8 Jan 2010 22:48:07 +0000 (17:48 -0500)
committerDana Jansens <danakj@orodu.net>
Fri, 8 Jan 2010 22:55:19 +0000 (17:55 -0500)
This changes how the imagecache works, you can load an image into it directly,
or you can load it by name (then it will load it from a file on disk).

NOTE: The name part is incomplete, as it needs to use the freedesktop.org icon
spec to search for the right file.  Also to resize it should look for another
icon on disk with the same name but different size (icon themes).

14 files changed:
Makefile.am
data/rc.xsd
obrender/image.c
obrender/image.h
obrender/imagecache.c
obrender/imagecache.h
obrender/render.h
openbox/client_list_combined_menu.c
openbox/client_list_menu.c
openbox/config.c
openbox/config.h
openbox/imageload.c [deleted file]
openbox/imageload.h [deleted file]
openbox/menu.c

index 164724676d3f3ba3dfbb4513cb257e8846008bc4..91b2303397f7c72f8daf0e1fb087b7deca506e69 100644 (file)
@@ -244,8 +244,6 @@ openbox_openbox_SOURCES = \
        openbox/grab.h \
        openbox/group.c \
        openbox/group.h \
-       openbox/imageload.c \
-       openbox/imageload.h \
        openbox/keyboard.c \
        openbox/keyboard.h \
        openbox/keytree.c \
index 062864261c63d5d59f64f1c9fb15d635b0ce502a..6d2ed1dd18264c405b7a3142329c329e823b3e2b 100644 (file)
             <xsd:element minOccurs="0" name="hideDelay" type="xsd:integer"/>
             <xsd:element minOccurs="0" name="middle" type="ob:bool"/>
             <xsd:element minOccurs="0" name="submenuShowDelay" type="xsd:integer"/>
-            <xsd:element minOccurs="0" name="applicationIcons" type="ob:bool"/>
+            <xsd:element minOccurs="0" name="showIcons" type="ob:bool"/>
             <xsd:element minOccurs="0" name="manageDesktops" type="ob:bool"/>
         </xsd:sequence>
     </xsd:complexType>
index c65cd2a5660b8cd8f96577b3d8912f6c8b29a224..671b7aeeb294f0c09beffad2121017c443bc3b46 100644 (file)
@@ -21,6 +21,9 @@
 #include "image.h"
 #include "color.h"
 #include "imagecache.h"
+#ifdef USE_IMLIB2
+#include <Imlib2.h>
+#endif
 
 #include <glib.h>
 
@@ -28,7 +31,8 @@
 #define FLOOR(i)        ((i) & (~0UL << FRACTION))
 #define AVERAGE(a, b)   (((((a) ^ (b)) & 0xfefefefeL) >> 1) + ((a) & (b)))
 
-void RrImagePicInit(RrImagePic *pic, gint w, gint h, RrPixel32 *data)
+void RrImagePicInit(RrImagePic *pic, const gchar *name,
+                    gint w, gint h, RrPixel32 *data)
 {
     gint i;
 
@@ -38,12 +42,14 @@ void RrImagePicInit(RrImagePic *pic, gint w, gint h, RrPixel32 *data)
     pic->sum = 0;
     for (i = w*h; i > 0; --i)
         pic->sum += *(data++);
+    pic->name = g_strdup(name);
 }
 
 static void RrImagePicFree(RrImagePic *pic)
 {
     if (pic) {
         g_free(pic->data);
+        g_free(pic->name);
         g_free(pic);
     }
 }
@@ -58,7 +64,10 @@ static void AddPicture(RrImage *self, RrImagePic ***list, gint *len,
 
     g_assert(pic->width > 0 && pic->height > 0);
 
-    g_assert(g_hash_table_lookup(self->cache->table, pic) == NULL);
+    if (pic->name)
+        g_assert(!g_hash_table_lookup(self->cache->name_table, pic->name));
+    else
+        g_assert(!g_hash_table_lookup(self->cache->pic_table, pic));
 
     /* grow the list */
     *list = g_renew(RrImagePic*, *list, ++*len);
@@ -70,8 +79,12 @@ static void AddPicture(RrImage *self, RrImagePic ***list, gint *len,
     /* set the new picture up at the front of the list */
     (*list)[0] = pic;
 
-    /* add the picture as a key to point to this image in the cache */
-    g_hash_table_insert(self->cache->table, (*list)[0], self);
+    /* add the name or the picture as a key to point to this image in the
+       cache */
+    if (pic->name)
+        g_hash_table_insert(self->cache->name_table, pic->name, self);
+    else
+        g_hash_table_insert(self->cache->pic_table, (*list)[0], self);
 
 /*
 #ifdef DEBUG
@@ -100,8 +113,11 @@ static void RemovePicture(RrImage *self, RrImagePic ***list,
 #endif
 */
 
-    /* remove the picture as a key in the cache */
-    g_hash_table_remove(self->cache->table, (*list)[i]);
+    /* remove the name or picture as a key in the cache */
+    if ((*list)[i]->name)
+        g_hash_table_remove(self->cache->name_table, (*list)[i]->name);
+    else
+        g_hash_table_remove(self->cache->pic_table, (*list)[i]);
 
     /* free the picture */
     RrImagePicFree((*list)[i]);
@@ -220,7 +236,7 @@ static RrImagePic* ResizeImage(RrPixel32 *src,
     }
 
     pic = g_new(RrImagePic, 1);
-    RrImagePicInit(pic, dstW, dstH, dststart);
+    RrImagePicInit(pic, NULL, dstW, dstH, dststart);
 
     return pic;
 }
@@ -326,9 +342,11 @@ RrImage* RrImageNew(RrImageCache *cache)
 }
 
 /*! Set function that will be called just before RrImage is destroyed. */
-void RrImageSetDestroyFunc(RrImage *image, RrImageDestroyFunc func)
+void RrImageSetDestroyFunc(RrImage *image, RrImageDestroyFunc func,
+                           gpointer data)
 {
     image->destroy_func = func;
+    image->destroy_data = data;
 }
 
 void RrImageRef(RrImage *self)
@@ -346,7 +364,7 @@ void RrImageUnref(RrImage *self)
 #endif
 */
         if (self->destroy_func)
-            self->destroy_func(self);
+            self->destroy_func(self, self->destroy_data);
         while (self->n_original > 0)
             RemovePicture(self, &self->original, 0, &self->n_original);
         while (self->n_resized > 0)
@@ -355,10 +373,8 @@ void RrImageUnref(RrImage *self)
     }
 }
 
-/*! Add a new picture with the given RGBA pixel data and dimensions into the
-  RrImage.  This adds an "original" picture to the image.
-*/
-void RrImageAddPicture(RrImage *self, RrPixel32 *data, gint w, gint h)
+static void AddPictureFromData(RrImage *self, const char *name,
+                               const RrPixel32 *data, gint w, gint h)
 {
     gint i;
     RrImagePic *pic;
@@ -384,10 +400,55 @@ void RrImageAddPicture(RrImage *self, RrPixel32 *data, gint w, gint h)
 
     /* add the new picture */
     pic = g_new(RrImagePic, 1);
-    RrImagePicInit(pic, w, h, g_memdup(data, w*h*sizeof(RrPixel32)));
+    RrImagePicInit(pic, name, w, h, g_memdup(data, w*h*sizeof(RrPixel32)));
     AddPicture(self, &self->original, &self->n_original, pic);
 }
 
+gboolean RrImageAddPictureName(RrImage *self, const gchar *name)
+{
+#ifdef USE_IMLIB2
+    Imlib_Image img;
+    gint w, h;
+    RrPixel32 *data;
+    gchar *path;
+
+    /* XXX find the path via freedesktop icon spec (use obt) ! */
+    path = g_strdup(name);
+
+    if (!(img = imlib_load_image(path)))
+        g_message("Cannot load image \"%s\" from file \"%s\"", name, path);
+    g_free(path);
+
+    if (!img)
+        return FALSE; /* failed to load it */
+
+    /* Get data and dimensions of the image.
+
+       WARNING: This stuff is NOT threadsafe !!
+    */
+    imlib_context_set_image(img);
+    data = imlib_image_get_data_for_reading_only();
+    w = imlib_image_get_width();
+    h = imlib_image_get_height();
+
+    /* add it to the RrImage, and set its name */
+    AddPictureFromData(self, name, data, w, h);
+
+    imlib_free_image();
+    return TRUE;
+#else
+    return FALSE;
+#endif
+}
+
+/*! Add a new picture with the given RGBA pixel data and dimensions into the
+  RrImage.  This adds an "original" picture to the image.
+*/
+void RrImageAddPicture(RrImage *self, const RrPixel32 *data, gint w, gint h)
+{
+    AddPictureFromData(self, NULL, data, w, h);    
+}
+
 /*! Remove the picture from the RrImage which has the given dimensions. This
  removes an "original" picture from the image.
 */
index b478daf9f5c797eb194379ba5eb729055cc6fc86..6e4a50e02d33b3d8b52005b96c32de82046a761e 100644 (file)
@@ -23,7 +23,8 @@
 #include "geom.h"
 
 /*! Initialize an RrImagePicture to the specified dimensions and pixel data */
-void RrImagePicInit(RrImagePic *pic, gint w, gint h, RrPixel32 *data);
+void RrImagePicInit(RrImagePic *pic, const gchar *path,
+                    gint w, gint h, RrPixel32 *data);
 
 void RrImageDrawImage(RrPixel32 *target, RrTextureImage *img,
                       gint target_w, gint target_h,
index fde1e7a06ce5e03805f9fdd357006ff3c29704f5..036ac121091a5b8fcf8a03031fd560f274193df3 100644 (file)
@@ -32,9 +32,9 @@ RrImageCache* RrImageCacheNew(gint max_resized_saved)
     self = g_new(RrImageCache, 1);
     self->ref = 1;
     self->max_resized_saved = max_resized_saved;
-    self->table = g_hash_table_new((GHashFunc)RrImagePicHash,
-                                   (GEqualFunc)RrImagePicEqual);
-    self->file_name_table = NULL;
+    self->pic_table = g_hash_table_new((GHashFunc)RrImagePicHash,
+                                       (GEqualFunc)RrImagePicEqual);
+    self->name_table = g_hash_table_new(g_str_hash, g_str_equal);
     return self;
 }
 
@@ -46,22 +46,31 @@ void RrImageCacheRef(RrImageCache *self)
 void RrImageCacheUnref(RrImageCache *self)
 {
     if (self && --self->ref == 0) {
-        g_assert(g_hash_table_size(self->table) == 0);
-        g_assert(self->file_name_table == NULL);
-        g_hash_table_unref(self->table);
+        g_assert(g_hash_table_size(self->pic_table) == 0);
+        g_hash_table_unref(self->pic_table);
+        self->pic_table = NULL;
+
+        g_assert(g_hash_table_size(self->name_table) == 0);
+        g_hash_table_destroy(self->name_table);
+        self->name_table = NULL;
 
         g_free(self);
     }
 }
 
+RrImage* RrImageCacheFindName(RrImageCache *self, const gchar *name)
+{
+    return g_hash_table_lookup(self->name_table, name);
+}
+
 /*! Finds an image in the cache, if it is already in there */
 RrImage* RrImageCacheFind(RrImageCache *self,
                           RrPixel32 *data, gint w, gint h)
 {
     RrImagePic pic;
 
-    RrImagePicInit(&pic, w, h, data);
-    return g_hash_table_lookup(self->table, &pic);
+    RrImagePicInit(&pic, NULL, w, h, data);
+    return g_hash_table_lookup(self->pic_table, &pic);
 }
 
 #define hashsize(n) ((RrPixel32)1<<(n))
index a61fae67438f9b4425ce05e17275016d6a30a374..9baf34bb7fc257972c9cfe598c4555b93d1a074f 100644 (file)
@@ -45,11 +45,14 @@ struct _RrImageCache {
     */
     gint max_resized_saved;
 
-    GHashTable *table;
-
-    /* Used to find out if an image file has already been loaded.
-       Quick file_name -> RrImage lookup. */
-    GHashTable *file_name_table;
+    /*! A hash table of images in the cache that don't have a file name
+      attached to them, with their key being a hash of the contents of the
+      image. */
+    GHashTable *pic_table;
+
+    /*! Used to find out if an image file has already been loaded.
+      Provides a quick file_name -> RrImage lookup. */
+    GHashTable *name_table;
 };
 
 #endif
index 7aa9d698249bd841a066e782fa895e795b44a2cd..64c2f6a114a1d2aa17aa8b700c103e9c13f0f5ce 100644 (file)
@@ -230,9 +230,13 @@ struct _RrImagePic {
     /* The sum of all the pixels.  This is used to compare pictures if their
        hashes match. */
     gint sum;
+    /* The name of the image.  This is used to determine
+       if the named image already is loaded.  May be NULL if the image
+       was not loaded from disk. */
+    gchar *name;
 };
 
-typedef void (*RrImageDestroyFunc)(RrImage *image);
+typedef void (*RrImageDestroyFunc)(RrImage *image, gpointer data);
 
 /*! An RrImage is a sort of meta-image.  It can contain multiple versions of
   an image at different sizes, which may or may not be completely different
@@ -252,10 +256,11 @@ struct _RrImage {
       RrImage. */
     RrImagePic **resized;
     gint n_resized;
+
     /* This function (if not NULL) will be called just before destroying
       RrImage. */
     RrImageDestroyFunc destroy_func;
+    gpointer           destroy_data;
 };
 
 /* these are the same on all endian machines because it seems to be dependant
@@ -343,12 +348,19 @@ void          RrImageCacheUnref(RrImageCache *self);
 /*! Finds an image in the cache, if it is already in there */
 RrImage*      RrImageCacheFind(RrImageCache *self,
                                RrPixel32 *data, gint w, gint h);
+/*! Finds an image in the cache, by searching for the name of the image */
+RrImage*      RrImageCacheFindName(RrImageCache *self,
+                                   const gchar *name);
 
 RrImage* RrImageNew(RrImageCache *cache);
 void     RrImageRef(RrImage *im);
 void     RrImageUnref(RrImage *im);
 
-void     RrImageAddPicture(RrImage *im, RrPixel32 *data, gint w, gint h);
+void     RrImageAddPicture(RrImage *im, const RrPixel32 *data, gint w, gint h);
+/*! Adds a picture by name, from a file on disk. 
+  @name Can be a full path to an image, or it can be a name as per the
+        freedesktop.org icon spec. */
+gboolean RrImageAddPictureName(RrImage *im, const gchar *name);
 void     RrImageRemovePicture(RrImage *im, gint w, gint h);
 
 G_END_DECLS
index 22840ad6ae9c5e53e61c6e0de1b4070879d5bac7..f4aae884eb3139892efb49570a09eeb203290ff3 100644 (file)
@@ -67,7 +67,7 @@ static gboolean self_update(ObMenuFrame *frame, gpointer data)
                     e = menu_add_normal(menu, desktop, c->title, NULL, FALSE);
                 }
 
-                if (config_menu_client_list_icons) {
+                if (config_menu_show_icons) {
                     e->data.normal.icon = client_icon(c);
                     RrImageRef(e->data.normal.icon);
                     e->data.normal.icon_alpha =
index 3f79f621f10882017bcd92276e1b9e197bb273bd..2d62c3e9ff05707b6fcac292f4c3b187584b149b 100644 (file)
@@ -69,7 +69,7 @@ static gboolean desk_menu_update(ObMenuFrame *frame, gpointer data)
                 e = menu_add_normal(menu, d->desktop, c->title, NULL, FALSE);
             }
 
-            if (config_menu_client_list_icons) {
+            if (config_menu_show_icons) {
                 e->data.normal.icon = client_icon(c);
                 RrImageRef(e->data.normal.icon);
                 e->data.normal.icon_alpha = c->iconic ? OB_ICONIC_ALPHA : 0xff;
index 304079c96afde1f08a2162e0c8edfcef424b95f0..6963559d862c12a5f797baa917958653da5b2b1d 100644 (file)
@@ -94,9 +94,8 @@ guint    config_menu_hide_delay;
 gboolean config_menu_middle;
 guint    config_submenu_show_delay;
 guint    config_submenu_hide_delay;
-gboolean config_menu_client_list_icons;
 gboolean config_menu_manage_desktops;
-gboolean config_menu_user_show_icons;
+gboolean config_menu_show_icons;
 
 GSList *config_menu_files;
 
@@ -817,17 +816,14 @@ static void parse_menu(xmlNodePtr node, gpointer d)
         config_submenu_show_delay = obt_xml_node_int(n);
     if ((n = obt_xml_find_node(node, "submenuHideDelay")))
         config_submenu_hide_delay = obt_xml_node_int(n);
-    if ((n = obt_xml_find_node(node, "applicationIcons")))
-        config_menu_client_list_icons = obt_xml_node_bool(n);
     if ((n = obt_xml_find_node(node, "manageDesktops")))
         config_menu_manage_desktops = obt_xml_node_bool(n);
     if ((n = obt_xml_find_node(node, "showIcons"))) {
-        config_menu_user_show_icons = obt_xml_node_bool(n);
-        #ifndef USE_IMLIB2
-        if (config_menu_user_show_icons)
-            g_message(_("Openbox was compiled without Imlib2."
-                      " Icons in user-defined menus will NOT be loaded."));
-        #endif
+        config_menu_show_icons = obt_xml_node_bool(n);
+#ifndef USE_IMLIB2
+        if (config_menu_show_icons)
+            g_message(_("Openbox was compiled without Imlib2 image loading support. Icons in menus will not be loaded."));
+#endif
     }
 
     while ((node = obt_xml_find_node(node, "file"))) {
@@ -1031,10 +1027,9 @@ void config_startup(ObtXmlInst *i)
     config_menu_middle = FALSE;
     config_submenu_show_delay = 200;
     config_submenu_hide_delay = 400;
-    config_menu_client_list_icons = TRUE;
     config_menu_manage_desktops = TRUE;
     config_menu_files = NULL;
-    config_menu_user_show_icons = TRUE;
+    config_menu_show_icons = TRUE;
 
     obt_xml_register(i, "menu", parse_menu, NULL);
 
index 1825f47739e70d618c0c226452079bb32a826f37..0e4ccb5cf0f0c80717aed2158f9b2e122caed00c 100644 (file)
@@ -193,12 +193,10 @@ extern gboolean config_menu_middle;
 extern guint    config_submenu_show_delay;
 /*! Delay before closing a submenu in milliseconds */
 extern guint    config_submenu_hide_delay;
-/*! Show icons in client_list_menu */
-extern gboolean config_menu_client_list_icons;
 /*! Show manage desktops in client_list_menu */
 extern gboolean config_menu_manage_desktops;
 /*! Load & show icons in user-defined menus */
-extern gboolean config_menu_user_show_icons;
+extern gboolean config_menu_show_icons;
 /*! User-specified menu files */
 extern GSList *config_menu_files;
 /*! Per app settings */
diff --git a/openbox/imageload.c b/openbox/imageload.c
deleted file mode 100644 (file)
index e7c1ddf..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
-   imageload.c for the Openbox window manager
-   by Libor Kadlcik (aka KadlSoft)
-*/
-
-/*
-    All loaded images are cached. There's no separate cache for the images,
-    instead they are simply stored in image cache (RrImageCache) as RrImages,
-    ready to be used.
-    Every RrImage loaded from file is associated with name of the file. This is
-    done by file name table (RrImageCache.file_name_table), which is a simple
-    hash table, where file names are keys to pointers to RrImage.
-    If you request to load file that is already in image cache, nothing will be
-    loaded and you just got the RrImage from cache.
-    When RrImage is destroyed (see RrImageDestroyNotify), the file name - pointer
-    to RrImage pair is removed from the file name table.
-*/
-
-#include "debug.h"
-#include "menu.h"
-#include "openbox.h"
-#include "gettext.h"
-#include "obrender/render.h"
-#include "obrender/image.h"
-#include "obrender/imagecache.h"
-#include "imageload.h"
-#include <Imlib2.h>
-
-#ifndef USE_IMLIB2
-RrImage* RrImageFetchFromFile(RrImageCache *cache, const gchar *name)
-{
-    return NULL;
-}
-#else
-
-static void CreateFileNameTable(RrImageCache *self)
-{
-    g_assert(self->file_name_table == NULL);
-    self->file_name_table = g_hash_table_new(&g_str_hash, &g_str_equal);
-}
-
-static void DestroyFileNameTable(RrImageCache *self)
-{
-    g_assert(g_hash_table_size(self->file_name_table) == 0);
-    g_hash_table_destroy(self->file_name_table);
-    self->file_name_table = NULL;
-}
-
-/*! Return file name from which this image has been loaded. */
-static gchar* GetFileName(RrImage *image)
-{
-    GHashTableIter iter;
-    void *key, *value;
-
-    g_hash_table_iter_init(&iter, image->cache->file_name_table);
-    while (g_hash_table_iter_next(&iter, &key, &value)) {
-        if (value == image)
-            return key;
-    }
-    return NULL;
-}
-
-/* RrImage is about to be deleted. So remove it from file name table. */
-static void RrImageDestroyNotify(RrImage *image)
-{
-    gchar *file_name = GetFileName(image);
-    g_assert(file_name != NULL);
-    ob_debug("Image \"%s\" no longer needed", file_name);
-    g_hash_table_remove(image->cache->file_name_table, file_name);
-    g_free(file_name);
-
-    if (g_hash_table_size(image->cache->file_name_table) == 0) {
-        ob_debug("No RrImage in file_name_table, destroying");
-        DestroyFileNameTable(image->cache);
-    }
-}
-
-#if (RrDefaultAlphaOffset != 24 || RrDefaultRedOffset != 16 \
-    || RrDefaultGreenOffset != 8 || RrDefaultBlueOffset != 0)
-#error RrImageFetchFromFile cannot handle current bit layout of RrPixel32.
-#endif
-
-/*! Load image from specified file and create RrImage for it (RrImage will be
-    linked into specified image cache). Reference count of the RrImage will
-    be set to 1.
-    If that image has already been loaded into the image cache, RrImage
-    from the cache will be returned and its reference count will be incremented.
-*/
-RrImage* RrImageFetchFromFile(RrImageCache *cache, const gchar *name)
-{
-    RrImage *rr_image, *found_rr_image;
-    gint w, h;
-    DATA32 *ro_data;
-
-    imlib_set_color_usage(128);
-
-    if (cache->file_name_table == NULL)
-        CreateFileNameTable(cache);
-
-    /* Find out if that image has already been loaded to this cache. */
-    rr_image = g_hash_table_lookup(cache->file_name_table, name);
-    if (rr_image && rr_image->cache == cache) {
-        ob_debug("\"%s\" already loaded in this image cache.", name);
-        RrImageRef(rr_image);
-        return rr_image;
-    }
-
-    Imlib_Image imlib_image = imlib_load_image(name);
-    if (imlib_image == NULL) {
-        g_message(_("Cannot load image from file \"%s\""), name);
-        return NULL;
-    }
-
-    /* Get data and dimensions of the image. */
-    imlib_context_set_image(imlib_image);
-    g_message("Alpha = %d\n", imlib_image_has_alpha());
-    ro_data = imlib_image_get_data_for_reading_only();
-    w = imlib_image_get_width();
-    h = imlib_image_get_height();
-    ob_debug("Loaded \"%s\", dimensions %dx%d", name, w, h);
-
-    /* There must not be any duplicated pictures in RrImageCache. */
-    found_rr_image = RrImageCacheFind(cache, ro_data, w, h);
-    if (found_rr_image) {
-        rr_image = found_rr_image;
-        RrImageRef(rr_image);
-        ob_debug("Image \"%s\" is duplicate", name);
-    }
-    else {
-        /* Create RrImage from the image and add it to file name table. */
-        rr_image = RrImageNew(cache);
-        RrImageSetDestroyFunc(rr_image, &RrImageDestroyNotify);
-        /* XXX: Is Imlib2's format of DATA32 always identical to RrPixel32? */
-        RrImageAddPicture(rr_image, ro_data, w, h);
-        g_hash_table_insert(cache->file_name_table, g_strdup(name), rr_image);
-    }
-
-    imlib_free_image();
-
-    return rr_image;
-}
-
-#endif
diff --git a/openbox/imageload.h b/openbox/imageload.h
deleted file mode 100644 (file)
index 21e7c9b..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __imageload_h
-#define __imageload_h
-
-#include "obrender/render.h"
-RrImage* RrImageFetchFromFile(RrImageCache *cache, const gchar *name);
-
-#endif
index 77d9548c0da34069884a41d57042230849f9751a..524220c0af14325eb691924ff1ea640928d44bf6 100644 (file)
@@ -36,7 +36,6 @@
 #include "gettext.h"
 #include "obt/xml.h"
 #include "obt/paths.h"
-#include "imageload.h"
 
 typedef struct _ObMenuParseState ObMenuParseState;
 
@@ -275,29 +274,39 @@ static void parse_menu_item(xmlNodePtr node,  gpointer data)
 
     if (state->parent) {
         /* Don't try to extract "icon" attribute if icons in user-defined
-          menus are not enabled. */
-        if (!(config_menu_user_show_icons &&
-            obt_xml_attr_string(node, "icon", &icon)))
-        {
-            icon = NULL;
-        }
+           menus are not enabled. */
 
         if (obt_xml_attr_string(node, "label", &label)) {
+            xmlNodePtr c;
             GSList *acts = NULL;
 
-            node = obt_xml_find_node(node->children, "action");
-            while (node) {
-                ObActionsAct *action = actions_parse(node);
+            c = obt_xml_find_node(node->children, "action");
+            while (c) {
+                ObActionsAct *action = actions_parse(c);
                 if (action)
                     acts = g_slist_append(acts, action);
-                node = obt_xml_find_node(node->next, "action");
+                c = obt_xml_find_node(node->next, "action");
             }
             e = menu_add_normal(state->parent, -1, label, acts, TRUE);
             
-            if (icon) { /* Icon will be used. */
-                e->data.normal.icon = RrImageFetchFromFile(ob_rr_icons, icon);
+            if (config_menu_show_icons &&
+                obt_xml_attr_string(node, "icon", &icon))
+            {
+                RrImage *ic;
+
+                ic = RrImageCacheFindName(ob_rr_icons, icon);
+                if (ic)
+                    RrImageRef(ic);
+                else {
+                    ic = RrImageNew(ob_rr_icons);
+                    if (!RrImageAddPictureName(ic, icon))
+                        RrImageUnref(ic); /* no need to keep it around */
+                }
+                e->data.normal.icon = ic;
+
                 if (e->data.normal.icon)
                     e->data.normal.icon_alpha = 0xff;
+
                 g_free(icon);
             }
             g_free(label);
This page took 0.041182 seconds and 4 git commands to generate.