My take icon icon resizing



Attached is my take on changing the stock icon sizes; it's
basically a complete rewrite from Padraig's patch in:

 http://bugzilla.gnome.org/show_bug.cgi?id=70648

Major differences include:

 - Since icon sizes are set from a GtkSettings setting,
   they have to be per-GtkSettings object. To this end,
   I added:

    gboolean gtk_icon_size_lookup_for_settings (GtkSettings *settings,
					        GtkIconSize  size,
					        gint        *width,
					        gint        *height);

   And the per-settings sizes are stored attached to
   the GtkSettings object.

 - I changed the string format from "gtk-menu 30,30:gtk-dialog 40,40"
   to "gtk-menu=30,30:gtk-dialog=40,40", since it seemed a little
   clearer with an explicit delimiter character.

 - I changed the string parser from being heuristic to validating.
   (Using some string scanning utilities from Pango rather than 
   than strsplit()/atoi())

 - I organized things so as much of the logic as possible lived
   in gtkiconfactory rather than slopping over into gtkrc.c

   (I made one private API addition to gtkrc.c - _gtk_rc_reset_styles()
   that resets all the styles so everything resizes; I wrote
   the function originally for some 
   change-font-rendering-options-on-the-fly patches.)

It seems to work in testing and I think it's basically the right
way to go about things. There maybe a little more cleanup to
do, but other than that I think it's ready to go in.

Regards,
                                        Owen

Index: gdk/x11/gdkevents-x11.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkevents-x11.c,v
retrieving revision 1.88
diff -u -p -r1.88 gdkevents-x11.c
--- gdk/x11/gdkevents-x11.c	19 Sep 2002 20:52:42 -0000	1.88
+++ gdk/x11/gdkevents-x11.c	19 Sep 2002 22:32:48 -0000
@@ -2200,6 +2200,7 @@ static struct
   { "Gtk/CanChangeAccels", "gtk-can-change-accels" },
   { "Gtk/ColorPalette", "gtk-color-palette" },
   { "Gtk/FontName", "gtk-font-name" },
+  { "Gtk/IconSizes", "gtk-icon-sizes" },
   { "Gtk/KeyThemeName", "gtk-key-theme-name" },
   { "Gtk/ToolbarStyle", "gtk-toolbar-style" },
   { "Gtk/ToolbarIconSize", "gtk-toolbar-icon-size" },
Index: gtk/gtkiconfactory.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkiconfactory.c,v
retrieving revision 1.42
diff -u -p -r1.42 gtkiconfactory.c
--- gtk/gtkiconfactory.c	16 Sep 2002 22:52:22 -0000	1.42
+++ gtk/gtkiconfactory.c	19 Sep 2002 22:32:48 -0000
@@ -24,8 +24,11 @@
  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
  */
 
+#include <pango/pango-utils.h>	/* For pango_scan_* */
 #include "gtkiconfactory.h"
 #include "stock-icons/gtkstockpixbufs.h"
+#include "gtkdebug.h"
+#include "gtksettings.h"
 #include "gtkstock.h"
 #include "gtkintl.h"
 #include <stdlib.h>
@@ -63,6 +66,10 @@ static void gtk_icon_factory_class_init 
 static void gtk_icon_factory_finalize   (GObject             *object);
 static void get_default_icons           (GtkIconFactory      *icon_factory);
 
+static GtkIconSize icon_size_register_intern (const gchar *name,
+					      gint         width,
+					      gint         height);
+
 GType
 gtk_icon_factory_get_type (void)
 {
@@ -800,7 +807,9 @@ get_default_icons (GtkIconFactory *facto
   add_unsized (factory, stock_zoom_out_24, GTK_STOCK_ZOOM_OUT);
 }
 
-/* Sizes */
+/************************************************************
+ *                    Icon size handling                    *
+ ************************************************************/
 
 typedef struct _IconSize IconSize;
 
@@ -821,6 +830,14 @@ struct _IconAlias
   gint   target;
 };
 
