X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=openbox%2Factions%2Fresizerelative.c;h=7ac9f06ef14ea57c36d8fd6da88821c2bb52ea20;hb=8f988b2bef5af05f0b5cddbc11b05c833158df5a;hp=c5fc1ea1cb5b8e91bd418f7aef5d8ee5b2732ab4;hpb=31f0c8c1ad8c9acf369ab8336765f4bf673b8e21;p=chaz%2Fopenbox diff --git a/openbox/actions/resizerelative.c b/openbox/actions/resizerelative.c index c5fc1ea1..7ac9f06e 100644 --- a/openbox/actions/resizerelative.c +++ b/openbox/actions/resizerelative.c @@ -2,21 +2,35 @@ #include "openbox/client.h" #include "openbox/screen.h" #include "openbox/frame.h" -#include /* for atoi */ +#include "openbox/config.h" typedef struct { gint left; + gint left_denom; gint right; + gint right_denom; gint top; + gint top_denom; gint bottom; + gint bottom_denom; } Options; static gpointer setup_func(xmlNodePtr node); +static void free_func(gpointer options); static gboolean run_func(ObActionsData *data, gpointer options); void action_resizerelative_startup(void) { - actions_register("ResizeRelative", setup_func, g_free, run_func); + actions_register("ResizeRelative", setup_func, free_func, run_func); +} + +static void xml_node_relative(xmlNodePtr n, gint *num, gint *denom) +{ + gchar *s; + + s = obt_xml_node_string(n); + config_parse_relative_number(s, num, denom); + g_free(s); } static gpointer setup_func(xmlNodePtr node) @@ -24,22 +38,27 @@ static gpointer setup_func(xmlNodePtr node) xmlNodePtr n; Options *o; - o = g_new0(Options, 1); + o = g_slice_new0(Options); if ((n = obt_xml_find_node(node, "left"))) - o->left = obt_xml_node_int(n); + xml_node_relative(n, &o->left, &o->left_denom); if ((n = obt_xml_find_node(node, "right"))) - o->right = obt_xml_node_int(n); + xml_node_relative(n, &o->right, &o->right_denom); if ((n = obt_xml_find_node(node, "top")) || (n = obt_xml_find_node(node, "up"))) - o->top = obt_xml_node_int(n); + xml_node_relative(n, &o->top, &o->top_denom); if ((n = obt_xml_find_node(node, "bottom")) || (n = obt_xml_find_node(node, "down"))) - o->bottom = obt_xml_node_int(n); + xml_node_relative(n, &o->bottom, &o->bottom_denom); return o; } +static void free_func(gpointer o) +{ + g_slice_free(Options, o); +} + /* Always return FALSE because its not interactive */ static gboolean run_func(ObActionsData *data, gpointer options) { @@ -48,17 +67,28 @@ static gboolean run_func(ObActionsData *data, gpointer options) if (data->client) { ObClient *c = data->client; gint x, y, ow, xoff, nw, oh, yoff, nh, lw, lh; + gint left = o->left, right = o->right, top = o->top, bottom = o->bottom; + + if (o->left_denom) + left = left * c->area.width / o->left_denom; + if (o->right_denom) + right = right * c->area.width / o->right_denom; + if (o->top_denom) + top = top * c->area.height / o->top_denom; + if (o->bottom_denom) + bottom = bottom * c->area.height / o->bottom_denom; + // When resizing, if the resize has a non-zero value then make sure it + // is at least as big as the size increment so the window does actually + // resize. x = c->area.x; y = c->area.y; ow = c->area.width; - xoff = -o->left * c->size_inc.width; - nw = ow + o->right * c->size_inc.width - + o->left * c->size_inc.width; + xoff = -MAX(left, (left ? c->size_inc.width : 0)); + nw = ow + MAX(right + left, (right + left ? c->size_inc.width : 0)); oh = c->area.height; - yoff = -o->top * c->size_inc.height; - nh = oh + o->bottom * c->size_inc.height - + o->top * c->size_inc.height; + yoff = -MAX(top, (top ? c->size_inc.height : 0)); + nh = oh + MAX(bottom + top, (bottom + top ? c->size_inc.height : 0)); client_try_configure(c, &x, &y, &nw, &nh, &lw, &lh, TRUE); xoff = xoff == 0 ? 0 :