From: Dana Jansens Date: Fri, 11 Jun 2010 20:20:43 +0000 (-0400) Subject: when managing a window, make sure its area is within its min/max bounds X-Git-Tag: cgl~34 X-Git-Url: http://git.openbox.org/?a=commitdiff_plain;h=1ba1747c82ad303d66a428c306661701d7c5fb92;p=dana%2Fopenbox.git when managing a window, make sure its area is within its min/max bounds --- diff --git a/openbox/client.c b/openbox/client.c index 2b8842c9..de3e5124 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -308,14 +308,21 @@ void client_manage(Window window, ObPrompt *prompt) /* remove the client's border */ XSetWindowBorderWidth(obt_display, self->window, 0); - /* adjust the frame to the client's size before showing or placing - the window */ + /* set up the frame for its original dimensions before trying to place the + window */ frame_adjust_area(self->frame, FALSE, TRUE, FALSE); frame_adjust_client_area(self->frame); /* where the frame was placed is where the window was originally */ place = self->area; + /* but make sure the width/height are valid */ + { + gint l; + client_try_configure(self, &place.x, &place.y, + &place.width, &place.height, &l, &l, FALSE); + } + /* figure out placement for the window if the window is new */ if (ob_state() == OB_STATE_RUNNING) { ob_debug("Positioned: %s @ %d %d", @@ -334,7 +341,8 @@ void client_manage(Window window, ObPrompt *prompt) "program + user specified" : "BADNESS !?")))), place.width, place.height); - obplaced = place_client(self, &place.x, &place.y, settings); + obplaced = place_client(self, &place.x, &place.y, + place.width, place.height, settings); /* watch for buggy apps that ask to be placed at (0,0) when there is a strut there */ diff --git a/openbox/place.c b/openbox/place.c index d9919d0c..7accf62b 100644 --- a/openbox/place.c +++ b/openbox/place.c @@ -128,9 +128,10 @@ static Rect **pick_head(ObClient *c) return area; } -static gboolean place_random(ObClient *client, gint *x, gint *y) +static gboolean place_random(ObClient *client, gint *x, gint *y, + gint w, gint h) { - gint l, r, t, b; + gint l, r, t, b, fw, fh; Rect **areas; guint i; @@ -138,10 +139,13 @@ static gboolean place_random(ObClient *client, gint *x, gint *y) i = (config_place_monitor != OB_PLACE_MONITOR_ANY) ? 0 : g_random_int_range(0, screen_num_monitors); + fw = w + client->frame->size.left + client->frame->size.right; + fh = h + client->frame->size.top + client->frame->size.bottom; + l = areas[i]->x; t = areas[i]->y; - r = areas[i]->x + areas[i]->width - client->frame->area.width; - b = areas[i]->y + areas[i]->height - client->frame->area.height; + r = areas[i]->x + areas[i]->width - fw; + b = areas[i]->y + areas[i]->height - fh; if (r > l) *x = g_random_int_range(l, r + 1); else *x = areas[i]->x; @@ -228,7 +232,7 @@ enum { IGNORE_END = 7 }; -static gboolean place_nooverlap(ObClient *c, gint *x, gint *y) +static gboolean place_nooverlap(ObClient *c, gint *x, gint *y, gint w, gint h) { Rect **areas; gint ignore; @@ -308,8 +312,10 @@ static gboolean place_nooverlap(ObClient *c, gint *x, gint *y) for (sit = spaces; sit; sit = g_slist_next(sit)) { Rect *r = sit->data; - if (r->width >= c->frame->area.width && - r->height >= c->frame->area.height && + const gint fw = w + c->frame->size.left + c->frame->size.right; + const gint fh = h + c->frame->size.top + c->frame->size.bottom; + + if (r->width >= fw && r->height >= fh && r->width * r->height > maxsize) { maxsize = r->width * r->height; @@ -320,12 +326,15 @@ static gboolean place_nooverlap(ObClient *c, gint *x, gint *y) if (maxit) { Rect *r = maxit->data; + const gint fw = w + c->frame->size.left + c->frame->size.right; + const gint fh = h + c->frame->size.top + c->frame->size.bottom; + /* center it in the area */ *x = r->x; *y = r->y; if (config_place_center) { - *x += (r->width - c->frame->area.width) / 2; - *y += (r->height - c->frame->area.height) / 2; + *x += (r->width - fw) / 2; + *y += (r->height - fh) / 2; } ret = TRUE; } @@ -343,20 +352,24 @@ static gboolean place_nooverlap(ObClient *c, gint *x, gint *y) return ret; } -static gboolean place_under_mouse(ObClient *client, gint *x, gint *y) +static gboolean place_under_mouse(ObClient *client, gint *x, gint *y, + gint w, gint h) { gint l, r, t, b; gint px, py; Rect *area; + const gint fw = w + client->frame->size.left + client->frame->size.right; + const gint fh = h + client->frame->size.top + client->frame->size.bottom; + if (!screen_pointer_pos(&px, &py)) return FALSE; area = pick_pointer_head(client); l = area->x; t = area->y; - r = area->x + area->width - client->frame->area.width; - b = area->y + area->height - client->frame->area.height; + r = area->x + area->width - fw; + b = area->y + area->height - fh; *x = px - client->area.width / 2 - client->frame->size.left; *x = MIN(MAX(*x, l), r); @@ -369,10 +382,13 @@ 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) + gint w, gint h, ObAppSettings *settings) { Rect *screen = NULL; + const gint fw = w + client->frame->size.left + client->frame->size.right; + const gint fh = h + client->frame->size.top + client->frame->size.bottom; + if (!settings || (settings && !settings->pos_given)) return FALSE; @@ -402,8 +418,7 @@ static gboolean place_per_app_setting(ObClient *client, gint *x, gint *y, if (settings->position.x.center) *x = screen->x + screen->width / 2 - client->area.width / 2; else if (settings->position.x.opposite) - *x = screen->x + screen->width - client->frame->area.width - - settings->position.x.pos; + *x = screen->x + screen->width - fw - settings->position.x.pos; else *x = screen->x + settings->position.x.pos; if (settings->position.x.denom) @@ -412,8 +427,7 @@ static gboolean place_per_app_setting(ObClient *client, gint *x, gint *y, if (settings->position.y.center) *y = screen->y + screen->height / 2 - client->area.height / 2; else if (settings->position.y.opposite) - *y = screen->y + screen->height - client->frame->area.height - - settings->position.y.pos; + *y = screen->y + screen->height - fh - settings->position.y.pos; else *y = screen->y + settings->position.y.pos; if (settings->position.y.denom) @@ -423,7 +437,8 @@ static gboolean place_per_app_setting(ObClient *client, gint *x, gint *y, return TRUE; } -static gboolean place_transient_splash(ObClient *client, gint *x, gint *y) +static gboolean place_transient_splash(ObClient *client, gint *x, gint *y, + gint w, gint h) { if (client->type == OB_CLIENT_TYPE_DIALOG) { GSList *it; @@ -446,8 +461,12 @@ static gboolean place_transient_splash(ObClient *client, gint *x, gint *y) } } if (!first) { - *x = ((r + 1 - l) - client->frame->area.width) / 2 + l; - *y = ((b + 1 - t) - client->frame->area.height) / 2 + t; + const gint fw = w + client->frame->size.left + + client->frame->size.right; + const gint fh = h + client->frame->size.top + + client->frame->size.bottom; + *x = ((r + 1 - l) - fw) / 2 + l; + *y = ((b + 1 - t) - fh) / 2 + t; return TRUE; } } @@ -459,10 +478,15 @@ static gboolean place_transient_splash(ObClient *client, gint *x, gint *y) Rect **areas; guint i; + const gint fw = w + client->frame->size.left + + client->frame->size.right; + const gint fh = h + client->frame->size.top + + client->frame->size.bottom; + 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; + *x = (areas[0]->width - fw) / 2 + areas[0]->x; + *y = (areas[0]->height - fh) / 2 + areas[0]->y; for (i = 0; i < screen_num_monitors; ++i) g_slice_free(Rect, areas[i]); @@ -475,7 +499,7 @@ static gboolean place_transient_splash(ObClient *client, gint *x, gint *y) /*! 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, +gboolean place_client(ObClient *client, gint *x, gint *y, gint w, gint h, ObAppSettings *settings) { gboolean ret; @@ -489,12 +513,12 @@ gboolean place_client(ObClient *client, gint *x, gint *y, return FALSE; /* try a number of methods */ - ret = place_per_app_setting(client, x, y, settings) || - place_transient_splash(client, x, y) || + ret = place_per_app_setting(client, x, y, w, h, settings) || + place_transient_splash(client, x, y, w, h) || (config_place_policy == OB_PLACE_POLICY_MOUSE && - place_under_mouse(client, x, y)) || - place_nooverlap(client, x, y) || - place_random(client, x, y); + place_under_mouse(client, x, y, w, h)) || + place_nooverlap(client, x, y, w, h) || + place_random(client, x, y, w, h); g_assert(ret); /* get where the client should be */ diff --git a/openbox/place.h b/openbox/place.h index 6a9add40..535e1d6a 100644 --- a/openbox/place.h +++ b/openbox/place.h @@ -39,6 +39,6 @@ typedef enum } ObPlaceMonitor; gboolean place_client(struct _ObClient *client, gint *x, gint *y, - struct _ObAppSettings *settings); + gint w, gint h, struct _ObAppSettings *settings); #endif