+typedef struct _SettingsIconSize SettingsIconSize;
+
+struct _SettingsIconSize
+{
+  gint width;
+  gint height;
+};
+
 static GHashTable *icon_aliases = NULL;
 static IconSize *icon_sizes = NULL;
 static gint      icon_sizes_allocated = 0;
@@ -896,13 +913,293 @@ init_icon_sizes (void)
     }
 }
 
+static void
+free_settings_sizes (gpointer data)
+{
+  g_array_free (data, TRUE);
+}
+
+static GArray *
+get_settings_sizes (GtkSettings *settings,
+		    gboolean    *created)
+{
+  GArray *settings_sizes;
+  static GQuark sizes_quark = 0;
+
+  if (!sizes_quark)
+    sizes_quark = g_quark_from_static_string ("gtk-icon-sizes");
+
+  settings_sizes = g_object_get_qdata (G_OBJECT (settings), sizes_quark);
+  if (!settings_sizes)
+    {
+      settings_sizes = g_array_new (FALSE, FALSE, sizeof (SettingsIconSize));
+      g_object_set_qdata_full (G_OBJECT (settings), sizes_quark,
+			       settings_sizes, free_settings_sizes);
+      if (created)
+	*created = TRUE;
+    }
+
+  return settings_sizes;
+}
+
+static void
+icon_size_set_for_settings (GtkSettings *settings,
+			    const gchar *size_name,
+			    gint         width,
+			    gint         height)
+{
+  GtkIconSize size;
+  GArray *settings_sizes;
+  SettingsIconSize *settings_size;
+
+  g_return_if_fail (size_name != NULL);
+
+  size = gtk_icon_size_from_name (size_name);
+  if (size == GTK_ICON_SIZE_INVALID)
+    /* Reserve a place */
+    size = icon_size_register_intern (size_name, -1, -1);
+  
+  settings_sizes = get_settings_sizes (settings, NULL);
+  if (size >= settings_sizes->len)
+    {
+      SettingsIconSize unset = { -1, -1 };
+      gint i;
+
+      for (i = settings_sizes->len; i <= size; i++)
+	g_array_append_val (settings_sizes, unset);
+    }
+
+  settings_size = &g_array_index (settings_sizes, SettingsIconSize, size);
+  
+  settings_size->width = width;
+  settings_size->height = height;
+}
+
+/* Like pango_parse_word, but accept - as well
+ */
+static gboolean
+scan_icon_size_name (const char **pos, GString *out)
+{
+  const char *p = *pos;
+
+  while (g_ascii_isspace (*p))
+    p++;
+  
+  if (!((*p >= 'A' && *p <= 'Z') ||
+	(*p >= 'a' && *p <= 'z') ||
+	*p == '_' || *p == '-'))
+    return FALSE;
+
+  g_string_truncate (out, 0);
+  g_string_append_c (out, *p);
+  p++;
+
+  while ((*p >= 'A' && *p <= 'Z') ||
+	 (*p >= 'a' && *p <= 'z') ||
+	 (*p >= '0' && *p <= '9') ||
+	 *p == '_' || *p == '-')
+    {
+      g_string_append_c (out, *p);
+      p++;
+    }
+
+  *pos = p;
+
+  return TRUE;
+}
+
+static void
+icon_size_setting_parse (GtkSettings *settings,
+			 const gchar *icon_size_string)
+{
+  GString *name_buf = g_string_new (NULL);
+  const gchar *p = icon_size_string;
+
+  while (pango_skip_space (&p))
+    {
+      gint width, height;
+      
+      if (!scan_icon_size_name (&p, name_buf))
+	goto err;
+
+      if (!pango_skip_space (&p))
+	goto err;
+
+      if (*p != '=')
+	goto err;
+
+      p++;
+
+      if (!pango_scan_int (&p, &width))
+	goto err;
+
+      if (!pango_skip_space (&p))
+	goto err;
+
+      if (*p != ',')
+	goto err;
+
+      p++;
+
+      if (!pango_scan_int (&p, &height))
+	goto err;
+
+      if (width > 0 && height > 0)
+	{
+	  icon_size_set_for_settings (settings, name_buf->str,
+				      width, height);
+	}
+      else
+	{
+	  g_warning ("Invalid size in gtk-icon-sizes: %d,%d\n", width, height);
+	}
+
+      pango_skip_space (&p);
+      if (*p == '\0')
+	break;
+      if (*p == ':')
+	p++;
+      else
+	goto err;
+    }
+
+  g_string_free (name_buf, TRUE);
+  return;
+
+ err:
+  g_warning ("Error parsing gtk-icon-sizes string:\n\t'%s'", icon_size_string);
+  g_string_free (name_buf, TRUE);
+}
+
+static void
+icon_size_set_all_from_settings (GtkSettings *settings)
+{
+  GArray *settings_sizes;
+  gchar *icon_size_string;
+
+  /* Reset old settings */
+  settings_sizes = get_settings_sizes (settings, NULL);
+  g_array_set_size (settings_sizes, 0);
+
+  g_object_get (settings,
+		"gtk-icon-sizes", &icon_size_string,
+		NULL);
+
+  if (icon_size_string)
+    {
+      icon_size_setting_parse (settings, icon_size_string);
+      g_free (icon_size_string);
+    }
+}
+
+static void
+icon_size_settings_changed (GtkSettings  *settings,
+			    GParamSpec   *pspec)
+{
+  icon_size_set_all_from_settings (settings);
+
+  _gtk_rc_reset_styles (settings);
+}
+
+static void
+icon_sizes_init_for_settings (GtkSettings *settings)
+{
+  g_signal_connect (settings,
+		    "notify::gtk-icon-sizes",
+		    G_CALLBACK (icon_size_settings_changed),
+		    NULL);
+  
+  icon_size_set_all_from_settings (settings);
+}
+     
+gboolean
+icon_size_lookup_intern (GtkSettings *settings,
+			 GtkIconSize  size,
+			 gint        *widthp,
+			 gint        *heightp)
+{
+  GArray *settings_sizes;
+  gint width_for_settings = -1;
+  gint height_for_settings = -1;
+  
+  init_icon_sizes ();
+
+  if (size >= icon_sizes_used || icon_sizes[size].width < 0)
+    return FALSE;
+
+  if (size == GTK_ICON_SIZE_INVALID)
+    return FALSE;
+
+  if (settings)
+    {
+      gboolean initial = FALSE;
+      
+      settings_sizes = get_settings_sizes (settings, &initial);
+      if (initial)
+	icon_sizes_init_for_settings (settings);
+  
+      if (size < settings_sizes->len)
+	{
+	  SettingsIconSize *settings_size;
+	  
+	  settings_size = &g_array_index (settings_sizes, SettingsIconSize, size);
+	  
+	  width_for_settings = settings_size->width;
+	  height_for_settings = settings_size->height;
+	}
+    }
+
+  if (widthp)
+    *widthp = width_for_settings >= 0 ? width_for_settings : icon_sizes[size].width;
+
+  if (heightp)
+    *heightp = height_for_settings >= 0 ? height_for_settings : icon_sizes[size].height;
+
+  return TRUE;
+}
+
+/**
+ * gtk_icon_size_lookup_for_settings:
+ * @GtkSettings: a #GtkSettings object, used to determine
+ *   which set of user preferences to used.
+ * @size: an icon size
+ * @width: location to store icon width
+ * @height: location to store icon height
+ *
+ * Obtains the pixel size of a semantic icon size, possibly
+ * modified by user preferences for a particular #GtkSettings
+ * Normally @size would be
+ * #GTK_ICON_SIZE_MENU, #GTK_ICON_SIZE_BUTTON, etc.  This function
+ * isn't normally needed, gtk_widget_render_icon() is the usual
+ * way to get an icon for rendering, then just look at the size of
+ * the rendered pixbuf. The rendered pixbuf may not even correspond to
+ * the width/height returned by gtk_icon_size_lookup(), because themes
+ * are free to render the pixbuf however they like, including changing
+ * the usual size.
+ * 
+ * Return value: %TRUE if @size was a valid size
+ **/
+gboolean
+gtk_icon_size_lookup_for_settings (GtkSettings *settings,
+				   GtkIconSize  size,
+				   gint        *widthp,
+				   gint        *heightp)
+{
+  g_return_val_if_fail (GTK_IS_SETTINGS (settings), FALSE);
+
+  return icon_size_lookup_intern (settings, size, widthp, heightp);
+}
+
 /**
  * gtk_icon_size_lookup:
  * @size: an icon size
  * @width: location to store icon width
  * @height: location to store icon height
  *
- * Obtains the pixel size of a semantic icon size, normally @size would be
+ * Obtains the pixel size of a semantic icon size, possibly
+ * modified by user preferences for the default #GtkSettings.
+ * (See gtk_icon_size_lookup_for_settings().)
+ * Normally @size would be
  * #GTK_ICON_SIZE_MENU, #GTK_ICON_SIZE_BUTTON, etc.  This function
  * isn't normally needed, gtk_widget_render_icon() is the usual
  * way to get an icon for rendering, then just look at the size of
@@ -918,21 +1215,55 @@ gtk_icon_size_lookup (GtkIconSize  size,
                       gint        *widthp,
                       gint        *heightp)
 {
-  init_icon_sizes ();
+  GTK_NOTE (MULTIHEAD,
+	    g_warning ("gtk_icon_size_lookup ()) is not multihead safe"));
 
-  if (size >= icon_sizes_used)
-    return FALSE;
+  return gtk_icon_size_lookup_for_settings (gtk_settings_get_default (),
+					    size, widthp, heightp);
+}
 
-  if (size == GTK_ICON_SIZE_INVALID)
-    return FALSE;
+static GtkIconSize
+icon_size_register_intern (const gchar *name,
+			   gint         width,
+			   gint         height)
+{
+  IconAlias *old_alias;
+  GtkIconSize size;
   
-  if (widthp)
-    *widthp = icon_sizes[size].width;
+  init_icon_sizes ();
 
-  if (heightp)
-    *heightp = icon_sizes[size].height;
+  old_alias = g_hash_table_lookup (icon_aliases, name);
+  if (old_alias && icon_sizes[old_alias->target].width > 0)
+    {
+      g_warning ("Icon size name '%s' already exists", name);
+      return GTK_ICON_SIZE_INVALID;
+    }
 
-  return TRUE;
+  if (old_alias)
+    {
+      size = old_alias->target;
+    }
+  else
+    {
+      if (icon_sizes_used == icon_sizes_allocated)
+	{
+	  icon_sizes_allocated *= 2;
+	  icon_sizes = g_renew (IconSize, icon_sizes, icon_sizes_allocated);
+	}
+
+      size = icon_sizes_used++;
+
+      /* alias to self. */
+      gtk_icon_size_register_alias (name, size);
+
+      icon_sizes[size].size = size;
+      icon_sizes[size].name = g_strdup (name);
+    }
+
+  icon_sizes[size].width = width;
+  icon_sizes[size].height = height;
+
+  return size;
 }
 
 /**
@@ -956,25 +1287,7 @@ gtk_icon_size_register (const gchar *nam
   g_return_val_if_fail (width > 0, 0);
   g_return_val_if_fail (height > 0, 0);
   
-  init_icon_sizes ();
-
-  if (icon_sizes_used == icon_sizes_allocated)
-    {
-      icon_sizes_allocated *= 2;
-      icon_sizes = g_renew (IconSize, icon_sizes, icon_sizes_allocated);
-    }
-  
-  icon_sizes[icon_sizes_used].size = icon_sizes_used;
-  icon_sizes[icon_sizes_used].name = g_strdup (name);
-  icon_sizes[icon_sizes_used].width = width;
-  icon_sizes[icon_sizes_used].height = height;
-
-  ++icon_sizes_used;
-
-  /* alias to self. */
-  gtk_icon_size_register_alias (name, icon_sizes_used - 1);
-  
-  return icon_sizes_used - 1;
+  return icon_size_register_intern (name, width, height);
 }
 
 /**
@@ -997,17 +1310,29 @@ gtk_icon_size_register_alias (const gcha
 
   init_icon_sizes ();
 
-  if (g_hash_table_lookup (icon_aliases, alias))
-    g_warning ("gtk_icon_size_register_alias: Icon size name '%s' already exists", alias);
-
-  if (!gtk_icon_size_lookup (target, NULL, NULL))
+  if (!icon_size_lookup_intern (NULL, target, NULL, NULL))
     g_warning ("gtk_icon_size_register_alias: Icon size %d does not exist", target);
-  
-  ia = g_new (IconAlias, 1);
-  ia->name = g_strdup (alias);
-  ia->target = target;
 
-  g_hash_table_insert (icon_aliases, ia->name, ia);
+  ia = g_hash_table_lookup (icon_aliases, alias);
+  if (ia)
+    {
+      if (icon_sizes[ia->target].width > 0)
+	{
+	  g_warning ("gtk_icon_size_register_alias: Icon size name '%s' already exists", alias);
+	  return;
+	}
+
+      ia->target = target;
+    }
+
+  if (!ia)
+    {
+      ia = g_new (IconAlias, 1);
+      ia->name = g_strdup (alias);
+      ia->target = target;
+
+      g_hash_table_insert (icon_aliases, ia->name, ia);
+    }
 }
 
 /** 
@@ -1026,7 +1351,7 @@ gtk_icon_size_from_name (const gchar *na
   
   ia = g_hash_table_lookup (icon_aliases, name);
 
-  if (ia)
+  if (ia && icon_sizes[ia->target].width > 0)
     return ia->target;
   else
     return GTK_ICON_SIZE_INVALID;
@@ -1049,6 +1374,8 @@ gtk_icon_size_get_name (GtkIconSize  siz
     return icon_sizes[size].name;
 }
 
+/************************************************************/
+
 /* Icon Set */
 
 
