]> git.sur5r.net Git - i3/i3/commitdiff
Bugfix: Correctly handle col-/rowspanned containers when setting focus (Thanks Ned)
authorMichael Stapelberg <michael+x200@stapelberg.de>
Sat, 9 May 2009 17:59:36 +0000 (19:59 +0200)
committerMichael Stapelberg <michael+x200@stapelberg.de>
Sat, 9 May 2009 18:00:20 +0000 (20:00 +0200)
This fixes ticket #34

src/commands.c

index bb8a3a89a90fa153dce931f0523d2df5184eb194..553d347d3083e8dec1416cc9b0cb9f5fc3d909e2 100644 (file)
@@ -77,10 +77,20 @@ static void focus_thing(xcb_connection_t *conn, direction_t direction, thing_t t
                                 return;
 
                 if (direction == D_DOWN && cell_exists(current_col, current_row+1))
-                        new_row++;
-                else if (direction == D_UP && cell_exists(current_col, current_row-1))
+                        new_row = current_row + t_ws->table[current_col][current_row]->rowspan;
+                else if (direction == D_UP && cell_exists(current_col, current_row-1)) {
+                        /* Set new_row as a sane default, but it may get overwritten in a second */
                         new_row--;
-                else {
+
+                        /* Search from the top to correctly handle rowspanned containers */
+                        for (int rows = 0; rows < current_row; rows += t_ws->table[current_col][rows]->rowspan) {
+                                if (new_row > (rows + (t_ws->table[current_col][rows]->rowspan - 1)))
+                                        continue;
+
+                                new_row = rows;
+                                break;
+                        }
+                } else {
                         /* Let’s see if there is a screen down/up there to which we can switch */
                         LOG("container is at %d with height %d\n", container->y, container->height);
                         i3Screen *screen;
@@ -95,10 +105,20 @@ static void focus_thing(xcb_connection_t *conn, direction_t direction, thing_t t
                 }
         } else if (direction == D_LEFT || direction == D_RIGHT) {
                 if (direction == D_RIGHT && cell_exists(current_col+1, current_row))
-                        new_col++;
-                else if (direction == D_LEFT && cell_exists(current_col-1, current_row))
+                        new_col = current_col + t_ws->table[current_col][current_row]->colspan;
+                else if (direction == D_LEFT && cell_exists(current_col-1, current_row)) {
+                        /* Set new_col as a sane default, but it may get overwritten in a second */
                         new_col--;
-                else {
+
+                        /* Search from the left to correctly handle colspanned containers */
+                        for (int cols = 0; cols < current_col; cols += t_ws->table[cols][current_row]->colspan) {
+                                if (new_col > (cols + (t_ws->table[cols][current_row]->colspan - 1)))
+                                        continue;
+
+                                new_col = cols;
+                                break;
+                        }
+                } else {
                         /* Let’s see if there is a screen left/right here to which we can switch */
                         LOG("container is at %d with width %d\n", container->x, container->width);
                         i3Screen *screen;