]> git.sur5r.net Git - i3/i3/commitdiff
Bugfix: Re-distribute free space when closing customly resized containers, re-evaluat...
authorMichael Stapelberg <michael+x200@stapelberg.de>
Sun, 3 May 2009 12:29:58 +0000 (14:29 +0200)
committerMichael Stapelberg <michael+x200@stapelberg.de>
Sun, 3 May 2009 12:29:58 +0000 (14:29 +0200)
This fixes ticket #4

include/layout.h
src/handlers.c
src/layout.c
src/table.c

index 7f930160cdb5227288573383602f91fea97308ed..40df0ad1bee8d6d9e644b6008e4185caea011523 100644 (file)
 #ifndef _LAYOUT_H
 #define _LAYOUT_H
 
+/**
+ * Gets the unoccupied space (= space which is available for windows which were resized by the user)
+ * for the given row. This is necessary to render both, customly resized windows and never touched
+ * windows correctly, meaning that the aspect ratio will be maintained when opening new windows.
+ *
+ */
+int get_unoccupied_x(Workspace *workspace, int row);
+
 /**
  * (Re-)draws window decorations for a given Client onto the given drawable/graphic context.
  * When in stacking mode, the window decorations are drawn onto an own window.
index 150a7516002a138caef3af18a7b24554b664388a..1113b82656a0714ddede36fda7c303b3ee02fc0c 100644 (file)
@@ -468,14 +468,45 @@ int handle_button_press(void *ignored, xcb_connection_t *conn, xcb_button_press_
                         return 1;
                 }
 
+                /* Save the old unoccupied space to re-evaluate the other containers (not first or second) later */
+                int old_unoccupied_x = get_unoccupied_x(ws, first->row);
+
                 /* Convert 0 (for default width_factor) to actual numbers */
                 if (first->width_factor == 0)
                         first->width_factor = ((float)ws->rect.width / ws->cols) / ws->rect.width;
+                else first->width_factor = ((first->width_factor * old_unoccupied_x) / ws->rect.width);
+
                 if (second->width_factor == 0)
                         second->width_factor = ((float)ws->rect.width / ws->cols) / ws->rect.width;
+                else second->width_factor = ((second->width_factor * old_unoccupied_x) / ws->rect.width);
+
+                LOG("\n\n\n");
+
+                LOG("old_unoccupied_x = %d\n", old_unoccupied_x);
+
+                LOG("Old first->width_factor = %f\n", first->width_factor);
+                LOG("Old second->width_factor = %f\n", second->width_factor);
 
                 first->width_factor *= (float)(first->width + (new_position - event->root_x)) / first->width;
                 second->width_factor *= (float)(second->width - (new_position - event->root_x)) / second->width;
+
+                LOG("new unoccupied_x = %d\n", get_unoccupied_x(ws, first->row));
+                LOG("old_unoccupied_x = %d\n", old_unoccupied_x);
+
+                for (int col = 0; col < ws->cols; col++) {
+                        Container *con = ws->table[col][first->row];
+                        if (con == first || con == second)
+                                continue;
+
+                        LOG("Updating other container (current width_factor = %f)\n", con->width_factor);
+                        con->width_factor = ((con->width_factor * old_unoccupied_x) / get_unoccupied_x(ws, first->row));
+                        LOG("to %f\n", con->width_factor);
+                }
+
+                LOG("New first->width_factor = %f\n", first->width_factor);
+                LOG("New second->width_factor = %f\n", second->width_factor);
+
+                LOG("\n\n\n");
         } else {
                 LOG("Resize was from Y = %d to Y = %d\n", event->root_y, new_position);
                 if (event->root_y == new_position) {
index 4c18989f0882cb516e90a20f0ba74d9cb1df172b..033e2a4ce85aa0581c3b5c2798ca1022da93bcce 100644 (file)
@@ -51,13 +51,13 @@ int get_unoccupied_x(Workspace *workspace, int row) {
         for (int cols = 0; cols < workspace->cols;) {
                 Container *con = workspace->table[cols][row];
                 LOG("width_factor[%d][%d] = %f, colspan = %d\n", cols, row, con->width_factor, con->colspan);
-                if (con->width_factor == 0)
+                if (con->width_factor == 0) {
+                        LOG("- %d * %f * %d = %f\n", workspace->rect.width, default_factor, con->colspan, workspace->rect.width * default_factor * con->colspan);
                         unoccupied -= workspace->rect.width * default_factor * con->colspan;
+                }
                 cols += con->colspan;
         }
 
-        assert(unoccupied != 0);
-
         LOG("unoccupied space: %d\n", unoccupied);
         return unoccupied;
 }
@@ -77,8 +77,6 @@ int get_unoccupied_y(Workspace *workspace, int col) {
                 rows += con->rowspan;
         }
 
-        assert(unoccupied != 0);
-
         LOG("unoccupied space: %d\n", unoccupied);
         return unoccupied;
 }
index 491d3bc85a25524d49bd3c6d301512eae9e35272..27c4af47c302214823440fbb732af52f9a48703a 100644 (file)
@@ -171,6 +171,25 @@ static void free_container(xcb_connection_t *conn, Workspace *workspace, int col
         if (old_container->mode == MODE_STACK)
                 leave_stack_mode(conn, old_container);
 
+        /* We need to distribute the space which will now be freed to other containers */
+        if (old_container->width_factor > 0) {
+                Container *dest_container = NULL;
+                /* Check if we got a container to the left… */
+                if (col > 0)
+                        dest_container = workspace->table[col-1][row];
+                /* …or to the right */
+                else if ((col+1) < workspace->cols)
+                        dest_container = workspace->table[col+1][row];
+
+                if (dest_container != NULL) {
+                        if (dest_container->width_factor == 0)
+                                dest_container->width_factor = ((float)workspace->rect.width / workspace->cols) / workspace->rect.width;
+                        LOG("dest_container->width_factor = %f\n", dest_container->width_factor);
+                        dest_container->width_factor += old_container->width_factor;
+                        LOG("afterwards it's %f\n", dest_container->width_factor);
+                }
+        }
+
         free(old_container);
 }