Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/libwnck/ChangeLog,v
retrieving revision 1.134
diff -u -p -r1.134 ChangeLog
--- ChangeLog	4 Aug 2002 20:18:17 -0000	1.134
+++ ChangeLog	6 Aug 2002 05:35:37 -0000
@@ -1,3 +1,22 @@
+2002-08-06  Mark McLoughlin  <mark@skynet.ie>
+
+	* libwnck/application.c:
+	(wnck_application_init): set the icon cache to not
+	use a fallback icon.
+	(set_icons): move code out of get_icons().
+	(icon_window_closed): reload icons when our icon
+	window is closed.
+	(window_icon_changed): handle the icon on the icon
+	window changing.
+	(get_icons): fallback to a window icon if now application
+	icon is found.
+	(wnck_application_get_icon_is_fallback): if we're not
+	using an icon from a window, its not a fallback, otherwise
+	query the window.
+
+	* libwnck/xutils.c:
+	(_wnck_icon_cache_set_want_fallback): ahem.
+
 2002-08-02  Mark McLoughlin  <mark@skynet.ie>
 
 	* libwnck/pager.c:
Index: libwnck/application.c
===================================================================
RCS file: /cvs/gnome/libwnck/libwnck/application.c,v
retrieving revision 1.12
diff -u -p -r1.12 application.c
--- libwnck/application.c	24 Mar 2002 14:27:01 -0000	1.12
+++ libwnck/application.c	6 Aug 2002 05:35:38 -0000
@@ -105,6 +105,7 @@ wnck_application_init (WnckApplication *
   application->priv = g_new0 (WnckApplicationPrivate, 1);
 
   application->priv->icon_cache = _wnck_icon_cache_new ();
+  _wnck_icon_cache_set_want_fallback (application->priv->icon_cache, FALSE);
 }
 
 static void
@@ -268,11 +269,79 @@ wnck_application_get_pid (WnckApplicatio
   return app->priv->pid;
 }
 
+static void 
+set_icons (WnckApplication *app,
+           GdkPixbuf       *icon,
+           GdkPixbuf       *mini_icon)
+{
+  if (icon)
+    g_object_ref (G_OBJECT (icon));
+  if (mini_icon)
+    g_object_ref (G_OBJECT (mini_icon));
+
+  if (app->priv->icon)
+    g_object_unref (G_OBJECT (app->priv->icon));
+
+  if (app->priv->mini_icon)
+    g_object_unref (G_OBJECT (app->priv->mini_icon));
+
+  app->priv->icon = icon;
+  app->priv->mini_icon = mini_icon;
+}
+
+static void
+icon_window_closed (WnckScreen      *screen,
+		    WnckWindow      *window,
+		    WnckApplication *app)
+{
+  g_assert (!app->priv->icon_from_leader);
+  g_assert (app->priv->icon_window != NULL);
+
+  if (app->priv->icon_window != window)
+    return;
+
+  app->priv->need_emit_icon_changed = TRUE;
+  app->priv->icon_window = NULL;
+
+  set_icons (app, NULL, NULL);
+
+  emit_icon_changed (app);
+}
+
+static void
+window_icon_changed (WnckWindow      *window,
+		     WnckApplication *app)
+{
+  GdkPixbuf *icon;
+  GdkPixbuf *mini_icon;
+
+  g_assert (!app->priv->icon_from_leader);
+  g_assert (app->priv->icon_window != NULL);
+
+  icon = wnck_window_get_icon (window);
+  mini_icon = wnck_window_get_mini_icon (window);
+
+  set_icons (app, icon, mini_icon);
+
+  if (!app->priv->icon)
+    {
+      g_signal_handlers_disconnect_by_func (
+		app->priv->screen, G_CALLBACK (icon_window_closed), app);
+      g_signal_handlers_disconnect_by_func (
+		app->priv->icon_window, G_CALLBACK (window_icon_changed), app);
+
+      app->priv->icon_window = NULL;
+    }
+
+  emit_icon_changed (app);
+}
+
 static void
 get_icons (WnckApplication *app)
 {
   GdkPixbuf *icon;
   GdkPixbuf *mini_icon;
+  GList     *l;
 
   icon = NULL;
   mini_icon = NULL;
@@ -285,32 +354,60 @@ get_icons (WnckApplication *app)
                         DEFAULT_MINI_ICON_WIDTH,
                         DEFAULT_MINI_ICON_HEIGHT))
     {
-      app->priv->need_emit_icon_changed = TRUE;
-      app->priv->icon_from_leader = TRUE;
-      
-      if (icon)
-        g_object_ref (G_OBJECT (icon));
-      if (mini_icon)
-        g_object_ref (G_OBJECT (mini_icon));
+      if (!app->priv->icon_from_leader && app->priv->icon_window)
+	{
+	  g_signal_handlers_disconnect_by_func (
+		app->priv->screen, G_CALLBACK (icon_window_closed), app);
+	  g_signal_handlers_disconnect_by_func (
+		app->priv->icon_window, G_CALLBACK (window_icon_changed), app);
 
-      if (app->priv->icon)
-        g_object_unref (G_OBJECT (app->priv->icon));
+	  app->priv->icon_window = NULL;
+	}
 
-      if (app->priv->mini_icon)
-        g_object_unref (G_OBJECT (app->priv->mini_icon));
+      app->priv->need_emit_icon_changed = TRUE;
+      app->priv->icon_from_leader = TRUE;
 
-      app->priv->icon = icon;
-      app->priv->mini_icon = mini_icon;
+      set_icons (app, icon, mini_icon);
     }
 