@@ -1253,17 +1580,27 @@ gtk_icon_set_copy (GtkIconSet *icon_set)
   return copy;
 }
 
-
 static gboolean
 sizes_equivalent (GtkIconSize lhs,
                   GtkIconSize rhs)
 {
+  /* We used to consider sizes equivalent if they were
+   * the same pixel size, but we don't have the GtkSettings
+   * here, so we can't do that. Plus, it's not clear that
+   * it is right... it was just a workaround for the fact
+   * that we register icons by logical size, not pixel size.
+   */
+#if 1
+  return lhs == rhs;
+#else  
+  
   gint r_w, r_h, l_w, l_h;
 
-  gtk_icon_size_lookup (rhs, &r_w, &r_h);
-  gtk_icon_size_lookup (lhs, &l_w, &l_h);
+  icon_size_lookup_intern (NULL, rhs, &r_w, &r_h);
+  icon_size_lookup_intern (NULL, lhs, &l_w, &l_h);
 
   return r_w == l_w && r_h == l_h;
+#endif
 }
 
 static GtkIconSource*
Index: gtk/gtkiconfactory.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkiconfactory.h,v
retrieving revision 1.9
diff -u -p -r1.9 gtkiconfactory.h
--- gtk/gtkiconfactory.h	2 Mar 2002 19:11:38 -0000	1.9
+++ gtk/gtkiconfactory.h	19 Sep 2002 22:32:48 -0000
@@ -88,9 +88,14 @@ GtkIconSet* gtk_icon_factory_lookup_defa
  * size from the rendered pixbuf, not from here.
  */
 
