X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fplace.c;h=d9919d0cadd3ed09c53e23a820d1642f006fad07;hb=fd77a0a7b3f892925f203287b8b46c6ec9be94ea;hp=9991196621018cfcf7bee2fc34d275fc14fb7b98;hpb=a9f2b2c681cd7028398ef62513dec003376bda6b;p=chaz%2Fopenbox diff --git a/openbox/place.c b/openbox/place.c index 99911966..d9919d0c 100644 --- a/openbox/place.c +++ b/openbox/place.c @@ -43,20 +43,7 @@ static void add_choice(guint *choice, guint mychoice) static Rect *pick_pointer_head(ObClient *c) { - guint i; - gint px, py; - - if (screen_pointer_pos(&px, &py)) { - for (i = 0; i < screen_num_monitors; ++i) { - Rect *monitor = screen_physical_area_monitor(i); - gboolean contain = RECT_CONTAINS(*monitor, px, py); - g_free(monitor); - if (contain) - return screen_area(c->desktop, i, NULL); - } - g_assert_not_reached(); - } else - return NULL; + return screen_area(c->desktop, screen_monitor_pointer(), NULL); } /*! Pick a monitor to place a window on. */ @@ -76,7 +63,7 @@ static Rect **pick_head(ObClient *c) /* try direct parent first */ if ((p = client_direct_parent(c))) { add_choice(choice, client_monitor(p)); - ob_debug("placement adding choice %d for parent\n", + ob_debug("placement adding choice %d for parent", client_monitor(p)); } @@ -86,43 +73,45 @@ static Rect **pick_head(ObClient *c) /* try on the client's desktop */ for (it = c->group->members; it; it = g_slist_next(it)) { - ObClient *itc = it->data; + ObClient *itc = it->data; 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", + ob_debug("placement adding choice %d for group sibling", client_monitor(it->data)); } } /* try on all desktops */ for (it = c->group->members; it; it = g_slist_next(it)) { - ObClient *itc = it->data; + ObClient *itc = it->data; 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)); + "another desktop", client_monitor(it->data)); } } } - if (focus_client) { + /* skip this if placing by the mouse position */ + if (focus_client && client_normal(focus_client) && + config_place_monitor != OB_PLACE_MONITOR_MOUSE) + { add_choice(choice, client_monitor(focus_client)); - ob_debug("placement adding choice %d for focused window\n", + ob_debug("placement adding choice %d for normal focused window", client_monitor(focus_client)); } screen_pointer_pos(&px, &py); for (i = 0; i < screen_num_monitors; i++) { - Rect *monitor = screen_physical_area_monitor(i); + const Rect *monitor = screen_physical_area_monitor(i); gboolean contain = RECT_CONTAINS(*monitor, px, py); - g_free(monitor); if (contain) { add_choice(choice, i); - ob_debug("placement adding choice %d for mouse pointer\n", i); + ob_debug("placement adding choice %d for mouse pointer", i); break; } } @@ -134,6 +123,8 @@ static Rect **pick_head(ObClient *c) for (i = 0; i < screen_num_monitors; ++i) area[i] = screen_area(c->desktop, choice[i], NULL); + g_free(choice); + return area; } @@ -144,7 +135,8 @@ static gboolean place_random(ObClient *client, gint *x, gint *y) guint i; areas = pick_head(client); - i = g_random_int_range(0, screen_num_monitors); + i = (config_place_monitor != OB_PLACE_MONITOR_ANY) ? + 0 : g_random_int_range(0, screen_num_monitors); l = areas[i]->x; t = areas[i]->y; @@ -157,7 +149,7 @@ static gboolean place_random(ObClient *client, gint *x, gint *y) else *y = areas[i]->y; for (i = 0; i < screen_num_monitors; ++i) - g_free(areas[i]); + g_slice_free(Rect, areas[i]); g_free(areas); return TRUE; @@ -165,7 +157,7 @@ static gboolean place_random(ObClient *client, gint *x, gint *y) static GSList* area_add(GSList *list, Rect *a) { - Rect *r = g_new(Rect, 1); + Rect *r = g_slice_new(Rect); *r = *a; return g_slist_prepend(list, r); } @@ -180,7 +172,7 @@ static GSList* area_remove(GSList *list, Rect *a) if (!RECT_INTERSECTS_RECT(*r, *a)) { result = g_slist_prepend(result, r); - r = NULL; /* dont free it */ + /* dont free r, it's moved to the result list */ } else { Rect isect, extra; @@ -215,9 +207,10 @@ static GSList* area_remove(GSList *list, Rect *a) r->width, RECT_BOTTOM(*r) - RECT_BOTTOM(isect)); result = area_add(result, &extra); } - } - g_free(r); + /* 'r' is not being added to the result list, so free it */ + g_slice_free(Rect, r); + } } g_slist_free(list); return result; @@ -251,10 +244,11 @@ static gboolean place_nooverlap(ObClient *c, gint *x, gint *y) /* try ignoring different things to find empty space */ for (ignore = 0; ignore < IGNORE_END && !ret; ignore++) { - guint i; - - /* try all monitors in order of preference */ - for (i = 0; i < screen_num_monitors && !ret; ++i) { + /* try all monitors in order of preference, but only the first one + if config_place_monitor is MOUSE or ACTIVE */ + for (i = 0; (i < (config_place_monitor != OB_PLACE_MONITOR_ANY ? + 1 : screen_num_monitors) && !ret); ++i) + { GList *it; /* add the whole monitor */ @@ -316,9 +310,9 @@ static gboolean place_nooverlap(ObClient *c, gint *x, gint *y) if (r->width >= c->frame->area.width && r->height >= c->frame->area.height && - r->width > maxsize) + r->width * r->height > maxsize) { - maxsize = r->width; + maxsize = r->width * r->height; maxit = sit; } } @@ -337,14 +331,14 @@ static gboolean place_nooverlap(ObClient *c, gint *x, gint *y) } while (spaces) { - g_free(spaces->data); + g_slice_free(Rect, spaces->data); spaces = g_slist_delete_link(spaces, spaces); } } } for (i = 0; i < screen_num_monitors; ++i) - g_free(areas[i]); + g_slice_free(Rect, areas[i]); g_free(areas); return ret; } @@ -369,6 +363,8 @@ static gboolean place_under_mouse(ObClient *client, gint *x, gint *y) *y = py - client->area.height / 2 - client->frame->size.top; *y = MIN(MAX(*y, t), b); + g_slice_free(Rect, area); + return TRUE; } @@ -399,27 +395,31 @@ static gboolean place_per_app_setting(ObClient *client, gint *x, gint *y, /* don't free the first one, it's being set as "screen" */ for (i = 1; i < screen_num_monitors; ++i) - g_free(areas[i]); + g_slice_free(Rect, areas[i]); g_free(areas); } - if (settings->center_x) + if (settings->position.x.center) *x = screen->x + screen->width / 2 - client->area.width / 2; - else if (settings->opposite_x) + else if (settings->position.x.opposite) *x = screen->x + screen->width - client->frame->area.width - - settings->position.x; + settings->position.x.pos; else - *x = screen->x + settings->position.x; + *x = screen->x + settings->position.x.pos; + if (settings->position.x.denom) + *x = (*x * screen->width) / settings->position.x.denom; - if (settings->center_y) + if (settings->position.y.center) *y = screen->y + screen->height / 2 - client->area.height / 2; - else if (settings->opposite_y) + else if (settings->position.y.opposite) *y = screen->y + screen->height - client->frame->area.height - - settings->position.y; + settings->position.y.pos; else - *y = screen->y + settings->position.y; + *y = screen->y + settings->position.y.pos; + if (settings->position.y.denom) + *y = (*y * screen->height) / settings->position.y.denom; - g_free(screen); + g_slice_free(Rect, screen); return TRUE; } @@ -446,7 +446,7 @@ static gboolean place_transient_splash(ObClient *client, gint *x, gint *y) } } if (!first) { - *x = ((r + 1 - l) - client->frame->area.width) / 2 + l; + *x = ((r + 1 - l) - client->frame->area.width) / 2 + l; *y = ((b + 1 - t) - client->frame->area.height) / 2 + t; return TRUE; } @@ -465,7 +465,7 @@ static gboolean place_transient_splash(ObClient *client, gint *x, gint *y) *y = (areas[0]->height - client->frame->area.height) / 2 + areas[0]->y; for (i = 0; i < screen_num_monitors; ++i) - g_free(areas[i]); + g_slice_free(Rect, areas[i]); g_free(areas); return TRUE; } @@ -473,23 +473,24 @@ static gboolean place_transient_splash(ObClient *client, gint *x, gint *y) return FALSE; } -/* Return TRUE if we want client.c to enforce on-screen-keeping */ +/*! Return TRUE if openbox chose the position for the window, and FALSE if + the application chose it */ gboolean place_client(ObClient *client, gint *x, gint *y, ObAppSettings *settings) { gboolean ret; - gboolean userplaced = FALSE; /* per-app settings override program specified position - * but not user specified */ - if ((client->positioned & USPosition) || + * but not user specified, unless pos_force is enabled */ + if (((client->positioned & USPosition) && + !(settings && settings->pos_given && settings->pos_force)) || ((client->positioned & PPosition) && !(settings && settings->pos_given))) return FALSE; /* try a number of methods */ - ret = place_transient_splash(client, x, y) || - (userplaced = place_per_app_setting(client, x, y, settings)) || + ret = place_per_app_setting(client, x, y, settings) || + place_transient_splash(client, x, y) || (config_place_policy == OB_PLACE_POLICY_MOUSE && place_under_mouse(client, x, y)) || place_nooverlap(client, x, y) || @@ -498,5 +499,5 @@ gboolean place_client(ObClient *client, gint *x, gint *y, /* get where the client should be */ frame_frame_gravity(client->frame, x, y); - return !userplaced; + return TRUE; }