From f7c8e767822b209ab4ae995a128e217768d51a4d Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Thu, 11 Mar 2010 00:15:34 +0100 Subject: [PATCH] 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. --- src/commands.c | 39 ++++++++++++++++++++++++++++++++-- testcases/t/06-focus.t | 48 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 3 deletions(-) diff --git a/src/commands.c b/src/commands.c index fd81e65c..bef0989f 100644 --- a/src/commands.c +++ b/src/commands.c @@ -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; diff --git a/testcases/t/06-focus.t b/testcases/t/06-focus.t index efdf5749..5ca3e062 100644 --- a/testcases/t/06-focus.t +++ b/testcases/t/06-focus.t @@ -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" ); -- 2.39.5