-gboolean              gtk_icon_size_lookup         (GtkIconSize  size,
-                                                    gint        *width,
-                                                    gint        *height);
+gboolean gtk_icon_size_lookup              (GtkIconSize  size,
+					    gint        *width,
+					    gint        *height);
+gboolean gtk_icon_size_lookup_for_settings (GtkSettings *settings,
+					    GtkIconSize  size,
+					    gint        *width,
+					    gint        *height);
+
 GtkIconSize           gtk_icon_size_register       (const gchar *name,
                                                     gint         width,
                                                     gint         height);
Index: gtk/gtkrc.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkrc.c,v
retrieving revision 1.128
diff -u -p -r1.128 gtkrc.c
--- gtk/gtkrc.c	1 Aug 2002 23:43:13 -0000	1.128
+++ gtk/gtkrc.c	19 Sep 2002 22:32:48 -0000
@@ -1269,10 +1269,10 @@ gtk_rc_clear_styles (GtkRcContext *conte
  * icon sets so they get re-rendered.
  */
 static void
-gtk_rc_reset_widgets (GtkRcContext *context)
+gtk_rc_reset_widgets (GtkSettings *settings)
 {
   GList *list, *toplevels;
-  
+
   _gtk_icon_set_invalidate_caches ();
   
   toplevels = gtk_window_list_toplevels ();
@@ -1306,6 +1306,53 @@ gtk_rc_clear_realized_style (gpointer ke
   g_slist_free (rc_styles);
 }
 
+/**
+ * _gtk_rc_reset_styles:
+ * @settings: a #GtkSettings
+ * 
+ * This setting resets all of our styles; we use it when the font
+ * rendering parameters or the icon sizes have changed. It's both less
+ * and more comprehensive then we actually need:
+ *
+ * Less comprehensive: it doesn't affect widgets that have a style
+ *   set on them.
+ *
+ * More comprehensive: it resets the styles, but the styles haven't
+ *   changed. The main reason for resetting the styles is becaues
+ *   most widgets will redo all their font stuff when their style
+ *   change.
+ **/
+void
+_gtk_rc_reset_styles (GtkSettings *settings)
+{
+  GtkRcContext *context;
+  gboolean reset = FALSE;
+
+  g_return_if_fail (GTK_IS_SETTINGS (settings));
+
+  context = gtk_rc_context_get (settings);
+  
+  if (context->default_style)
+    {
+      g_object_unref (G_OBJECT (context->default_style));
+      context->default_style = NULL;
+      reset = TRUE;
+    }
+  
+  /* Clear out styles that have been looked up already
+   */
+  if (realized_style_ht)
+    {
+      g_hash_table_foreach (realized_style_ht, gtk_rc_clear_realized_style, NULL);
+      g_hash_table_destroy (realized_style_ht);
+      realized_style_ht = NULL;
+      reset = TRUE;
+    }
+  
+  if (reset)
+    gtk_rc_reset_widgets (settings);
+}
+
 const gchar*
 _gtk_rc_context_get_default_font_name (GtkSettings *settings)
 {
@@ -1322,29 +1369,10 @@ _gtk_rc_context_get_default_font_name (G
 
   if (new_font_name != context->font_name && !(new_font_name && strcmp (context->font_name, new_font_name) == 0))
     {
-      gboolean reset = FALSE;
-      g_free (context->font_name);
-      context->font_name = g_strdup (new_font_name);
-
-      if (context->default_style)
-        {
-	  g_object_unref (G_OBJECT (context->default_style));
-	  context->default_style = NULL;
-	  reset = TRUE;
-        }
-
-      /* Clear out styles that have been looked up already
-       */
-      if (realized_style_ht)
-	{
-	  g_hash_table_foreach (realized_style_ht, gtk_rc_clear_realized_style, NULL);
-	  g_hash_table_destroy (realized_style_ht);
-	  realized_style_ht = NULL;
-	  reset = TRUE;
-	}
-
-      if (reset)
-	gtk_rc_reset_widgets (context);
+       g_free (context->font_name);
+       context->font_name = g_strdup (new_font_name);
+ 
+       _gtk_rc_reset_styles (settings);
     }
           
   g_free (new_font_name);
@@ -1454,7 +1482,7 @@ gtk_rc_reparse_all_for_settings (GtkSett
       
       g_object_thaw_notify (G_OBJECT (context->settings));
 
-      gtk_rc_reset_widgets (context);
+      gtk_rc_reset_widgets (context->settings);
     }
 
   return mtime_modified;
Index: gtk/gtkrc.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkrc.h,v
retrieving revision 1.38
diff -u -p -r1.38 gtkrc.h
--- gtk/gtkrc.h	1 Aug 2002 23:43:13 -0000	1.38
+++ gtk/gtkrc.h	19 Sep 2002 22:32:48 -0000
@@ -232,6 +232,7 @@ const GtkRcProperty* _gtk_rc_style_looku
 						       GQuark      property_name);
 
 const gchar* _gtk_rc_context_get_default_font_name (GtkSettings *settings);
+void         _gtk_rc_reset_styles                  (GtkSettings *settings);
 
 #ifdef __cplusplus
 }
Index: gtk/gtksettings.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtksettings.c,v
retrieving revision 1.30
diff -u -p -r1.30 gtksettings.c
--- gtk/gtksettings.c	1 Aug 2002 23:43:13 -0000	1.30
+++ gtk/gtksettings.c	19 Sep 2002 22:32:48 -0000
@@ -31,7 +31,8 @@ enum {
   PROP_KEY_THEME_NAME,
   PROP_MENU_BAR_ACCEL,
   PROP_DND_DRAG_THRESHOLD,
-  PROP_FONT_NAME
+  PROP_FONT_NAME,
+  PROP_ICON_SIZES
 };
 
 
@@ -213,7 +214,15 @@ gtk_settings_class_init (GtkSettingsClas
 								  G_PARAM_READWRITE),
                                              NULL);
   g_assert (result == PROP_FONT_NAME);
- 
+
+  result = settings_install_property_parser (class,
+                                             g_param_spec_string ("gtk-icon-sizes",
+								   _("Icon Sizes"),
+								   _("List of icon sizes (gtk-menu=16,16;gtk-button=20,20..."),
+								  NULL,
+								  G_PARAM_READWRITE),
+                                             NULL);
+  g_assert (result == PROP_ICON_SIZES);
 }
 
 static void
