From 1b2e11ee858c80aff09d2bd1e44a0468d767c160 Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Thu, 3 Feb 2011 12:22:33 -0500 Subject: [PATCH] b=621962 rearrange nsIconChannel::Init to make what is happening clearer r=roc --- .../decoders/icon/gtk/nsIconChannel.cpp | 41 ++++++++++++++----- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/modules/libpr0n/decoders/icon/gtk/nsIconChannel.cpp b/modules/libpr0n/decoders/icon/gtk/nsIconChannel.cpp index ac97bec82e0..8ff60adf060 100644 --- a/modules/libpr0n/decoders/icon/gtk/nsIconChannel.cpp +++ b/modules/libpr0n/decoders/icon/gtk/nsIconChannel.cpp @@ -168,6 +168,8 @@ 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(); @@ -464,30 +466,47 @@ nsIconChannel::Init(nsIURI* aURI) 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;