b=621962 rearrange nsIconChannel::Init to make what is happening clearer r=roc
authorKarl Tomlinson <karlt+@karlt.net>
Thu, 03 Feb 2011 12:22:33 -0500
changeset 61853 57536671a3637d216f06e1f28b0ddf8b8c5250d3
parent 61852 9a9f6f3eec6ba9acb0249e3d8e4310770c40d59d
child 61854 29df2b0fa77bb689e9984499c5f604b8507da8b3
push id18521
push usereakhgari@mozilla.com
push dateThu, 03 Feb 2011 17:24:54 +0000
treeherderautoland@562ae97b2636 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs621962
milestone2.0b12pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
b=621962 rearrange nsIconChannel::Init to make what is happening clearer r=roc
modules/libpr0n/decoders/icon/gtk/nsIconChannel.cpp
--- a/modules/libpr0n/decoders/icon/gtk/nsIconChannel.cpp
+++ b/modules/libpr0n/decoders/icon/gtk/nsIconChannel.cpp
@@ -163,16 +163,18 @@ static GtkWidget *gStockImageWidget = ns
 static GnomeIconTheme *gIconTheme = nsnull;
 #endif
 
 static GtkIconFactory *gIconFactory = nsnull;
 
 static void
 ensure_stock_image_widget()
 {
+  // Only the style of the GtkImage needs to be used, but the widget is kept
+  // to track dynamic style changes.
   if (!gProtoWindow) {
     gProtoWindow = gtk_window_new(GTK_WINDOW_POPUP);
     GtkWidget* protoLayout = gtk_fixed_new();
     gtk_container_add(GTK_CONTAINER(gProtoWindow), protoLayout);
 
     gStockImageWidget = gtk_image_new();
     gtk_container_add(GTK_CONTAINER(protoLayout), gStockImageWidget);
 
@@ -459,40 +461,57 @@ nsIconChannel::Init(nsIURI* aURI)
 
   nsCAutoString iconSizeString;
   iconURI->GetIconSize(iconSizeString);
 
   nsCAutoString iconStateString;
   iconURI->GetIconState(iconStateString);
 
   GtkIconSize icon_size = moz_gtk_icon_size(iconSizeString.get());
-   
+  GtkStateType state = iconStateString.EqualsLiteral("disabled") ?
+    GTK_STATE_INSENSITIVE : GTK_STATE_NORMAL;
+
+  // First lookup the icon by stock id.
   ensure_stock_image_widget();
+  GtkStyle *style = gtk_widget_get_style(gStockImageWidget);
+  GtkIconSet *icon_set =
+    gtk_style_lookup_icon_set(style, stockIcon.get());
 
-  gboolean sensitive = strcmp(iconStateString.get(), "disabled");
-  gtk_widget_set_sensitive (gStockImageWidget, sensitive);
+  if (icon_set) {
+    gtk_icon_set_ref(icon_set);
+  } else {
+    // stockIcon is not a stock id, so assume it is an icon name.
+    //
+    // Creating a GtkIconSet is a convenient way to allow the style to
+    // render the icon, possibly with variations suitable for insensitive
+    // states.
+    //
+    // The GtkIconSet is also used to add a new stock id in such a way that
+    // the look up above will succeed next time.  Maybe this is to take
+    // advantage of the cache of stock icon GdkPixbufs.
 
-  GdkPixbuf *icon = gtk_widget_render_icon(gStockImageWidget, stockIcon.get(),
-                                           icon_size, NULL);
-  if (!icon) {
     ensure_icon_factory();
       
-    GtkIconSet *icon_set = gtk_icon_set_new();
+    icon_set = gtk_icon_set_new();
     GtkIconSource *icon_source = gtk_icon_source_new();
     
     gtk_icon_source_set_icon_name(icon_source, stockIcon.get());
     gtk_icon_set_add_source(icon_set, icon_source);
     gtk_icon_factory_add(gIconFactory, stockIcon.get(), icon_set);
-    gtk_icon_set_unref(icon_set);
     gtk_icon_source_free(icon_source);
-
-    icon = gtk_widget_render_icon(gStockImageWidget, stockIcon.get(),
-                                  icon_size, NULL);
   }
 
+  GdkPixbuf *icon =
+    gtk_icon_set_render_icon (icon_set, style,
+                              gtk_widget_get_default_direction(), state,
+                              icon_size, gStockImageWidget, NULL);
+  gtk_icon_set_unref(icon_set);
+
+  // gtk_icon_set_render_icon() never returns NULL, except when we have
+  // https://bugzilla.gnome.org/show_bug.cgi?id=629878#c13
   if (!icon)
     return NS_ERROR_NOT_AVAILABLE;
   
   nsresult rv = moz_gdk_pixbuf_to_channel(icon, iconURI,
                                           getter_AddRefs(mRealChannel));
 
   g_object_unref(icon);