6 static Rect* pick_head(ObClient *c)
8 /* try direct parent first */
9 if (c->transient_for && c->transient_for != OB_TRAN_GROUP) {
10 return screen_area_monitor(c->desktop,
11 client_monitor(c->transient_for));
14 /* more than one guy in his group (more than just him) */
15 if (c->group && c->group->members->next) {
18 /* try on the client's desktop */
19 for (it = c->group->members; it; it = g_slist_next(it)) {
20 ObClient *itc = it->data;
22 (itc->desktop == c->desktop ||
23 itc->desktop == DESKTOP_ALL || c->desktop == DESKTOP_ALL))
24 return screen_area_monitor(c->desktop,
25 client_monitor(it->data));
28 /* try on all desktops */
29 for (it = c->group->members; it; it = g_slist_next(it)) {
30 ObClient *itc = it->data;
32 return screen_area_monitor(c->desktop,
33 client_monitor(it->data));
40 static gboolean place_random(ObClient *client, gint *x, gint *y)
45 area = pick_head(client);
47 area = screen_area_monitor(client->desktop,
48 g_random_int_range(0, screen_num_monitors));
52 r = area->x + area->width - client->frame->area.width;
53 b = area->y + area->height - client->frame->area.height;
55 if (r > l) *x = g_random_int_range(l, r + 1);
57 if (b > t) *y = g_random_int_range(t, b + 1);
60 /* get where the client should be */
61 frame_frame_gravity(client->frame, x, y);
66 static gboolean place_transient(ObClient *client, gint *x, gint *y)
68 if (client->transient_for) {
69 if (client->transient_for != OB_TRAN_GROUP) {
71 ObClient *p = client->transient_for;
72 *x = (p->frame->area.width - c->frame->area.width) / 2 +
74 *y = (p->frame->area.height - c->frame->area.height) / 2 +
79 gboolean first = TRUE;
81 for (it = client->group->members; it; it = it->next) {
82 ObClient *m = it->data;
83 if (!(m == client || m->transient_for)) {
87 r = m->frame->area.x + m->frame->area.width - 1;
88 b = m->frame->area.y + m->frame->area.height - 1;
91 l = MIN(l, m->frame->area.x);
92 t = MIN(t, m->frame->area.y);
93 r = MAX(r, m->frame->area.x +m->frame->area.width - 1);
94 b = MAX(b, m->frame->area.y +m->frame->area.height -1);
99 *x = ((r + 1 - l) - client->frame->area.width) / 2 + l;
100 *y = ((b + 1 - t) - client->frame->area.height) / 2 + t;
108 static gboolean place_dialog(ObClient *client, gint *x, gint *y)
110 /* center parentless dialogs on the screen */
111 if (client->type == OB_CLIENT_TYPE_DIALOG) {
114 area = pick_head(client);
116 area = screen_area_monitor(client->desktop, 0);
118 *x = (area->width - client->frame->area.width) / 2 + area->x;
119 *y = (area->height - client->frame->area.height) / 2 + area->y;
125 void place_client(ObClient *client, gint *x, gint *y)
127 if (client->positioned)
129 if (place_transient(client, x, y))
131 if (place_dialog(client, x, y))
133 if (place_random(client, x, y))
135 g_assert_not_reached(); /* the last one better succeed */