Select containers above or near the whole snapped width/height

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.
This commit is contained in:
Michael Stapelberg 2010-03-11 00:15:34 +01:00
parent a70f4353b7
commit f7c8e76782
2 changed files with 84 additions and 3 deletions

View File

@ -185,9 +185,26 @@ static void focus_thing(xcb_connection_t *conn, direction_t direction, thing_t t
continue; continue;
new_col = cols; new_col = cols;
DLOG("Fixed it to new col %d\n", new_col);
break; 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); DLOG("Fixed it to new col %d\n", new_col);
break;
}
} }
} else if (direction == D_LEFT || direction == D_RIGHT) { } else if (direction == D_LEFT || direction == D_RIGHT) {
if (direction == D_RIGHT && cell_exists(t_ws, current_col+1, current_row)) 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; continue;
new_row = rows; new_row = rows;
DLOG("Fixed it to new row %d\n", new_row);
break; 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 { } else {
ELOG("direction unhandled\n"); ELOG("direction unhandled\n");
return; return;

View File

@ -4,7 +4,7 @@
# the workspace to be empty). # the workspace to be empty).
# TODO: skip it by default? # TODO: skip it by default?
use Test::More tests => 8; use Test::More tests => 14;
use Test::Deep; use Test::Deep;
use X11::XCB qw(:all); use X11::XCB qw(:all);
use Data::Dumper; use Data::Dumper;
@ -76,4 +76,50 @@ is($focus, $bottom->id, "Bottom window focused (wrapping to the top works)");
$focus = focus_after("j"); $focus = focus_after("j");
is($focus, $top->id, "Top window focused (wrapping to the bottom works)"); 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" ); diag( "Testing i3, Perl $], $^X" );