From 8e246323e7fd4f578381f57f0e96fd7064adcc18 Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Wed, 14 Apr 2010 19:20:10 +0200 Subject: [PATCH] Add parsing of relative positions --- openbox/actions/moveresizeto.c | 60 ++++++++++++++-------------------------- openbox/config.c | 19 ++++++++++-- openbox/config.h | 3 ++ openbox/geom.h | 1 + openbox/place.c | 4 ++ 5 files changed, 44 insertions(+), 43 deletions(-) diff --git a/openbox/actions/moveresizeto.c b/openbox/actions/moveresizeto.c index ce50e9b..e579250 100644 --- a/openbox/actions/moveresizeto.c +++ b/openbox/actions/moveresizeto.c @@ -2,6 +2,7 @@ #include "openbox/client.h" #include "openbox/screen.h" #include "openbox/frame.h" +#include "openbox/config.h" #include /* for atoi */ enum { @@ -12,12 +13,8 @@ enum { }; typedef struct { - gboolean xcenter; - gboolean ycenter; - gboolean xopposite; - gboolean yopposite; - gint x; - gint y; + GravityCoord x; + GravityCoord y; gint w; gint h; gint monitor; @@ -36,42 +33,23 @@ void action_moveresizeto_startup(void) actions_register("MoveToCenter", setup_center_func, free_func, run_func); } -static void parse_coord(xmlNodePtr n, gint *pos, - gboolean *opposite, gboolean *center) -{ - gchar *s = obt_xml_node_string(n); - if (g_ascii_strcasecmp(s, "current") != 0) { - if (!g_ascii_strcasecmp(s, "center")) - *center = TRUE; - else { - if (s[0] == '-') - *opposite = TRUE; - if (s[0] == '-' || s[0] == '+') - *pos = atoi(s+1); - else - *pos = atoi(s); - } - } - g_free(s); -} - static gpointer setup_func(xmlNodePtr node) { xmlNodePtr n; Options *o; o = g_slice_new0(Options); - o->x = G_MININT; - o->y = G_MININT; + o->x.pos = G_MININT; + o->y.pos = G_MININT; o->w = G_MININT; o->h = G_MININT; o->monitor = CURRENT_MONITOR; if ((n = obt_xml_find_node(node, "x"))) - parse_coord(n, &o->x, &o->xopposite, &o->xcenter); + config_parse_gravity_coord(n, &o->x); if ((n = obt_xml_find_node(node, "y"))) - parse_coord(n, &o->y, &o->yopposite, &o->ycenter); + config_parse_gravity_coord(n, &o->y); if ((n = obt_xml_find_node(node, "width"))) { gchar *s = obt_xml_node_string(n); @@ -155,16 +133,20 @@ static gboolean run_func(ObActionsData *data, gpointer options) w += c->frame->size.left + c->frame->size.right; h += c->frame->size.top + c->frame->size.bottom; - x = o->x; - if (o->xcenter) x = (area->width - w) / 2; + x = o->x.pos; + if (o->x.denom) + x = (x * area->width) / o->x.denom; + if (o->x.center) x = (area->width - w) / 2; else if (x == G_MININT) x = c->frame->area.x - carea->x; - else if (o->xopposite) x = area->width - w - x; + else if (o->x.opposite) x = area->width - w - x; x += area->x; - y = o->y; - if (o->ycenter) y = (area->height - h) / 2; + y = o->y.pos; + if (o->y.denom) + y = (y * area->height) / o->y.denom; + if (o->y.center) y = (area->height - h) / 2; else if (y == G_MININT) y = c->frame->area.y - carea->y; - else if (o->yopposite) y = area->height - h - y; + else if (o->y.opposite) y = area->height - h - y; y += area->y; /* get the client's size back */ @@ -193,12 +175,12 @@ static gpointer setup_center_func(xmlNodePtr node) Options *o; o = g_slice_new0(Options); - o->x = G_MININT; - o->y = G_MININT; + o->x.pos = G_MININT; + o->y.pos = G_MININT; o->w = G_MININT; o->h = G_MININT; o->monitor = -1; - o->xcenter = TRUE; - o->ycenter = TRUE; + o->x.center = TRUE; + o->y.center = TRUE; return o; } diff --git a/openbox/config.c b/openbox/config.c index bf0facd..93cd4af 100644 --- a/openbox/config.c +++ b/openbox/config.c @@ -153,18 +153,29 @@ void config_app_settings_copy_non_defaults(const ObAppSettings *src, } } -static void config_parse_gravity_coord(xmlNodePtr node, GravityCoord *c) +void config_parse_relative_position(gchar *s, GravityCoord *c) +{ + c->pos = strtol(s, &s, 10); + + if (*s == '%') { + c->denom = 100; + } else if (*s == '/') { + c->denom = atoi(s+1); + } +} + +void config_parse_gravity_coord(xmlNodePtr node, GravityCoord *c) { gchar *s = obt_xml_node_string(node); if (!g_ascii_strcasecmp(s, "center")) c->center = TRUE; else { + gchar *ps = s; if (s[0] == '-') c->opposite = TRUE; if (s[0] == '-' || s[0] == '+') - c->pos = atoi(s+1); - else - c->pos = atoi(s); + ps++; + config_parse_relative_position(ps, c); } g_free(s); } diff --git a/openbox/config.h b/openbox/config.h index 818dcc7..2197c4b 100644 --- a/openbox/config.h +++ b/openbox/config.h @@ -212,5 +212,8 @@ ObAppSettings* config_create_app_settings(void); src. */ void config_app_settings_copy_non_defaults(const ObAppSettings *src, ObAppSettings *dest); +/*! Parses an x geometry style position, with some extensions like ratios + and percentages */ +void config_parse_gravity_coord(xmlNodePtr node, GravityCoord *c); #endif diff --git a/openbox/geom.h b/openbox/geom.h index 6a1725e..003b008 100644 --- a/openbox/geom.h +++ b/openbox/geom.h @@ -24,6 +24,7 @@ typedef struct _GravityCoord { gint pos; + gint denom; gboolean center; gboolean opposite; } GravityCoord; diff --git a/openbox/place.c b/openbox/place.c index 836c215..224c15a 100644 --- a/openbox/place.c +++ b/openbox/place.c @@ -406,6 +406,8 @@ static gboolean place_per_app_setting(ObClient *client, gint *x, gint *y, settings->position.x.pos; else *x = screen->x + settings->position.x.pos; + if (settings->position.x.denom) + *x = (*x * screen->width) / settings->position.x.denom; if (settings->position.y.center) *y = screen->y + screen->height / 2 - client->area.height / 2; @@ -414,6 +416,8 @@ static gboolean place_per_app_setting(ObClient *client, gint *x, gint *y, settings->position.y.pos; else *y = screen->y + settings->position.y.pos; + if (settings->position.y.denom) + *y = (*y * screen->height) / settings->position.y.denom; g_slice_free(Rect, screen); return TRUE; -- 1.7.0.2