diff -pru libwnck-old/libwnck/selector.c libwnck/libwnck/selector.c
--- libwnck-old/libwnck/selector.c	2005-02-22 09:41:48.000000000 -0700
+++ libwnck/libwnck/selector.c	2005-05-30 16:31:23.911783469 -0600
@@ -219,7 +219,7 @@ wnck_selector_get_window_name (WnckWindo
   else
     name = g_strdup (const_name);
 
-  if (wnck_window_or_transient_demands_attention (window))
+  if (wnck_window_or_transient_needs_attention (window))
     {
       return_value = g_strdup_printf ("<b>%s</b>", name);
       g_free (name);
@@ -307,7 +307,8 @@ wnck_selector_window_state_changed (Wnck
       (changed_mask &
        (WNCK_WINDOW_STATE_MINIMIZED | WNCK_WINDOW_STATE_SHADED |
         WNCK_WINDOW_STATE_SKIP_TASKLIST |
-        WNCK_WINDOW_STATE_DEMANDS_ATTENTION)))
+        WNCK_WINDOW_STATE_DEMANDS_ATTENTION |
+        WNCK_WINDOW_STATE_URGENT)))
     return;
 
   item = NULL;
@@ -332,7 +333,7 @@ wnck_selector_window_state_changed (Wnck
 
   if (changed_mask &
       (WNCK_WINDOW_STATE_MINIMIZED | WNCK_WINDOW_STATE_SHADED |
-       WNCK_WINDOW_STATE_DEMANDS_ATTENTION))
+       WNCK_WINDOW_STATE_DEMANDS_ATTENTION | WNCK_WINDOW_STATE_URGENT))
     {
       window_name = wnck_selector_get_window_name (window);
       gtk_label_set_text (GTK_LABEL (item->label), window_name);
diff -pru libwnck-old/libwnck/tasklist.c libwnck/libwnck/tasklist.c
--- libwnck-old/libwnck/tasklist.c	2005-05-30 16:22:48.282061000 -0600
+++ libwnck/libwnck/tasklist.c	2005-05-30 16:34:45.844557352 -0600
@@ -201,7 +201,7 @@ static WnckTask *wnck_task_new_from_clas
 static WnckTask *wnck_task_new_from_startup_sequence (WnckTasklist      *tasklist,
                                                       SnStartupSequence *sequence);
 #endif
-static gboolean wnck_task_get_demands_attention (WnckTask *task);
+static gboolean wnck_task_get_needs_attention (WnckTask *task);
 
 
 static char      *wnck_task_get_text (WnckTask *task);
@@ -2242,7 +2242,7 @@ wnck_task_popup_menu (WnckTask *task,
       
       text = wnck_task_get_text (win_task);
       menu_item = gtk_image_menu_item_new_with_label (text);
-      if (wnck_task_get_demands_attention (win_task)) 
+      if (wnck_task_get_needs_attention (win_task)) 
         make_gtk_label_bold (GTK_LABEL (GTK_BIN (menu_item)->child));
       g_free (text);
       
@@ -2546,13 +2546,13 @@ wnck_task_get_icon (WnckTask *task)
 }
 
 static gboolean
-wnck_task_get_demands_attention (WnckTask *task)
+wnck_task_get_needs_attention (WnckTask *task)
 {
   GList *l;
   WnckTask *win_task;
-  gboolean demands_attention;
+  gboolean needs_attention;
 
-  demands_attention = FALSE;
+  needs_attention = FALSE;
 
   switch (task->type)
     {
@@ -2562,9 +2562,9 @@ wnck_task_get_demands_attention (WnckTas
 	{
 	  win_task = WNCK_TASK (l->data);
 
-	  if (wnck_window_or_transient_demands_attention (win_task->window))
+	  if (wnck_window_or_transient_needs_attention (win_task->window))
 	    {
-	      demands_attention = TRUE;
+	      needs_attention = TRUE;
 	      break;
 	    }
 
@@ -2573,15 +2573,15 @@ wnck_task_get_demands_attention (WnckTas
       break;
 
     case WNCK_TASK_WINDOW:
-      demands_attention =
-	wnck_window_or_transient_demands_attention (task->window);
+      needs_attention =
+	wnck_window_or_transient_needs_attention (task->window);
       break;
 
     case WNCK_TASK_STARTUP_SEQUENCE:
       break;
     }
 
-  return demands_attention != FALSE;
+  return needs_attention != FALSE;
 }
 
 static void
@@ -2600,7 +2600,7 @@ wnck_task_update_visible_state (WnckTask
   if (text != NULL)
     {
       gtk_label_set_text (GTK_LABEL (task->label), text);
-      if (wnck_task_get_demands_attention (task))
+      if (wnck_task_get_needs_attention (task))
         {
           make_gtk_label_bold ((GTK_LABEL (task->label)));
           wnck_task_queue_glow (task);
@@ -2632,8 +2632,9 @@ wnck_task_state_changed (WnckWindow     
       return;
     }
   
-  if ((changed_mask & WNCK_WINDOW_STATE_MINIMIZED) ||
-      (changed_mask & WNCK_WINDOW_STATE_DEMANDS_ATTENTION))
+  if ((changed_mask & WNCK_WINDOW_STATE_MINIMIZED)         ||
+      (changed_mask & WNCK_WINDOW_STATE_DEMANDS_ATTENTION) ||
+      (changed_mask & WNCK_WINDOW_STATE_URGENT))
     {
       WnckTask *win_task;
 
@@ -2856,7 +2857,7 @@ wnck_task_create_widgets (WnckTask *task
                           PANGO_ELLIPSIZE_END);
   gtk_label_set_max_width_chars (GTK_LABEL (task->label), MAX_WIDTH_CHARS);
 
-  if (wnck_task_get_demands_attention (task))
+  if (wnck_task_get_needs_attention (task))
     {
       make_gtk_label_bold ((GTK_LABEL (task->label)));
       wnck_task_queue_glow (task);
diff -pru libwnck-old/libwnck/window.c libwnck/libwnck/window.c
--- libwnck-old/libwnck/window.c	2005-05-30 16:22:48.285061000 -0600
+++ libwnck/libwnck/window.c	2005-05-30 16:30:19.832095240 -0600
@@ -47,7 +47,8 @@ static GHashTable *window_hash = NULL;
     ((window)->priv->is_sticky           << 6) |        \
     ((window)->priv->is_hidden           << 7) |        \
     ((window)->priv->is_fullscreen       << 8) |        \
-    ((window)->priv->demands_attention   << 9) )
+    ((window)->priv->demands_attention   << 9) |        \
+    ((window)->priv->is_urgent           << 10) )
 
 struct _WnckWindowPrivate
 {
@@ -100,6 +101,7 @@ struct _WnckWindowPrivate
   guint is_hidden : 1;
   guint is_fullscreen : 1;
   guint demands_attention : 1;
+  guint is_urgent : 1;
 
   /* _NET_WM_STATE_HIDDEN doesn't map directly into an
    * externally-visible state (it determines the WM_STATE
@@ -125,6 +127,7 @@ struct _WnckWindowPrivate
   guint need_update_transient_for : 1;
   guint need_update_startup_id : 1;
   guint need_update_wmclass : 1;
+  guint need_update_wmhints : 1;
 };
 
 enum {
@@ -376,8 +379,10 @@ _wnck_window_create (Window      xwindow
   _wnck_select_input (window->priv->xwindow,
                       WNCK_APP_WINDOW_EVENT_MASK);
 
-  window->priv->group_leader =
-    _wnck_get_group_leader (window->priv->xwindow);
+  /* Default the group leader to the window itself; it is set in
+   * update_wmhints() if a different group leader is specified.
+   */
+  window->priv->group_leader = window->priv->xwindow;
 
   window->priv->session_id =
     _wnck_get_session_id (window->priv->xwindow);
@@ -404,6 +409,7 @@ _wnck_window_create (Window      xwindow
   window->priv->need_update_transient_for = TRUE;
   window->priv->need_update_startup_id = TRUE;
   window->priv->need_update_wmclass = TRUE;
+  window->priv->need_update_wmhints = TRUE;
   force_update_now (window);
 
   return window;
@@ -610,26 +616,26 @@ wnck_window_is_minimized (WnckWindow *wi
 }
 
 /**
- * wnck_window_demands_attention:
+ * wnck_window_needs_attention:
  * @window: a #WnckWindow
  *
- * If the window has the demands attention state set returns
- * %TRUE. This state may change anytime a state_changed signal gets
- * emitted.
+ * If the window needs attention returns %TRUE. This state may change
+ * anytime a state_changed signal gets emitted, as it can depend on flags
+ * such as the demands_attention and is_urgent hints.
  *
- * Return value: %TRUE if window has the demands_attention hint set
+ * Return value: %TRUE if window needs attention
  **/
 gboolean
-wnck_window_demands_attention (WnckWindow *window)
+wnck_window_needs_attention (WnckWindow *window)
 {
   g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
 
-  return window->priv->demands_attention;
+  return window->priv->demands_attention || window->priv->is_urgent;
 }
 
-/* Return whether one of the transients of @window demands attention */
+/* Return whether one of the transients of @window needs attention */
 static gboolean
-transient_demands_attention (WnckWindow *window)
+transient_needs_attention (WnckWindow *window)
 {
   GList *windows;
   WnckWindow *transient;
@@ -646,7 +652,7 @@ transient_demands_attention (WnckWindow 
       if (transient == window)
         return FALSE;
 
-      if (wnck_window_demands_attention (transient))
+      if (wnck_window_needs_attention (transient))
         return TRUE;
     }
 
@@ -654,21 +660,19 @@ transient_demands_attention (WnckWindow 
 }
 
 /**
- * wnck_window_or_transient_demands_attention:
+ * wnck_window_or_transient_needs_attention:
  * @window: a #WnckWindow
  *
- * If the window or one of its transients has the demands attention
- * state set returns %TRUE. This state may change anytime a
- * state_changed signal gets emitted.
+ * If the window or one of its transients needs attention returns %TRUE.
+ * This state may change anytime a state_changed signal gets emitted.
  *
- * Return value: %TRUE if window or one of its transients has the
- *               demands_attention hint set
+ * Return value: %TRUE if window or one of its transients needs attention
  **/
 gboolean
-wnck_window_or_transient_demands_attention (WnckWindow *window)
+wnck_window_or_transient_needs_attention (WnckWindow *window)
 {
-  return wnck_window_demands_attention (window) || 
-         transient_demands_attention (window);
+  return wnck_window_needs_attention (window) || 
+         transient_needs_attention (window);
 }
 
 gboolean
@@ -1616,14 +1620,18 @@ _wnck_window_process_property_notify (Wn
   else if (xevent->xproperty.atom ==
            _wnck_atom_get ("_NET_WM_ICON") ||
            xevent->xproperty.atom ==
-           _wnck_atom_get ("KWM_WIN_ICON") ||
-           xevent->xproperty.atom ==
-           _wnck_atom_get ("WM_HINTS"))
+           _wnck_atom_get ("KWM_WIN_ICON"))
     {
       _wnck_icon_cache_property_changed (window->priv->icon_cache,
                                          xevent->xproperty.atom);
       queue_update (window);
     }
+  else if (xevent->xproperty.atom ==
+  	   _wnck_atom_get ("WM_HINTS"))
+    {
+      window->priv->need_update_wmhints = TRUE;
+      queue_update (window);
+    }
 }
 
 void
@@ -1756,6 +1764,9 @@ update_state (WnckWindow *window)
       break;
     }
 
+  /* FIXME!!!!!!!!!! What in the world is this buggy duplicate of the code
+   * immediately above this for??!?!?
+   */
   switch (window->priv->wintype)
     {
     case WNCK_WINDOW_DESKTOP:
@@ -2089,6 +2100,39 @@ update_wmclass (WnckWindow *window)
 }
 
 static void
+update_wmhints (WnckWindow *window)
+{
+  XWMHints *hints;
+
+  if (!window->priv->need_update_wmhints)
+    return;
+
+  _wnck_error_trap_push ();
+  hints = XGetWMHints (gdk_display, window->priv->xwindow);
+  _wnck_error_trap_pop ();
+
+  if (hints)
+    {
+      if ((hints->flags & IconPixmapHint) ||
+          (hints->flags & IconMaskHint))
+        _wnck_icon_cache_property_changed (window->priv->icon_cache,
+                                           _wnck_atom_get ("WM_HINTS"));
+
+      if (hints->flags & WindowGroupHint)
+          window->priv->group_leader = hints->window_group;
+
+      if (hints->flags & XUrgencyHint)
+        window->priv->is_urgent = TRUE;
+      else
+        window->priv->is_urgent = FALSE;
+
+      XFree (hints);
+    }
+
+  window->priv->need_update_wmhints = FALSE;
+}
+
+static void
 force_update_now (WnckWindow *window)
 {
   WnckWindowState old_state;
@@ -2143,6 +2187,7 @@ force_update_now (WnckWindow *window)
 
   update_startup_id (window);    /* no side effects */
   update_wmclass (window);
+  update_wmhints (window);
   update_transient_for (window); /* wintype needs this to be first */
   update_wintype (window);
   update_wm_state (window);
diff -pru libwnck-old/libwnck/window.h libwnck/libwnck/window.h
--- libwnck-old/libwnck/window.h	2005-05-30 16:22:48.286061000 -0600
+++ libwnck/libwnck/window.h	2005-05-30 16:29:42.198341908 -0600
@@ -43,7 +43,8 @@ typedef enum
   WNCK_WINDOW_STATE_STICKY                 = 1 << 6,
   WNCK_WINDOW_STATE_HIDDEN                 = 1 << 7,
   WNCK_WINDOW_STATE_FULLSCREEN             = 1 << 8,
-  WNCK_WINDOW_STATE_DEMANDS_ATTENTION      = 1 << 9
+  WNCK_WINDOW_STATE_DEMANDS_ATTENTION      = 1 << 9,
+  WNCK_WINDOW_STATE_URGENT                 = 1 << 10,
 } WnckWindowState;
 
 typedef enum
@@ -157,8 +158,8 @@ gboolean wnck_window_is_skip_pager      
 gboolean wnck_window_is_skip_tasklist          (WnckWindow *window);
 gboolean wnck_window_is_fullscreen             (WnckWindow *window);
 gboolean wnck_window_is_sticky                 (WnckWindow *window);
-gboolean wnck_window_demands_attention         (WnckWindow *window);
-gboolean wnck_window_or_transient_demands_attention (WnckWindow *window);
+gboolean wnck_window_needs_attention           (WnckWindow *window);
+gboolean wnck_window_or_transient_needs_attention (WnckWindow *window);
 
 void wnck_window_set_skip_pager    (WnckWindow *window,
                                     gboolean skip);
diff -pru libwnck-old/libwnck/xutils.h libwnck/libwnck/xutils.h
--- libwnck-old/libwnck/xutils.h	2005-05-30 16:22:48.287061000 -0600
+++ libwnck/libwnck/xutils.h	2005-05-30 16:24:07.895885331 -0600
@@ -109,7 +109,6 @@ void _wnck_change_viewport (Screen *scre
 			    int     x,
 			    int     y);
 
-Window _wnck_get_group_leader   (Window xwindow);
 char*  _wnck_get_session_id     (Window xwindow);
 int    _wnck_get_pid            (Window xwindow);
 char*  _wnck_get_name           (Window xwindow);
