From 6a1c34d2c584271d26f4dcc214798421c097a1ac Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Mon, 10 May 2010 09:33:10 +0200 Subject: [PATCH] Implement 'split' --- src/cmdparse.l | 1 + src/cmdparse.y | 10 +++++++ src/tree.c | 5 ++++ testcases/Makefile | 2 +- testcases/t/21-next-prev.t | 6 ---- testcases/t/22-split.t | 58 ++++++++++++++++++++++++++++++++++++++ testcases/t/lib/i3test.pm | 12 +++++++- 7 files changed, 86 insertions(+), 8 deletions(-) create mode 100644 testcases/t/22-split.t diff --git a/src/cmdparse.l b/src/cmdparse.l index ee73c7b9..4a8e01fc 100644 --- a/src/cmdparse.l +++ b/src/cmdparse.l @@ -101,6 +101,7 @@ move { return TOK_MOVE; } open { return TOK_OPEN; } next { return TOK_NEXT; } prev { return TOK_PREV; } +split { return TOK_SPLIT; } horizontal { return TOK_HORIZONTAL; } vertical { return TOK_VERTICAL; } diff --git a/src/cmdparse.y b/src/cmdparse.y index d77fa4ca..abb30ebe 100644 --- a/src/cmdparse.y +++ b/src/cmdparse.y @@ -113,6 +113,7 @@ void parse_cmd(const char *new) { %token TOK_OPEN "open" %token TOK_NEXT "next" %token TOK_PREV "prev" +%token TOK_SPLIT "split" %token TOK_HORIZONTAL "horizontal" %token TOK_VERTICAL "vertical" @@ -256,6 +257,7 @@ operation: | fullscreen | next | prev + | split ; exec: @@ -357,6 +359,14 @@ prev: } ; +split: + TOK_SPLIT WHITESPACE direction + { + printf("splitting in direction %c\n", $3); + tree_split(focused, ($3 == 'v' ? VERT : HORIZ)); + } + ; + direction: TOK_HORIZONTAL { $$ = 'h'; } | 'h' { $$ = 'h'; } diff --git a/src/tree.c b/src/tree.c index 3a657983..72e8645c 100644 --- a/src/tree.c +++ b/src/tree.c @@ -167,6 +167,11 @@ void tree_close_con() { * */ void tree_split(Con *con, orientation_t orientation) { + /* for a workspace, we just need to change orientation */ + if (con->parent->type == CT_OUTPUT) { + con->orientation = orientation; + return; + } /* 2: replace it with a new Con */ Con *new = con_new(NULL); Con *parent = con->parent; diff --git a/testcases/Makefile b/testcases/Makefile index f433546f..9741c24c 100644 --- a/testcases/Makefile +++ b/testcases/Makefile @@ -1,5 +1,5 @@ test: - PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(1)" -It/lib t/21* + PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(1)" -It/lib t/22* all: test diff --git a/testcases/t/21-next-prev.t b/testcases/t/21-next-prev.t index 8ed3ada7..bc0e6025 100644 --- a/testcases/t/21-next-prev.t +++ b/testcases/t/21-next-prev.t @@ -81,10 +81,4 @@ $i3->command('next horizontal')->recv; ($nodes, $focus) = get_ws_content($tmp); is($focus->[0], $right, 'right container focused'); - -# -# TODO: extend this test-case (as soon as splitting is implemented): -# - wrapping (no horizontal switch possible, goes level-up) -# - going level-up "manually" - diag( "Testing i3, Perl $], $^X" ); diff --git a/testcases/t/22-split.t b/testcases/t/22-split.t new file mode 100644 index 00000000..95e387d1 --- /dev/null +++ b/testcases/t/22-split.t @@ -0,0 +1,58 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Tests splitting +# +use i3test tests => 11; +use X11::XCB qw(:all); +use v5.10; + +my $i3 = i3("/tmp/nestedcons"); + +my $tmp = get_unused_workspace(); +$i3->command("workspace $tmp")->recv; + +my $ws = get_ws($tmp); +is($ws->{orientation}, 0, 'orientation horizontal by default'); +$i3->command('split v')->recv; +$ws = get_ws($tmp); +is($ws->{orientation}, 1, 'split v changes workspace orientation'); + +###################################################################### +# Open two containers, split, open another container. Then verify +# the layout is like we expect it to be +###################################################################### +$i3->command('open')->recv; +$i3->command('open')->recv; +my $content = get_ws_content($tmp); + +is(@{$content}, 2, 'two containers on workspace level'); +my $first = $content->[0]; +my $second = $content->[1]; + +is(@{$first->{nodes}}, 0, 'first container has no children'); +is(@{$second->{nodes}}, 0, 'second container has no children (yet)'); +my $old_name = $second->{name}; + + +$i3->command('split h')->recv; +$i3->command('open')->recv; + +$content = get_ws_content($tmp); + +is(@{$content}, 2, 'two containers on workspace level'); +$first = $content->[0]; +$second = $content->[1]; + +is(@{$first->{nodes}}, 0, 'first container has no children'); +isnt($second->{name}, $old_name, 'second container was replaced'); +is($second->{orientation}, 0, 'orientation is horizontal'); +is(@{$second->{nodes}}, 2, 'second container has 2 children'); +is($second->{nodes}->[0]->{name}, $old_name, 'found old second container'); + +# TODO: extend this test-case (test next/prev) +# - wrapping (no horizontal switch possible, goes level-up) +# - going level-up "manually" + + +diag( "Testing i3, Perl $], $^X" ); diff --git a/testcases/t/lib/i3test.pm b/testcases/t/lib/i3test.pm index 5ca84231..4b76b7f4 100644 --- a/testcases/t/lib/i3test.pm +++ b/testcases/t/lib/i3test.pm @@ -19,7 +19,7 @@ use AnyEvent::I3; #use Exporter qw(import); use base 'Exporter'; -our @EXPORT = qw(get_workspace_names get_unused_workspace get_ws_content); +our @EXPORT = qw(get_workspace_names get_unused_workspace get_ws_content get_ws); BEGIN { my $window_count = 0; @@ -76,4 +76,14 @@ sub get_ws_content { return wantarray ? ($cons[0]->{nodes}, $cons[0]->{focus}) : $cons[0]->{nodes}; } +sub get_ws { + my ($name) = @_; + my $i3 = i3("/tmp/nestedcons"); + my $tree = $i3->get_workspaces->recv; + my @ws = map { @{$_->{nodes}} } @{$tree->{nodes}}; + my @cons = grep { $_->{name} eq $name } @ws; + return $cons[0]; +} + + 1