1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1 |
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
2 |
||
3 |
/* Metacity window groups */
|
|
4 |
||
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
5 |
/*
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
6 |
* Copyright (C) 2002 Red Hat Inc.
|
7 |
* Copyright (C) 2003 Rob Adams
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
8 |
*
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
9 |
* This program is free software; you can redistribute it and/or
|
10 |
* modify it under the terms of the GNU General Public License as
|
|
11 |
* published by the Free Software Foundation; either version 2 of the
|
|
12 |
* License, or (at your option) any later version.
|
|
13 |
*
|
|
14 |
* This program is distributed in the hope that it will be useful, but
|
|
15 |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
16 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
17 |
* General Public License for more details.
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
18 |
*
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
19 |
* You should have received a copy of the GNU General Public License
|
1.2.68
by Dmitry Shachnev
Import upstream version 3.12.0 |
20 |
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
21 |
*/
|
22 |
||
23 |
#include <config.h> |
|
24 |
#include "util.h" |
|
25 |
#include "group-private.h" |
|
26 |
#include "group-props.h" |
|
27 |
#include "window.h" |
|
28 |
||
29 |
static MetaGroup* |
|
30 |
meta_group_new (MetaDisplay *display, |
|
31 |
Window group_leader) |
|
32 |
{
|
|
33 |
MetaGroup *group; |
|
34 |
#define N_INITIAL_PROPS 3
|
|
35 |
Atom initial_props[N_INITIAL_PROPS]; |
|
36 |
int i; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
37 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
38 |
g_assert (N_INITIAL_PROPS == (int) G_N_ELEMENTS (initial_props)); |
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
39 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
40 |
group = g_new0 (MetaGroup, 1); |
41 |
||
42 |
group->display = display; |
|
43 |
group->windows = NULL; |
|
44 |
group->group_leader = group_leader; |
|
45 |
group->refcount = 1; /* owned by caller, hash table has only weak ref */ |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
46 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
47 |
if (display->groups_by_leader == NULL) |
48 |
display->groups_by_leader = g_hash_table_new (meta_unsigned_long_hash, |
|
49 |
meta_unsigned_long_equal); |
|
50 |
||
51 |
g_assert (g_hash_table_lookup (display->groups_by_leader, &group_leader) == NULL); |
|
52 |
||
53 |
g_hash_table_insert (display->groups_by_leader, |
|
54 |
&group->group_leader, |
|
55 |
group); |
|
56 |
||
57 |
/* Fill these in the order we want them to be gotten */
|
|
58 |
i = 0; |
|
1.2.41
by Pedro Fragoso
Import upstream version 2.23.21 |
59 |
initial_props[i++] = display->atom_WM_CLIENT_MACHINE; |
60 |
initial_props[i++] = display->atom__NET_WM_PID; |
|
61 |
initial_props[i++] = display->atom__NET_STARTUP_ID; |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
62 |
g_assert (N_INITIAL_PROPS == i); |
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
63 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
64 |
meta_group_reload_properties (group, initial_props, N_INITIAL_PROPS); |
65 |
||
66 |
meta_topic (META_DEBUG_GROUPS, |
|
67 |
"Created new group with leader 0x%lx\n", |
|
68 |
group->group_leader); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
69 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
70 |
return group; |
71 |
}
|
|
72 |
||
73 |
static void |
|
74 |
meta_group_unref (MetaGroup *group) |
|
75 |
{
|
|
76 |
g_return_if_fail (group->refcount > 0); |
|
77 |
||
78 |
group->refcount -= 1; |
|
79 |
if (group->refcount == 0) |
|
80 |
{
|
|
81 |
meta_topic (META_DEBUG_GROUPS, |
|
82 |
"Destroying group with leader 0x%lx\n", |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
83 |
group->group_leader); |
84 |
||
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
85 |
g_assert (group->display->groups_by_leader != NULL); |
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
86 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
87 |
g_hash_table_remove (group->display->groups_by_leader, |
88 |
&group->group_leader); |
|
89 |
||
90 |
/* mop up hash table, this is how it gets freed on display close */
|
|
91 |
if (g_hash_table_size (group->display->groups_by_leader) == 0) |
|
92 |
{
|
|
93 |
g_hash_table_destroy (group->display->groups_by_leader); |
|
94 |
group->display->groups_by_leader = NULL; |
|
95 |
}
|
|
96 |
||
97 |
g_free (group->wm_client_machine); |
|
98 |
g_free (group->startup_id); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
99 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
100 |
g_free (group); |
101 |
}
|
|
102 |
}
|
|
103 |
||
104 |
MetaGroup* |
|
105 |
meta_window_get_group (MetaWindow *window) |
|
106 |
{
|
|
107 |
if (window->unmanaging) |
|
108 |
return NULL; |
|
109 |
||
110 |
return window->group; |
|
111 |
}
|
|
112 |
||
113 |
void
|
|
114 |
meta_window_compute_group (MetaWindow* window) |
|
115 |
{
|
|
116 |
MetaGroup *group; |
|
117 |
MetaWindow *ancestor; |
|
118 |
||
119 |
/* use window->xwindow if no window->xgroup_leader */
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
120 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
121 |
group = NULL; |
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
122 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
123 |
/* Determine the ancestor of the window; its group setting will override the
|
124 |
* normal grouping rules; see bug 328211.
|
|
125 |
*/
|
|
126 |
ancestor = meta_window_find_root_ancestor (window); |
|
127 |
||
128 |
if (window->display->groups_by_leader) |
|
129 |
{
|
|
130 |
if (ancestor != window) |
|
131 |
group = ancestor->group; |
|
132 |
else if (window->xgroup_leader != None) |
|
133 |
group = g_hash_table_lookup (window->display->groups_by_leader, |
|
134 |
&window->xgroup_leader); |
|
135 |
else
|
|
136 |
group = g_hash_table_lookup (window->display->groups_by_leader, |
|
137 |
&window->xwindow); |
|
138 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
139 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
140 |
if (group != NULL) |
141 |
{
|
|
142 |
window->group = group; |
|
143 |
group->refcount += 1; |
|
144 |
}
|
|
145 |
else
|
|
146 |
{
|
|
147 |
if (ancestor != window && ancestor->xgroup_leader != None) |
|
148 |
group = meta_group_new (window->display, |
|
149 |
ancestor->xgroup_leader); |
|
150 |
else if (window->xgroup_leader != None) |
|
151 |
group = meta_group_new (window->display, |
|
152 |
window->xgroup_leader); |
|
153 |
else
|
|
154 |
group = meta_group_new (window->display, |
|
155 |
window->xwindow); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
156 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
157 |
window->group = group; |
158 |
}
|
|
159 |
||
160 |
window->group->windows = g_slist_prepend (window->group->windows, window); |
|
161 |
||
162 |
meta_topic (META_DEBUG_GROUPS, |
|
163 |
"Adding %s to group with leader 0x%lx\n", |
|
164 |
window->desc, group->group_leader); |
|
165 |
||
166 |
}
|
|
167 |
||
168 |
static void |
|
169 |
remove_window_from_group (MetaWindow *window) |
|
170 |
{
|
|
171 |
if (window->group != NULL) |
|
172 |
{
|
|
173 |
meta_topic (META_DEBUG_GROUPS, |
|
174 |
"Removing %s from group with leader 0x%lx\n", |
|
175 |
window->desc, window->group->group_leader); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
176 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
177 |
window->group->windows = |
178 |
g_slist_remove (window->group->windows, |
|
179 |
window); |
|
180 |
meta_group_unref (window->group); |
|
181 |
window->group = NULL; |
|
182 |
}
|
|
183 |
}
|
|
184 |
||
185 |
void
|
|
186 |
meta_window_group_leader_changed (MetaWindow *window) |
|
187 |
{
|
|
188 |
remove_window_from_group (window); |
|
189 |
meta_window_compute_group (window); |
|
190 |
}
|
|
191 |
||
192 |
void
|
|
193 |
meta_window_shutdown_group (MetaWindow *window) |
|
194 |
{
|
|
195 |
remove_window_from_group (window); |
|
196 |
}
|
|
197 |
||
198 |
MetaGroup* |
|
199 |
meta_display_lookup_group (MetaDisplay *display, |
|
200 |
Window group_leader) |
|
201 |
{
|
|
202 |
MetaGroup *group; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
203 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
204 |
group = NULL; |
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
205 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
206 |
if (display->groups_by_leader) |
207 |
group = g_hash_table_lookup (display->groups_by_leader, |
|
208 |
&group_leader); |
|
209 |
||
210 |
return group; |
|
211 |
}
|
|
212 |
||
213 |
GSList* |
|
214 |
meta_group_list_windows (MetaGroup *group) |
|
215 |
{
|
|
216 |
return g_slist_copy (group->windows); |
|
217 |
}
|
|
218 |
||
219 |
void
|
|
220 |
meta_group_update_layers (MetaGroup *group) |
|
221 |
{
|
|
222 |
GSList *tmp; |
|
223 |
GSList *frozen_stacks; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
224 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
225 |
if (group->windows == NULL) |
226 |
return; |
|
227 |
||
228 |
frozen_stacks = NULL; |
|
229 |
tmp = group->windows; |
|
230 |
while (tmp != NULL) |
|
231 |
{
|
|
232 |
MetaWindow *window = tmp->data; |
|
233 |
||
234 |
/* we end up freezing the same stack a lot of times,
|
|
235 |
* but doesn't hurt anything. have to handle
|
|
236 |
* groups that span 2 screens.
|
|
237 |
*/
|
|
238 |
meta_stack_freeze (window->screen->stack); |
|
239 |
frozen_stacks = g_slist_prepend (frozen_stacks, window->screen->stack); |
|
240 |
||
241 |
meta_stack_update_layer (window->screen->stack, |
|
242 |
window); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
243 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
244 |
tmp = tmp->next; |
245 |
}
|
|
246 |
||
247 |
tmp = frozen_stacks; |
|
248 |
while (tmp != NULL) |
|
249 |
{
|
|
250 |
meta_stack_thaw (tmp->data); |
|
251 |
tmp = tmp->next; |
|
252 |
}
|
|
253 |
||
254 |
g_slist_free (frozen_stacks); |
|
255 |
}
|
|
256 |
||
257 |
const char* |
|
258 |
meta_group_get_startup_id (MetaGroup *group) |
|
259 |
{
|
|
260 |
return group->startup_id; |
|
261 |
}
|
|
262 |
||
263 |
gboolean
|
|
264 |
meta_group_property_notify (MetaGroup *group, |
|
265 |
XEvent *event) |
|
266 |
{
|
|
267 |
meta_group_reload_property (group, |
|
268 |
event->xproperty.atom); |
|
269 |
||
270 |
return TRUE; |
|
271 |
||
272 |
}
|