[gtk+] GtkHeaderBar: try harder to find the best window icon



commit 6e96111d9f5e9298ff0b716f063b084a94a880e6
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Jan 24 15:40:37 2014 -0500

    GtkHeaderBar: try harder to find the best window icon
    
    GtkWindow has 4 (!) APIs for setting window icons, and we
    have to try them all in the right order to find the right
    icon. This commit makes it so, and keeps the icon list
    manipulation inside gtkwindow.c by adding a private API
    for getting a single icon at the right size.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=722515

 gtk/gtkheaderbar.c     |   46 ++++----------------------------
 gtk/gtkwindow.c        |   67 ++++++++++++++++++++++++++++++++++++++++++++++++
 gtk/gtkwindowprivate.h |    3 ++
 3 files changed, 76 insertions(+), 40 deletions(-)
---
diff --git a/gtk/gtkheaderbar.c b/gtk/gtkheaderbar.c
index 3b9923e..36c7e70 100644
--- a/gtk/gtkheaderbar.c
+++ b/gtk/gtkheaderbar.c
@@ -218,54 +218,20 @@ _gtk_header_bar_update_window_icon (GtkHeaderBar *bar,
                                     GtkWindow    *window)
 {
   GtkHeaderBarPrivate *priv = gtk_header_bar_get_instance_private (bar);
-  gint size;
-  GList *list;
-  const gchar *name;
-  GdkPixbuf *best = NULL;
+  GdkPixbuf *pixbuf;
 
   if (priv->titlebar_icon == NULL)
     return FALSE;
 
   if (GTK_IS_BUTTON (gtk_widget_get_parent (priv->titlebar_icon)))
-    size = 16;
+    pixbuf = gtk_window_get_icon_for_size (window, 16);
   else
-    size = 20;
+    pixbuf = gtk_window_get_icon_for_size (window, 20);
 
-  list = gtk_window_get_icon_list (window);
-
-  if (list != NULL)
-    {
-      GdkPixbuf *pixbuf;
-      GList *l;
-
-      best = NULL;
-      for (l = list; l; l = l->next)
-        {
-          pixbuf = list->data;
-          if (gdk_pixbuf_get_width (pixbuf) <= size)
-            {
-              best = g_object_ref (pixbuf);
-              break;
-            }
-        }
-
-      if (best == NULL)
-        best = gdk_pixbuf_scale_simple (GDK_PIXBUF (list->data), size, size, GDK_INTERP_BILINEAR);
-
-      g_list_free (list);
-    }
-  else
-    {
-      name = gtk_window_get_icon_name (window);
-      if (name != NULL)
-        best = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
-                                         name, size, GTK_ICON_LOOKUP_FORCE_SIZE, NULL);
-    }
-
-  if (best)
+  if (pixbuf)
     {
-      gtk_image_set_from_pixbuf (GTK_IMAGE (priv->titlebar_icon), best);
-      g_object_unref (best);
+      gtk_image_set_from_pixbuf (GTK_IMAGE (priv->titlebar_icon), pixbuf);
+      g_object_unref (pixbuf);
       gtk_widget_show (priv->titlebar_icon);
 
       return TRUE;
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index f42f9f7..5e2cc05 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -4019,6 +4019,73 @@ gtk_window_realize_icon (GtkWindow *window)
     }
 }
 
+static GdkPixbuf *
+icon_from_list (GList *list,
+                gint   size)
+{
+  GdkPixbuf *best;
+  GdkPixbuf *pixbuf;
+  GList *l;
+
+  best = NULL;
+  for (l = list; l; l = l->next)
+    {
+      pixbuf = list->data;
+      if (gdk_pixbuf_get_width (pixbuf) <= size)
+        {
+          best = g_object_ref (pixbuf);
+          break;
+        }
+    }
+
+  if (best == NULL)
+    best = gdk_pixbuf_scale_simple (GDK_PIXBUF (list->data), size, size, GDK_INTERP_BILINEAR);
+
+  return best;
+}
+
+static GdkPixbuf *
+icon_from_name (const gchar *name,
+                gint         size)
+{
+  return gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
+                                   name, size,
+                                   GTK_ICON_LOOKUP_FORCE_SIZE, NULL);
+}
+
+GdkPixbuf *
+gtk_window_get_icon_for_size (GtkWindow *window,
+                              gint       size)
+{
+  GtkWindowPrivate *priv = window->priv;
+  GtkWindowIconInfo *info;
+  const gchar *name;
+
+  info = ensure_icon_info (window);
+
+  if (info->icon_list != NULL)
+    return icon_from_list (info->icon_list, size);
+
+  name = gtk_window_get_icon_name (window);
+  if (name != NULL)
+    return icon_from_name (name, size);
+
+  if (priv->transient_parent != NULL)
+    {
+      info = ensure_icon_info (priv->transient_parent);
+      if (info->icon_list)
+        return icon_from_list (info->icon_list, size);
+    }
+
+  if (default_icon_list != NULL)
+    return icon_from_list (default_icon_list, size);
+
+  if (default_icon_name != NULL)
+    return icon_from_name (default_icon_name, size);
+
+  return NULL;
+}
+
 static void
 gtk_window_unrealize_icon (GtkWindow *window)
 {
diff --git a/gtk/gtkwindowprivate.h b/gtk/gtkwindowprivate.h
index 9f9bce6..704026d 100644
--- a/gtk/gtkwindowprivate.h
+++ b/gtk/gtkwindowprivate.h
@@ -107,6 +107,9 @@ void    _gtk_window_get_popover_position (GtkWindow                   *window,
                                           GtkPositionType             *pos,
                                           cairo_rectangle_int_t       *rect);
 
+GdkPixbuf *gtk_window_get_icon_for_size (GtkWindow *window,
+                                         gint       size);
+
 G_END_DECLS
 
 #endif /* __GTK_WINDOW_PRIVATE_H__ */


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