--- metacity-2.20.1/src/window.c	2007-11-17 15:11:01.000000000 -0500
+++ metacity-2.20.1.patched/src/window.c	2007-11-28 11:43:28.000000000 -0500
@@ -74,6 +74,9 @@
 static void     meta_window_show          (MetaWindow     *window);
 static void     meta_window_hide          (MetaWindow     *window);
 
+static void     meta_window_set_demands_attention_internal (MetaWindow     *window,
+                                                            MetaWorkspace *workspace);
+
 static void     meta_window_save_rect         (MetaWindow    *window);
 
 static void meta_window_move_resize_internal (MetaWindow         *window,
@@ -2793,7 +2796,7 @@
                   "last_user_time (%u) is more recent; ignoring "
                   " _NET_ACTIVE_WINDOW message.\n",
                   window->display->last_user_time);
-      meta_window_set_demands_attention(window);
+      meta_window_set_demands_attention_internal (window, workspace);
       return;
     }
 
@@ -2813,8 +2816,21 @@
   /* Get window on current or given workspace */
   if (workspace == NULL)
     workspace = window->screen->active_workspace;
-  if (!meta_window_located_on_workspace (window, workspace))
-    meta_window_change_workspace (window, workspace);
+
+  /* For non-transient windows, we just set up a pulsing indicator, 
+     rather than move windows or workspaces.
+     See http://bugzilla.gnome.org/show_bug.cgi?id=482354 */
+  if (window->xtransient_for == None && !meta_window_located_on_workspace (window, workspace))
+    {
+      meta_window_set_demands_attention_internal (window, workspace);
+      return;
+    }
+  else if (window->xtransient_for != None)
+    {
+      /* Move transients to current workspace - preference dialogs should appear over 
+         the source window.  */
+      meta_window_change_workspace (window, workspace);
+    }
   
   if (window->shaded)
     meta_window_unshade (window, timestamp);
@@ -7982,34 +7998,49 @@
 void
 meta_window_set_demands_attention (MetaWindow *window)
 {
+  meta_window_set_demands_attention_internal (window, NULL);
+}
+
+static void
+meta_window_set_demands_attention_internal (MetaWindow    *window, 
+                                            MetaWorkspace *workspace)
+{
   MetaRectangle candidate_rect, other_rect;
   GList *stack = window->screen->stack->sorted;
   MetaWindow *other_window;
-  gboolean obscured = FALSE;
+  gboolean obscured;
   
+  if (!workspace)
+    workspace = window->screen->active_workspace;
+
+  /* We count windows not located on the current workspace as obscured */
+  obscured = !meta_window_located_on_workspace (window, workspace);
+
   /* Does the window have any other window on this workspace
    * overlapping it?
    */
+  if (!obscured) 
+    {
+      meta_window_get_outer_rect (window, &candidate_rect);
 
-  meta_window_get_outer_rect (window, &candidate_rect);
-
-  /* The stack is sorted with the top windows first. */
+      /* The stack is sorted with the top windows first. */
   
-  while (stack != NULL && stack->data != window)
-    {
-      other_window = stack->data;
-      stack = stack->next;
-     
-      if (other_window->on_all_workspaces ||
-          window->on_all_workspaces ||
-          other_window->workspace == window->workspace)
+      while (stack != NULL && stack->data != window)
         {
-          meta_window_get_outer_rect (other_window, &other_rect);
-
-          if (meta_rectangle_overlap (&candidate_rect, &other_rect))
+          other_window = stack->data;
+          stack = stack->next;
+     
+          if (other_window->on_all_workspaces ||
+              window->on_all_workspaces ||
+              other_window->workspace == window->workspace)
             {
-              obscured = TRUE;
-              break;
+              meta_window_get_outer_rect (other_window, &other_rect);
+
+              if (meta_rectangle_overlap (&candidate_rect, &other_rect))
+                {
+                  obscured = TRUE;
+                  break;
+                }
             }
         }
     }
