X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=openbox%2Fplace.c;h=0b8309a22ba74d6c867c1b673c27022ad60f101c;hb=b068bf8528748c5197b7b64a4ba89d65b7c01bf3;hp=f37973b3ed9bfce0298c5f4bc9985b9163abd131;hpb=7ffa091d5b464ce508023c3b5e5bc50a36be53fb;p=chaz%2Fopenbox diff --git a/openbox/place.c b/openbox/place.c index f37973b3..0b8309a2 100644 --- a/openbox/place.c +++ b/openbox/place.c @@ -23,6 +23,7 @@ #include "frame.h" #include "focus.h" #include "config.h" +#include "debug.h" static void add_choice(guint *choice, guint mychoice) { @@ -61,6 +62,7 @@ static Rect **pick_head(ObClient *c) guint *choice; guint i; gint px, py; + ObClient *p; area = g_new(Rect*, screen_num_monitors); choice = g_new(guint, screen_num_monitors); @@ -68,8 +70,10 @@ static Rect **pick_head(ObClient *c) choice[i] = screen_num_monitors; /* make them all invalid to start */ /* try direct parent first */ - if (c->transient_for && c->transient_for != OB_TRAN_GROUP) { - add_choice(choice, client_monitor(c->transient_for)); + if ((p = client_direct_parent(c))) { + add_choice(choice, client_monitor(p)); + ob_debug("placement adding choice %d for parent\n", + client_monitor(p)); } /* more than one window in its group (more than just this window) */ @@ -82,25 +86,36 @@ static Rect **pick_head(ObClient *c) if (itc != c && (itc->desktop == c->desktop || itc->desktop == DESKTOP_ALL || c->desktop == DESKTOP_ALL)) + { add_choice(choice, client_monitor(it->data)); + ob_debug("placement adding choice %d for group sibling\n", + client_monitor(it->data)); + } } /* try on all desktops */ for (it = c->group->members; it; it = g_slist_next(it)) { ObClient *itc = it->data; - if (itc != c) + if (itc != c) { add_choice(choice, client_monitor(it->data)); + ob_debug("placement adding choice %d for group sibling on " + "another desktop\n", client_monitor(it->data)); + } } } - if (focus_client) + if (focus_client) { add_choice(choice, client_monitor(focus_client)); + ob_debug("placement adding choice %d for focused window\n", + client_monitor(focus_client)); + } screen_pointer_pos(&px, &py); for (i = 0; i < screen_num_monitors; i++) if (RECT_CONTAINS(*screen_physical_area_monitor(i), px, py)) { add_choice(choice, i); + ob_debug("placement adding choice %d for mouse pointer\n", i); break; } @@ -254,13 +269,16 @@ typedef enum } ObSmartType; #define SMART_IGNORE(placer, c) \ - (placer == c || c->shaded || !client_normal(c) || !c->frame->visible || \ + (placer == c || c->shaded || !c->frame->visible || \ + c->type == OB_CLIENT_TYPE_SPLASH || c->type == OB_CLIENT_TYPE_DESKTOP || \ + ((c->type == OB_CLIENT_TYPE_MENU || c->type == OB_CLIENT_TYPE_TOOLBAR) &&\ + client_has_parent(c)) || \ (c->desktop != DESKTOP_ALL && \ c->desktop != (placer->desktop == DESKTOP_ALL ? \ screen_desktop : placer->desktop))) static gboolean place_smart(ObClient *client, gint *x, gint *y, - ObSmartType type) + ObSmartType type, gboolean ignore_max) { gboolean ret = FALSE; GSList *spaces = NULL, *sit; @@ -276,7 +294,7 @@ static gboolean place_smart(ObClient *client, gint *x, gint *y, areas = pick_head(client); - for (i = 0; i < screen_num_monitors; ++i) { + for (i = 0; i < screen_num_monitors && !ret; ++i) { spaces = area_add(spaces, areas[i]); /* stay out from under windows in higher layers */ @@ -285,7 +303,8 @@ static gboolean place_smart(ObClient *client, gint *x, gint *y, if (WINDOW_IS_CLIENT(it->data)) { c = it->data; - if (c->fullscreen || (c->max_vert && c->max_horz)) + if (ignore_max && + (c->fullscreen || (c->max_vert && c->max_horz))) continue; } else continue; @@ -309,7 +328,8 @@ static gboolean place_smart(ObClient *client, gint *x, gint *y, if (WINDOW_IS_CLIENT(it->data)) { c = it->data; - if (c->fullscreen || (c->max_vert && c->max_horz)) + if (ignore_max && + (c->fullscreen || (c->max_vert && c->max_horz))) continue; } else continue; @@ -412,50 +432,43 @@ static gboolean place_per_app_setting(ObClient *client, gint *x, gint *y, if (settings->center_x) *x = screen->x + screen->width / 2 - client->area.width / 2; + else if (settings->opposite_x) + *x = screen->x + screen->width - client->frame->area.width - + settings->position.x; else *x = screen->x + settings->position.x; if (settings->center_y) *y = screen->y + screen->height / 2 - client->area.height / 2; + else if (settings->opposite_y) + *y = screen->y + screen->height - client->frame->area.height - + settings->position.y; else *y = screen->y + settings->position.y; return TRUE; } -static gboolean place_transient(ObClient *client, gint *x, gint *y) +static gboolean place_transient_splash(ObClient *client, gint *x, gint *y) { - if (client->transient_for) { - if (client->transient_for != OB_TRAN_GROUP) { - ObClient *c = client; - ObClient *p = client->transient_for; - - if (client_normal(p)) { - *x = (p->frame->area.width - c->frame->area.width) / 2 + - p->frame->area.x; - *y = (p->frame->area.height - c->frame->area.height) / 2 + - p->frame->area.y; - return TRUE; - } - } else { - GSList *it; - gboolean first = TRUE; - gint l, r, t, b; - for (it = client->group->members; it; it = g_slist_next(it)) { - ObClient *m = it->data; - if (!(m == client || m->transient_for) && client_normal(m)) { - if (first) { - l = RECT_LEFT(m->frame->area); - t = RECT_TOP(m->frame->area); - r = RECT_RIGHT(m->frame->area); - b = RECT_BOTTOM(m->frame->area); - first = FALSE; - } else { - l = MIN(l, RECT_LEFT(m->frame->area)); - t = MIN(t, RECT_TOP(m->frame->area)); - r = MAX(r, RECT_RIGHT(m->frame->area)); - b = MAX(b, RECT_BOTTOM(m->frame->area)); - } + if (client->type == OB_CLIENT_TYPE_DIALOG) { + GSList *it; + gboolean first = TRUE; + gint l, r, t, b; + for (it = client->parents; it; it = g_slist_next(it)) { + ObClient *m = it->data; + if (!m->iconic) { + if (first) { + l = RECT_LEFT(m->frame->area); + t = RECT_TOP(m->frame->area); + r = RECT_RIGHT(m->frame->area); + b = RECT_BOTTOM(m->frame->area); + first = FALSE; + } else { + l = MIN(l, RECT_LEFT(m->frame->area)); + t = MIN(t, RECT_TOP(m->frame->area)); + r = MAX(r, RECT_RIGHT(m->frame->area)); + b = MAX(b, RECT_BOTTOM(m->frame->area)); } } if (!first) { @@ -466,7 +479,9 @@ static gboolean place_transient(ObClient *client, gint *x, gint *y) } } - if (client->transient) { + if (client->type == OB_CLIENT_TYPE_DIALOG || + client->type == OB_CLIENT_TYPE_SPLASH) + { Rect **areas; areas = pick_head(client); @@ -488,15 +503,17 @@ gboolean place_client(ObClient *client, gint *x, gint *y, gboolean ret = FALSE; if (client->positioned) return FALSE; - if (place_transient(client, x, y)) + if (place_transient_splash(client, x, y)) ret = TRUE; else if (!( place_per_app_setting(client, x, y, settings) || ((config_place_policy == OB_PLACE_POLICY_MOUSE) ? place_under_mouse(client, x, y) : - place_smart(client, x, y, SMART_FULL) || - place_smart(client, x, y, SMART_GROUP) || - place_smart(client, x, y, SMART_FOCUSED) || + place_smart(client, x, y, SMART_FULL, FALSE) || + place_smart(client, x, y, SMART_FULL, TRUE) || + place_smart(client, x, y, SMART_GROUP, FALSE) || + place_smart(client, x, y, SMART_GROUP, TRUE) || + place_smart(client, x, y, SMART_FOCUSED, TRUE) || place_random(client, x, y)))) g_assert_not_reached(); /* the last one better succeed */ /* get where the client should be */