X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Factions%2Fgrowtoedge.c;h=a37e3a26e093606100ea82581e368bcf7bb4fff1;hb=fdabb69f4f25596df972caa76c85c2aeba26226e;hp=a5b24e37e85b255530ae33aab97e822b56941d34;hpb=01a35904fec67a7f92a0eb7f19457e79ca3d0988;p=chaz%2Fopenbox diff --git a/openbox/actions/growtoedge.c b/openbox/actions/growtoedge.c index a5b24e37..a37e3a26 100644 --- a/openbox/actions/growtoedge.c +++ b/openbox/actions/growtoedge.c @@ -7,31 +7,32 @@ typedef struct { ObDirection dir; + gboolean shrink; } Options; -static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node); -static void free_func(gpointer options); +static gpointer setup_func(xmlNodePtr node); +static gpointer setup_shrink_func(xmlNodePtr node); static gboolean run_func(ObActionsData *data, gpointer options); -void action_growtoedge_startup() +void action_growtoedge_startup(void) { - actions_register("GrowToEdge", - setup_func, - free_func, - run_func, - NULL, NULL); + actions_register("GrowToEdge", setup_func, + g_free, run_func, NULL, NULL); + actions_register("ShrinkToEdge", setup_shrink_func, + g_free, run_func, NULL, NULL); } -static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node) +static gpointer setup_func(xmlNodePtr node) { xmlNodePtr n; Options *o; o = g_new0(Options, 1); o->dir = OB_DIRECTION_NORTH; + o->shrink = FALSE; - if ((n = parse_find_node("direction", node))) { - gchar *s = parse_string(doc, n); + if ((n = obt_parse_find_node(node, "direction"))) { + gchar *s = obt_parse_node_string(n); if (!g_ascii_strcasecmp(s, "north") || !g_ascii_strcasecmp(s, "up")) o->dir = OB_DIRECTION_NORTH; @@ -50,87 +51,101 @@ static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node) return o; } -static void free_func(gpointer options) +static gpointer setup_shrink_func(xmlNodePtr node) { - Options *o = options; + Options *o; + + o = setup_func(node); + o->shrink = TRUE; + + return o; +} - g_free(o); +static gboolean do_grow(ObActionsData *data, gint x, gint y, gint w, gint h) +{ + gint realw, realh, lw, lh; + + realw = w; + realh = h; + client_try_configure(data->client, &x, &y, &realw, &realh, + &lw, &lh, TRUE); + /* if it's going to be resized smaller than it intended, don't + move the window over */ + if (x != data->client->area.x) x += w - realw; + if (y != data->client->area.y) y += h - realh; + + if (x != data->client->area.x || y != data->client->area.y || + realw != data->client->area.width || + realh != data->client->area.height) + { + actions_client_move(data, TRUE); + client_move_resize(data->client, x, y, realw, realh); + actions_client_move(data, FALSE); + return TRUE; + } + return FALSE; } /* Always return FALSE because its not interactive */ static gboolean run_func(ObActionsData *data, gpointer options) { Options *o = options; + gint x, y, w, h; + ObDirection opp; + gint half; + + if (!data->client || + /* don't allow vertical resize if shaded */ + ((o->dir == OB_DIRECTION_NORTH || o->dir == OB_DIRECTION_SOUTH) && + data->client->shaded)) + { + return FALSE; + } - if (data->client) { - gint x, y, width, height, dest; - ObClient *c = data->client; - Rect *a; - - a = screen_area(c->desktop, SCREEN_AREA_ALL_MONITORS, &c->frame->area); - x = c->frame->area.x; - y = c->frame->area.y; - /* get the unshaded frame's dimensions..if it is shaded */ - width = c->area.width + c->frame->size.left + c->frame->size.right; - height = c->area.height + c->frame->size.top + c->frame->size.bottom; - -#if 0 - dest = client_directional_edge_search(c, o->dir); - - switch(o->dir) { - case OB_DIRECTION_NORTH: - if (c->shaded) break; /* don't allow vertical resize if shaded */ - - if (a->y == y) - height = height / 2; - else { - height = c->frame->area.y + height - dest; - y = dest; - } - break; - case OB_DIRECTION_WEST: - if (a->x == x) - width = width / 2; - else { - width = c->frame->area.x + width - dest; - x = dest; - } - break; - case OB_DIRECTION_SOUTH: - if (c->shaded) break; /* don't allow vertical resize if shaded */ - - if (a->y + a->height == y + c->frame->area.height) { - height = c->frame->area.height / 2; - y = a->y + a->height - height; - } else - height = dest - c->frame->area.y; - y += (height - c->frame->area.height) % c->size_inc.height; - height -= (height - c->frame->area.height) % c->size_inc.height; - break; - case OB_DIRECTION_EAST: - if (a->x + a->width == x + c->frame->area.width) { - width = c->frame->area.width / 2; - x = a->x + a->width - width; - } else - width = dest - c->frame->area.x; - x += (width - c->frame->area.width) % c->size_inc.width; - width -= (width - c->frame->area.width) % c->size_inc.width; - break; - default: - g_assert_not_reached(); - } - - width -= c->frame->size.left + c->frame->size.right; - height -= c->frame->size.top + c->frame->size.bottom; - frame_frame_gravity(c->frame, &x, &y); - - actions_client_move(data, FALSE); - client_move_resize(c, x, y, width, height); - actions_client_move(data, TRUE); + if (!o->shrink) { + /* try grow */ + client_find_resize_directional(data->client, o->dir, TRUE, + &x, &y, &w, &h); + if (do_grow(data, x, y, w, h)) + return FALSE; + } -#endif - g_free(a); + /* we couldn't grow, so try shrink! */ + opp = (o->dir == OB_DIRECTION_NORTH ? OB_DIRECTION_SOUTH : + (o->dir == OB_DIRECTION_SOUTH ? OB_DIRECTION_NORTH : + (o->dir == OB_DIRECTION_EAST ? OB_DIRECTION_WEST : + OB_DIRECTION_EAST))); + client_find_resize_directional(data->client, opp, FALSE, + &x, &y, &w, &h); + switch (opp) { + case OB_DIRECTION_NORTH: + half = data->client->area.y + data->client->area.height / 2; + if (y > half) { + h += y - half; + y = half; + } + break; + case OB_DIRECTION_SOUTH: + half = data->client->area.height / 2; + if (h < half) + h = half; + break; + case OB_DIRECTION_WEST: + half = data->client->area.x + data->client->area.width / 2; + if (x > half) { + w += x - half; + x = half; + } + break; + case OB_DIRECTION_EAST: + half = data->client->area.width / 2; + if (w < half) + w = half; + break; + default: g_assert_not_reached(); } + if (do_grow(data, x, y, w, h)) + return FALSE; return FALSE; }