--- metacity-2.20.1/src/core/window.c 2007-11-17 15:11:01.000000000 -0500 +++ metacity-2.20.1.patched/src/core/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; + } } } }