]> git.sur5r.net Git - i3/i3/commitdiff
Implement automatic cleaning of the table
authorMichael Stapelberg <michael+git@stapelberg.de>
Tue, 24 Feb 2009 19:29:30 +0000 (20:29 +0100)
committerMichael Stapelberg <michael+git@stapelberg.de>
Tue, 24 Feb 2009 19:29:30 +0000 (20:29 +0100)
include/table.h
src/commands.c
src/table.c

index a57b392fe1d50ffceead702316fc42bd63a0f07a..24605b72f0d6727551c8762bb74951f29560b645 100644 (file)
@@ -27,5 +27,6 @@ void init_table();
 void expand_table_rows(Workspace *workspace);
 void expand_table_cols(Workspace *workspace);
 bool cell_exists(int col, int row);
+void cleanup_table(Workspace *workspace);
 
 #endif
index 930696eeeba85e2634526bb02094251a0526cf61..e05c0af506fe43bed3192c513eea4d9b79f90156 100644 (file)
@@ -175,7 +175,8 @@ static void move_current_window(xcb_connection_t *connection, direction_t direct
         container->currently_focused = to_focus;
         new->currently_focused = current_client;
 
-        /* TODO: delete all empty columns/rows */
+        /* delete all empty columns/rows */
+        cleanup_table(container->workspace);
         render_layout(connection);
 
         set_focus(connection, current_client);
index 763163718c8cbb5a2e3c9afd79178cdd87677d08..76e99bd8c2855730f2f96c0e5917a548daf2e7f5 100644 (file)
@@ -80,11 +80,84 @@ void expand_table_cols(Workspace *workspace) {
                 new_container(workspace, &(workspace->table[workspace->cols-1][c]));
 }
 
+static void shrink_table_cols(Workspace *workspace) {
+        workspace->cols--;
+        free(workspace->table[workspace->cols]);
+        workspace->table = realloc(workspace->table, sizeof(Container**) * workspace->cols);
+}
+
+static void shrink_table_rows(Workspace *workspace) {
+        workspace->rows--;
+        for (int cols = 0; cols < workspace->cols; cols++)
+                workspace->table[cols] = realloc(workspace->table[cols], sizeof(Container*) * workspace->rows);
+}
+
+
 /*
  * Performs simple bounds checking for the given column/row
  *
  */
 bool cell_exists(int col, int row) {
         return (col >= 0 && col < c_ws->cols) &&
-                (row >= 0 && row < c_ws->rows);
+               (row >= 0 && row < c_ws->rows);
+}
+
+static void move_columns_from(Workspace *workspace, int cols) {
+        for (; cols < workspace->cols; cols++)
+                for (int rows = 0; rows < workspace->rows; rows++) {
+                        free(workspace->table[cols-1][rows]);
+
+                        printf("moving cols = %d to cols -1 = %d\n", cols, cols-1);
+                        workspace->table[cols-1][rows] = workspace->table[cols][rows];
+                        workspace->table[cols][rows] = NULL;
+                }
+}
+
+static void move_rows_from(Workspace *workspace, int rows) {
+        for (; rows < workspace->rows; rows++)
+                for (int cols = 0; cols < workspace->cols; cols++) {
+                        free(workspace->table[cols][rows-1]);
+
+                        printf("moving rows = %d to rows -1 = %d\n", rows, rows - 1);
+                        workspace->table[cols][rows-1] = workspace->table[cols][rows];
+                        workspace->table[cols][rows] = NULL;
+                }
+}
+
+/*
+ * Shrinks the table by "compacting" it, that is, removing completely empty rows/columns
+ *
+ */
+void cleanup_table(Workspace *workspace) {
+        /* Check for empty columns */
+        for (int cols = 0; cols < workspace->cols;) {
+                bool completely_empty = true;
+                for (int rows = 0; rows < workspace->rows; rows++)
+                        if (workspace->table[cols][rows]->currently_focused != NULL) {
+                                completely_empty = false;
+                                break;
+                        }
+                if (completely_empty && cols > 0) {
+                        printf("Removing completely empty column %d\n", cols);
+                        if (cols < (workspace->cols - 1))
+                                move_columns_from(workspace, cols+1);
+                        shrink_table_cols(workspace);
+                } else cols++;
+        }
+
+        /* Check for empty rows */
+        for (int rows = 0; rows < workspace->rows;) {
+                bool completely_empty = true;
+                for (int cols = 0; cols < workspace->cols; cols++)
+                        if (workspace->table[cols][rows]->currently_focused != NULL) {
+                                completely_empty = false;
+                                break;
+                        }
+                if (completely_empty && rows > 0) {
+                        printf("Removing completely empty row %d\n", rows);
+                        if (rows < (workspace->rows - 1))
+                                move_rows_from(workspace, rows+1);
+                        shrink_table_rows(workspace);
+                } else rows++;
+        }
 }