]> git.sur5r.net Git - i3/i3/commitdiff
Select containers above or near the whole snapped width/height
authorMichael Stapelberg <michael@stapelberg.de>
Wed, 10 Mar 2010 23:15:34 +0000 (00:15 +0100)
committerMichael Stapelberg <michael@stapelberg.de>
Wed, 10 Mar 2010 23:15:34 +0000 (00:15 +0100)
This fixes ticket #100, and is best explained using a little example.
Consider the following layout:

+---+---+
|   | X |
+---+---+
|   X   |
+---+---+

Where X marks a window, so you have an empty container in the upper
left, the container on the bottom is snapped to the right. Before
this commit, nothing would happen when focusing "above". After
this commit, the upper window gets focused.

src/commands.c
testcases/t/06-focus.t

index fd81e65c5b6bbe529a0109f07d33a1ff0457eb83..bef0989fa7e714895fb82373f8d298cbce62c896 100644 (file)
@@ -185,9 +185,26 @@ static void focus_thing(xcb_connection_t *conn, direction_t direction, thing_t t
                                         continue;
 
                                 new_col = cols;
+                                DLOG("Fixed it to new col %d\n", new_col);
+                                break;
+                        }
+                }
+
+                if (t_ws->table[new_col][new_row]->currently_focused == NULL) {
+                        DLOG("Cell still empty, checking for full cols above spanned width...\n");
+                        DLOG("new_col = %d\n", new_col);
+                        DLOG("colspan = %d\n", container->colspan);
+                        for (int cols = new_col;
+                             cols < container->col + container->colspan;
+                             cols += t_ws->table[cols][new_row]->colspan) {
+                                DLOG("candidate: new_row = %d, cols = %d\n", new_row, cols);
+                                if (t_ws->table[cols][new_row]->currently_focused == NULL)
+                                        continue;
+
+                                new_col = cols;
+                                DLOG("Fixed it to new col %d\n", new_col);
                                 break;
                         }
-                        DLOG("Fixed it to new col %d\n", new_col);
                 }
         } else if (direction == D_LEFT || direction == D_RIGHT) {
                 if (direction == D_RIGHT && cell_exists(t_ws, current_col+1, current_row))
@@ -227,10 +244,28 @@ static void focus_thing(xcb_connection_t *conn, direction_t direction, thing_t t
                                         continue;
 
                                 new_row = rows;
+                                DLOG("Fixed it to new row %d\n", new_row);
                                 break;
                         }
-                        DLOG("Fixed it to new row %d\n", new_row);
                 }
+
+                if (t_ws->table[new_col][new_row]->currently_focused == NULL) {
+                        DLOG("Cell still empty, checking for full cols near full spanned height...\n");
+                        DLOG("new_row = %d\n", new_row);
+                        DLOG("rowspan = %d\n", container->rowspan);
+                        for (int rows = new_row;
+                             rows < container->row + container->rowspan;
+                             rows += t_ws->table[new_col][rows]->rowspan) {
+                                DLOG("candidate: new_col = %d, rows = %d\n", new_col, rows);
+                                if (t_ws->table[new_col][rows]->currently_focused == NULL)
+                                        continue;
+
+                                new_row = rows;
+                                DLOG("Fixed it to new col %d\n", new_row);
+                                break;
+                        }
+                }
+
         } else {
                 ELOG("direction unhandled\n");
                 return;
index efdf574908bf3f0c0a493e558454e08867bcf35c..5ca3e062bd801cf258ec7877745ab273301b652c 100644 (file)
@@ -4,7 +4,7 @@
 # the workspace to be empty).
 # TODO: skip it by default?
 
-use Test::More tests => 8;
+use Test::More tests => 14;
 use Test::Deep;
 use X11::XCB qw(:all);
 use Data::Dumper;
@@ -76,4 +76,50 @@ is($focus, $bottom->id, "Bottom window focused (wrapping to the top works)");
 $focus = focus_after("j");
 is($focus, $top->id, "Top window focused (wrapping to the bottom works)");
 
+###############################################
+# Test focus with empty containers and colspan
+###############################################
+
+# Switch to the 10. workspace
+$sock->write(i3test::format_ipc_command("10"));
+sleep 0.25;
+
+$top = i3test::open_standard_window($x);
+$bottom = i3test::open_standard_window($x);
+sleep 0.25;
+
+$focus = focus_after("mj");
+$focus = focus_after("mh");
+$focus = focus_after("k");
+is($focus, $bottom->id, "Selecting top window without snapping doesn't work");
+
+$focus = focus_after("sl");
+is($focus, $bottom->id, "Bottom window focused");
+
+$focus = focus_after("k");
+is($focus, $top->id, "Top window focused");
+
+# Same thing, but left/right instead of top/bottom
+
+# Switch to the 11. workspace
+$sock->write(i3test::format_ipc_command("11"));
+sleep 0.25;
+
+my $left = i3test::open_standard_window($x);
+my $right = i3test::open_standard_window($x);
+sleep 0.25;
+
+$focus = focus_after("ml");
+$focus = focus_after("h");
+$focus = focus_after("mk");
+$focus = focus_after("l");
+is($focus, $left->id, "Selecting right window without snapping doesn't work");
+
+$focus = focus_after("sj");
+is($focus, $left->id, "left window focused");
+
+$focus = focus_after("l");
+is($focus, $right->id, "right window focused");
+
+
 diag( "Testing i3, Perl $], $^X" );