X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fplace.c;h=e9832ec30a3bb45775ee453add1d282715c2fab5;hb=4940d007cce43a135f1b448902f5a3571dbce62a;hp=4717cbfc3c3ca98ca962d4a7f8fb093a6e562b51;hpb=0e9bd66b75725b4d6632eafcaeb34b9fe310e4ea;p=chaz%2Fopenbox diff --git a/openbox/place.c b/openbox/place.c index 4717cbfc..e9832ec3 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) { @@ -52,6 +53,9 @@ static Rect *pick_pointer_head(ObClient *c) g_assert_not_reached(); } +/*! Pick a monitor to place a window on. + The returned array value should be freed with g_free. The areas within the + array should not be freed. */ static Rect **pick_head(ObClient *c) { Rect **area; @@ -67,6 +71,8 @@ static Rect **pick_head(ObClient *c) /* try direct parent first */ if (c->transient_for && c->transient_for != OB_TRAN_GROUP) { add_choice(choice, client_monitor(c->transient_for)); + ob_debug("placement adding choice %d for parent\n", + client_monitor(c->transient_for)); } /* more than one window in its group (more than just this window) */ @@ -79,25 +85,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; } @@ -126,9 +143,9 @@ static gboolean place_random(ObClient *client, gint *x, gint *y) b = areas[i]->y + areas[i]->height - client->frame->area.height; if (r > l) *x = g_random_int_range(l, r + 1); - else *x = 0; + else *x = areas[i]->x; if (b > t) *y = g_random_int_range(t, b + 1); - else *y = 0; + else *y = areas[i]->y; g_free(areas); @@ -251,7 +268,7 @@ typedef enum } ObSmartType; #define SMART_IGNORE(placer, c) \ - (placer == c || !c->frame->visible || c->shaded || !client_normal(c) || \ + (placer == c || c->shaded || !client_normal(c) || !c->frame->visible || \ (c->desktop != DESKTOP_ALL && \ c->desktop != (placer->desktop == DESKTOP_ALL ? \ screen_desktop : placer->desktop))) @@ -273,7 +290,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 */ @@ -282,7 +299,7 @@ static gboolean place_smart(ObClient *client, gint *x, gint *y, if (WINDOW_IS_CLIENT(it->data)) { c = it->data; - if (c->fullscreen) + if (c->fullscreen || (c->max_vert && c->max_horz)) continue; } else continue; @@ -306,7 +323,7 @@ static gboolean place_smart(ObClient *client, gint *x, gint *y, if (WINDOW_IS_CLIENT(it->data)) { c = it->data; - if (c->fullscreen) + if (c->fullscreen || (c->max_vert && c->max_horz)) continue; } else continue; @@ -388,16 +405,24 @@ static gboolean place_under_mouse(ObClient *client, gint *x, gint *y) static gboolean place_per_app_setting(ObClient *client, gint *x, gint *y, ObAppSettings *settings) { - Rect *screen; + Rect *screen = NULL; if (!settings || (settings && !settings->pos_given)) return FALSE; /* Find which head the pointer is on */ - if (settings->head == -1) + if (settings->monitor == 0) screen = pick_pointer_head(client); - else - screen = screen_area_monitor(client->desktop, settings->head); + else if (settings->monitor > 0 && + (guint)settings->monitor <= screen_num_monitors) + screen = screen_area_monitor(client->desktop, + (guint)settings->monitor - 1); + else { + Rect **all = NULL; + all = pick_head(client); + screen = all[0]; + g_free(all); /* the areas themselves don't need to be freed */ + } if (settings->center_x) *x = screen->x + screen->width / 2 - client->area.width / 2; @@ -412,17 +437,20 @@ static gboolean place_per_app_setting(ObClient *client, gint *x, gint *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 && client->type == OB_CLIENT_TYPE_DIALOG) { if (client->transient_for != OB_TRAN_GROUP) { ObClient *c = client; ObClient *p = client->transient_for; - *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; + + 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; @@ -451,6 +479,21 @@ static gboolean place_transient(ObClient *client, gint *x, gint *y) } } } + + if ((client->transient && client->type == OB_CLIENT_TYPE_DIALOG) + || client->type == OB_CLIENT_TYPE_SPLASH) + { + Rect **areas; + + areas = pick_head(client); + + *x = (areas[0]->width - client->frame->area.width) / 2 + areas[0]->x; + *y = (areas[0]->height - client->frame->area.height) / 2 + areas[0]->y; + + g_free(areas); + return TRUE; + } + return FALSE; } @@ -461,7 +504,7 @@ 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) || @@ -473,6 +516,7 @@ gboolean place_client(ObClient *client, gint *x, gint *y, place_random(client, x, y)))) g_assert_not_reached(); /* the last one better succeed */ /* get where the client should be */ - frame_frame_gravity(client->frame, x, y); + frame_frame_gravity(client->frame, x, y, + client->area.width, client->area.height); return ret; }