@@ -366,6 +375,7 @@ gtk_settings_notify (GObject    *object,
   GtkSettings *settings = GTK_SETTINGS (object);
   guint property_id = pspec->param_id;
   gint double_click_time;
+  gchar *icon_sizes;
 
   if (settings->screen == NULL) /* initialization */
     return;
Index: gtk/gtkstyle.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkstyle.c,v
retrieving revision 1.124
diff -u -p -r1.124 gtkstyle.c
--- gtk/gtkstyle.c	11 Sep 2002 10:40:46 -0000	1.124
+++ gtk/gtkstyle.c	19 Sep 2002 22:32:48 -0000
@@ -1989,6 +1989,8 @@ gtk_default_render_icon (GtkStyle       
   GdkPixbuf *scaled;
   GdkPixbuf *stated;
   GdkPixbuf *base_pixbuf;
+  GdkScreen *screen;
+  GtkSettings *settings;
 
   /* Oddly, style can be NULL in this function, because
    * GtkIconSet can be used without a style and if so
@@ -1998,10 +2000,28 @@ gtk_default_render_icon (GtkStyle       
   base_pixbuf = gtk_icon_source_get_pixbuf (source);
 
   g_return_val_if_fail (base_pixbuf != NULL, NULL);
+
+  if (widget && gtk_widget_has_screen (widget))
+    {
+      screen = gtk_widget_get_screen (widget);
+      settings = gtk_settings_get_for_screen (screen);
+    }
+  else if (style->colormap)
+    {
+      screen = gdk_colormap_get_screen (style->colormap);
+      settings = gtk_settings_get_for_screen (screen);
+    }
+  else
+    {
+      settings = gtk_settings_get_default ();
+      GTK_NOTE (MULTIHEAD,
+		g_warning ("Using the default screen for gtk_default_render_icon()"));
+    }
+
   
-  if (size != (GtkIconSize) -1 && !gtk_icon_size_lookup (size, &width, &height))
+  if (size != (GtkIconSize) -1 && !gtk_icon_size_lookup_for_settings (settings, size, &width, &height))
     {
-      g_warning (G_STRLOC ": invalid icon size `%d'", size);
+      g_warning (G_STRLOC ": invalid icon size '%d'", size);
       return NULL;
     }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]