-  /* FIXME we should really fall back to using the icon
-   * for one of the windows. But then we need to be more
-   * complicated about icon_changed and when the icon
-   * needs updating and all that.
-   */
-  
   g_assert ((app->priv->icon && app->priv->mini_icon) ||
             !(app->priv->icon || app->priv->mini_icon));
+
+  if (!app->priv->icon)
+    {
+      l = app->priv->windows;
+
+      while (l != NULL)
+        {
+	  WnckWindow *window = l->data;
+
+	  if (wnck_window_get_icon_is_fallback (window) && l->next)
+	    continue;
+
+	  icon = wnck_window_get_icon (window);
+	  mini_icon = wnck_window_get_mini_icon (window);
+
+	  g_assert ((icon && mini_icon) || !(icon || mini_icon));
+
+	  if (icon)
+	    {
+	      g_signal_connect (window, "icon-changed",
+				G_CALLBACK (window_icon_changed), app);
+	      g_signal_connect (app->priv->screen, "window-closed",
+				G_CALLBACK (icon_window_closed), app);
+
+	      app->priv->icon_window = window;
+	      app->priv->need_emit_icon_changed = TRUE;
+	      app->priv->icon_from_leader = FALSE;
+
+	      set_icons (app, icon, mini_icon);
+
+	      break;
+	    }
+
+	  l = l->next;
+        }
+    }
 }
 
 GdkPixbuf*
@@ -347,7 +444,10 @@ wnck_application_get_icon_is_fallback (W
 {
   g_return_val_if_fail (WNCK_IS_APPLICATION (app), FALSE);
 
-  return _wnck_icon_cache_get_is_fallback (app->priv->icon_cache);
+  if (app->priv->icon_window)
+    return wnck_window_get_icon_is_fallback (app->priv->icon_window);
+
+  return FALSE;
 }
 
 /* xwindow is a group leader */
Index: libwnck/xutils.c
===================================================================
RCS file: /cvs/gnome/libwnck/libwnck/xutils.c,v
retrieving revision 1.29
diff -u -p -r1.29 xutils.c
--- libwnck/xutils.c	4 Aug 2002 20:18:17 -0000	1.29
+++ libwnck/xutils.c	6 Aug 2002 05:35:48 -0000
@@ -1692,7 +1692,7 @@ void
 _wnck_icon_cache_set_want_fallback (WnckIconCache *icon_cache,
                                     gboolean       setting)
 {
-  icon_cache->want_fallback = TRUE;
+  icon_cache->want_fallback = setting;
 }
 
 gboolean
