1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
--- 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;
+ }
}
}
}
|