Created a 'GrowToFill' action. (Bug 3356)
authorLucas Augusto Deters <deters@inf.ufsc.br>
Sat, 28 Aug 2010 05:21:18 +0000 (02:21 -0300)
committerDana Jansens <danakj@orodu.net>
Mon, 2 Sep 2013 18:10:37 +0000 (14:10 -0400)
openbox/actions/growtoedge.c

index d5a7bfd..940792f 100644 (file)
@@ -8,6 +8,7 @@
 typedef struct {
     ObDirection dir;
     gboolean shrink;
 typedef struct {
     ObDirection dir;
     gboolean shrink;
+    gboolean fill;
 } Options;
 
 static gpointer setup_func(xmlNodePtr node);
 } Options;
 
 static gpointer setup_func(xmlNodePtr node);
@@ -19,6 +20,7 @@ static gpointer setup_north_func(xmlNodePtr node);
 static gpointer setup_south_func(xmlNodePtr node);
 static gpointer setup_east_func(xmlNodePtr node);
 static gpointer setup_west_func(xmlNodePtr node);
 static gpointer setup_south_func(xmlNodePtr node);
 static gpointer setup_east_func(xmlNodePtr node);
 static gpointer setup_west_func(xmlNodePtr node);
+static gpointer setup_fill_func(xmlNodePtr node);
 
 void action_growtoedge_startup(void)
 {
 
 void action_growtoedge_startup(void)
 {
@@ -31,6 +33,7 @@ void action_growtoedge_startup(void)
     actions_register("GrowToEdgeSouth", setup_south_func, free_func, run_func);
     actions_register("GrowToEdgeEast", setup_east_func, free_func, run_func);
     actions_register("GrowToEdgeWest", setup_west_func, free_func, run_func);
     actions_register("GrowToEdgeSouth", setup_south_func, free_func, run_func);
     actions_register("GrowToEdgeEast", setup_east_func, free_func, run_func);
     actions_register("GrowToEdgeWest", setup_west_func, free_func, run_func);
+    actions_register("GrowToFill", setup_fill_func, free_func, run_func);
 }
 
 static gpointer setup_func(xmlNodePtr node)
 }
 
 static gpointer setup_func(xmlNodePtr node)
@@ -41,6 +44,7 @@ static gpointer setup_func(xmlNodePtr node)
     o = g_slice_new0(Options);
     o->dir = OB_DIRECTION_NORTH;
     o->shrink = FALSE;
     o = g_slice_new0(Options);
     o->dir = OB_DIRECTION_NORTH;
     o->shrink = FALSE;
+    o->fill = FALSE;
 
     if ((n = obt_xml_find_node(node, "direction"))) {
         gchar *s = obt_xml_node_string(n);
 
     if ((n = obt_xml_find_node(node, "direction"))) {
         gchar *s = obt_xml_node_string(n);
@@ -62,6 +66,17 @@ static gpointer setup_func(xmlNodePtr node)
     return o;
 }
 
     return o;
 }
 
+static gpointer setup_fill_func(xmlNodePtr node)
+{
+    Options *o;
+
+    o = setup_func(node);
+    o->fill = TRUE;
+
+    return o;
+}
+
+
 static gpointer setup_shrink_func(xmlNodePtr node)
 {
     Options *o;
 static gpointer setup_shrink_func(xmlNodePtr node)
 {
     Options *o;
@@ -107,26 +122,107 @@ static gboolean run_func(ObActionsData *data, gpointer options)
 {
     Options *o = options;
     gint x, y, w, h;
 {
     Options *o = options;
     gint x, y, w, h;
+
     ObDirection opp;
     gint half;
 
     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))
-    {
+    if (!data->client)
+        return FALSE;
+    if (data->client->shaded) {
+        gboolean doing_verical_resize =
+            o->dir == OB_DIRECTION_NORTH ||
+            o->dir == OB_DIRECTION_SOUTH ||
+            o->fill;
+        if (doing_verical_resize)
+            return FALSE;
+    }
+
+    if (o->fill) {
+        if (o->shrink) {
+            /* We don't have any implementation of shrinking for the FillToGrow
+               action. */
+            return FALSE;
+        }
+
+        gint head, size;
+        gint e_start, e_size;
+        gboolean near;
+
+        gint north_edge;
+        head = RECT_TOP(data->client->frame->area)+1;
+        size = data->client->frame->area.height;
+        e_start = RECT_LEFT(data->client->frame->area);
+        e_size = data->client->frame->area.width;
+
+        client_find_edge_directional(data->client, OB_DIRECTION_NORTH,
+                                     head, size, e_start, e_size,
+                                     &north_edge, &near);
+
+        gint south_edge;
+        head = RECT_BOTTOM(data->client->frame->area)-1;
+        size = data->client->frame->area.height;
+        e_start = RECT_LEFT(data->client->frame->area);
+        e_size = data->client->frame->area.width;
+
+        client_find_edge_directional(data->client, OB_DIRECTION_SOUTH,
+                                     head, size, e_start, e_size,
+                                     &south_edge, &near);
+
+        gint east_edge;
+        head = RECT_RIGHT(data->client->frame->area)-1;
+        size = data->client->frame->area.width;
+        e_start = RECT_TOP(data->client->frame->area);
+        e_size = data->client->frame->area.height;
+
+        client_find_edge_directional(data->client, OB_DIRECTION_EAST,
+                                     head, size, e_start, e_size,
+                                     &east_edge, &near);
+
+        gint west_edge;
+        head = RECT_LEFT(data->client->frame->area)+1;
+        size = data->client->frame->area.width;
+        e_start = RECT_TOP(data->client->frame->area);
+        e_size = data->client->frame->area.height;
+
+        client_find_edge_directional(data->client, OB_DIRECTION_WEST,
+                                     head, size, e_start, e_size,
+                                     &west_edge, &near);
+
+        /* Calculate the client pos and size, based on frame pos and size.
+         */
+
+        gint w_client_delta =
+            data->client->frame->area.width - data->client->area.width;
+        gint h_client_delta =
+            data->client->frame->area.height - data->client->area.height;
+
+        gint x_client_delta =
+            data->client->area.x - data->client->frame->area.x;
+        gint y_client_delta =
+            data->client->area.y - data->client->frame->area.y;
+
+        x = west_edge + x_client_delta + 1;
+        y = north_edge + y_client_delta + 1;
+
+        w = east_edge - west_edge - w_client_delta - 1;
+        h = south_edge - north_edge - h_client_delta - 1;
+
+        /* grow passing client pos and size */
+
+        do_grow(data, x, y, w, h);
         return FALSE;
     }
 
     if (!o->shrink) {
         return FALSE;
     }
 
     if (!o->shrink) {
-        /* try grow */
+        /* Try grow. */
         client_find_resize_directional(data->client, o->dir, TRUE,
                                        &x, &y, &w, &h);
         client_find_resize_directional(data->client, o->dir, TRUE,
                                        &x, &y, &w, &h);
+
         if (do_grow(data, x, y, w, h))
             return FALSE;
     }
 
         if (do_grow(data, x, y, w, h))
             return FALSE;
     }
 
-    /* we couldn't grow, so try shrink! */
+    /* 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 :
     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 :