2010-05-10 09:33:10 +02:00
|
|
|
|
#!perl
|
|
|
|
|
# vim:ts=4:sw=4:expandtab
|
|
|
|
|
#
|
2012-09-10 14:09:01 +02:00
|
|
|
|
# Please read the following documents before working on tests:
|
2017-09-24 10:19:50 +02:00
|
|
|
|
# • https://build.i3wm.org/docs/testsuite.html
|
2012-09-10 14:09:01 +02:00
|
|
|
|
# (or docs/testsuite)
|
|
|
|
|
#
|
2017-09-24 10:19:50 +02:00
|
|
|
|
# • https://build.i3wm.org/docs/lib-i3test.html
|
2012-09-10 14:09:01 +02:00
|
|
|
|
# (alternatively: perldoc ./testcases/lib/i3test.pm)
|
|
|
|
|
#
|
2017-09-24 10:19:50 +02:00
|
|
|
|
# • https://build.i3wm.org/docs/ipc.html
|
2012-09-10 14:09:01 +02:00
|
|
|
|
# (or docs/ipc)
|
|
|
|
|
#
|
|
|
|
|
# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
|
|
|
|
|
# (unless you are already familiar with Perl)
|
|
|
|
|
#
|
2010-05-10 09:33:10 +02:00
|
|
|
|
# Tests splitting
|
|
|
|
|
#
|
2011-03-09 20:25:17 +01:00
|
|
|
|
use i3test;
|
con_set_layout: always use the parent container, handle workspaces properly
Previously, in case 'layout stacked' (for example) had been called
interactively, con_set_layout would be called with focused->parent,
while with for_window, it’d be called on the actual matching container.
This difference in behavior was the cause for the inability to use
'for_window [class="XTerm"] layout tabbed', which now works \o/, but
more on that below.
The change also allows us to handle the case of the user selecting a
CT_WORKSPACE container properly, that is, by using the special case and
creating a new split container on the workspace which gets all the
contents, but a new layout.
Now, before you are enthusiastic about the change and try to use
for_window magic in your config file, keep in mind: The 'layout' command
acts on the parent split container. That is, when using a line such as
this one:
for_window [class="XTerm"] layout tabbed
…and opening an XTerm when on a workspace with one single other window,
the whole workspace will be set tabbed (just as previously when you
opened an XTerm and sent 'layout tabbed' manually).
Therefore, to open XTerm in its own tabbed split container, you need to
split before:
for_window [class="XTerm"] split v, layout tabbed
The comma here is important! It says that the second command should not
be treated as an entirely unrelated command, but it should also relate
the matching window (while it does work with a ';', that is prone to
race-conditions and should be avoided).
fixes #358
2012-09-05 00:22:38 +02:00
|
|
|
|
use List::Util qw(first);
|
2010-05-10 09:33:10 +02:00
|
|
|
|
|
2012-06-10 17:56:28 +02:00
|
|
|
|
my $tmp;
|
|
|
|
|
my $ws;
|
2010-05-10 09:33:10 +02:00
|
|
|
|
|
2012-06-10 17:56:28 +02:00
|
|
|
|
################################################################################
|
2010-05-10 09:33:10 +02:00
|
|
|
|
# Open two containers, split, open another container. Then verify
|
|
|
|
|
# the layout is like we expect it to be
|
2012-06-10 17:56:28 +02:00
|
|
|
|
################################################################################
|
2010-05-10 09:33:10 +02:00
|
|
|
|
|
2012-06-10 17:56:28 +02:00
|
|
|
|
sub verify_split_layout {
|
|
|
|
|
my (%args) = @_;
|
2010-05-10 09:33:10 +02:00
|
|
|
|
|
2012-06-10 17:56:28 +02:00
|
|
|
|
$tmp = fresh_workspace;
|
2010-05-10 09:33:10 +02:00
|
|
|
|
|
2012-06-10 17:56:28 +02:00
|
|
|
|
$ws = get_ws($tmp);
|
Introduce splith/splitv layouts, remove orientation
With this commit, the "default" layout is replaced by the splith and
splitv layouts. splith is equivalent to default with orientation
horizontal and splitv is equivalent to default with orientation
vertical.
The "split h" and "split v" commands continue to work as before, they
split the current container and you will end up in a split container
with layout splith (after "split h") or splitv (after "split v").
To change a splith container into a splitv container, use either "layout
splitv" or "layout toggle split". The latter command is used in the
default config as mod+l (previously "layout default"). In case you have
"layout default" in your config file, it is recommended to just replace
it by "layout toggle split", which will work as "layout default" did
before when pressing it once, but toggle between horizontal/vertical
when pressing it repeatedly.
The rationale behind this commit is that it’s cleaner to have all
parameters that influence how windows are rendered in the layout itself
rather than having a special parameter in combination with only one
layout. This enables us to change existing split containers in all cases
without breaking existing features (see ticket #464). Also, users should
feel more confident about whether they are actually splitting or just
changing an existing split container now.
As a nice side-effect, this commit brings back the "layout toggle"
feature we once had in i3 version 3 (see the userguide).
AFAIK, it is safe to use in-place restart to upgrade into versions
after this commit (switching to an older version will break your layout,
though).
Fixes #464
2012-08-04 03:04:00 +02:00
|
|
|
|
is($ws->{layout}, 'splith', 'orientation horizontal by default');
|
2012-06-10 17:56:28 +02:00
|
|
|
|
cmd 'split v';
|
|
|
|
|
$ws = get_ws($tmp);
|
Introduce splith/splitv layouts, remove orientation
With this commit, the "default" layout is replaced by the splith and
splitv layouts. splith is equivalent to default with orientation
horizontal and splitv is equivalent to default with orientation
vertical.
The "split h" and "split v" commands continue to work as before, they
split the current container and you will end up in a split container
with layout splith (after "split h") or splitv (after "split v").
To change a splith container into a splitv container, use either "layout
splitv" or "layout toggle split". The latter command is used in the
default config as mod+l (previously "layout default"). In case you have
"layout default" in your config file, it is recommended to just replace
it by "layout toggle split", which will work as "layout default" did
before when pressing it once, but toggle between horizontal/vertical
when pressing it repeatedly.
The rationale behind this commit is that it’s cleaner to have all
parameters that influence how windows are rendered in the layout itself
rather than having a special parameter in combination with only one
layout. This enables us to change existing split containers in all cases
without breaking existing features (see ticket #464). Also, users should
feel more confident about whether they are actually splitting or just
changing an existing split container now.
As a nice side-effect, this commit brings back the "layout toggle"
feature we once had in i3 version 3 (see the userguide).
AFAIK, it is safe to use in-place restart to upgrade into versions
after this commit (switching to an older version will break your layout,
though).
Fixes #464
2012-08-04 03:04:00 +02:00
|
|
|
|
is($ws->{layout}, 'splitv', 'split v changes workspace orientation');
|
2010-05-10 09:33:10 +02:00
|
|
|
|
|
2012-06-10 17:56:28 +02:00
|
|
|
|
cmd 'open';
|
|
|
|
|
cmd 'open';
|
|
|
|
|
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)');
|
2014-07-15 10:35:52 +02:00
|
|
|
|
my $old_id = $second->{id};
|
2010-05-10 09:33:10 +02:00
|
|
|
|
|
2012-06-10 17:56:28 +02:00
|
|
|
|
cmd $args{split_command};
|
|
|
|
|
cmd 'open';
|
2010-05-10 09:33:10 +02:00
|
|
|
|
|
2012-06-10 17:56:28 +02:00
|
|
|
|
$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');
|
2014-07-15 10:35:52 +02:00
|
|
|
|
isnt($second->{id}, $old_id, 'second container was replaced');
|
Introduce splith/splitv layouts, remove orientation
With this commit, the "default" layout is replaced by the splith and
splitv layouts. splith is equivalent to default with orientation
horizontal and splitv is equivalent to default with orientation
vertical.
The "split h" and "split v" commands continue to work as before, they
split the current container and you will end up in a split container
with layout splith (after "split h") or splitv (after "split v").
To change a splith container into a splitv container, use either "layout
splitv" or "layout toggle split". The latter command is used in the
default config as mod+l (previously "layout default"). In case you have
"layout default" in your config file, it is recommended to just replace
it by "layout toggle split", which will work as "layout default" did
before when pressing it once, but toggle between horizontal/vertical
when pressing it repeatedly.
The rationale behind this commit is that it’s cleaner to have all
parameters that influence how windows are rendered in the layout itself
rather than having a special parameter in combination with only one
layout. This enables us to change existing split containers in all cases
without breaking existing features (see ticket #464). Also, users should
feel more confident about whether they are actually splitting or just
changing an existing split container now.
As a nice side-effect, this commit brings back the "layout toggle"
feature we once had in i3 version 3 (see the userguide).
AFAIK, it is safe to use in-place restart to upgrade into versions
after this commit (switching to an older version will break your layout,
though).
Fixes #464
2012-08-04 03:04:00 +02:00
|
|
|
|
is($second->{layout}, 'splith', 'orientation is horizontal');
|
2012-06-10 17:56:28 +02:00
|
|
|
|
is(@{$second->{nodes}}, 2, 'second container has 2 children');
|
2014-07-15 10:35:52 +02:00
|
|
|
|
is($second->{nodes}->[0]->{id}, $old_id, 'found old second container');
|
2012-06-10 17:56:28 +02:00
|
|
|
|
}
|
2010-05-10 09:33:10 +02:00
|
|
|
|
|
2012-06-10 17:56:28 +02:00
|
|
|
|
verify_split_layout(split_command => 'split h');
|
|
|
|
|
verify_split_layout(split_command => 'split horizontal');
|
2010-05-10 09:33:10 +02:00
|
|
|
|
|
|
|
|
|
# TODO: extend this test-case (test next/prev)
|
|
|
|
|
# - wrapping (no horizontal switch possible, goes level-up)
|
|
|
|
|
# - going level-up "manually"
|
|
|
|
|
|
2010-06-01 22:29:19 +02:00
|
|
|
|
######################################################################
|
|
|
|
|
# Test splitting multiple times without actually creating windows
|
|
|
|
|
######################################################################
|
|
|
|
|
|
2011-03-09 20:25:17 +01:00
|
|
|
|
$tmp = fresh_workspace;
|
2010-06-01 22:29:19 +02:00
|
|
|
|
|
|
|
|
|
$ws = get_ws($tmp);
|
Introduce splith/splitv layouts, remove orientation
With this commit, the "default" layout is replaced by the splith and
splitv layouts. splith is equivalent to default with orientation
horizontal and splitv is equivalent to default with orientation
vertical.
The "split h" and "split v" commands continue to work as before, they
split the current container and you will end up in a split container
with layout splith (after "split h") or splitv (after "split v").
To change a splith container into a splitv container, use either "layout
splitv" or "layout toggle split". The latter command is used in the
default config as mod+l (previously "layout default"). In case you have
"layout default" in your config file, it is recommended to just replace
it by "layout toggle split", which will work as "layout default" did
before when pressing it once, but toggle between horizontal/vertical
when pressing it repeatedly.
The rationale behind this commit is that it’s cleaner to have all
parameters that influence how windows are rendered in the layout itself
rather than having a special parameter in combination with only one
layout. This enables us to change existing split containers in all cases
without breaking existing features (see ticket #464). Also, users should
feel more confident about whether they are actually splitting or just
changing an existing split container now.
As a nice side-effect, this commit brings back the "layout toggle"
feature we once had in i3 version 3 (see the userguide).
AFAIK, it is safe to use in-place restart to upgrade into versions
after this commit (switching to an older version will break your layout,
though).
Fixes #464
2012-08-04 03:04:00 +02:00
|
|
|
|
is($ws->{layout}, 'splith', 'orientation horizontal by default');
|
2011-03-09 20:25:17 +01:00
|
|
|
|
cmd 'split v';
|
2010-06-01 22:29:19 +02:00
|
|
|
|
$ws = get_ws($tmp);
|
Introduce splith/splitv layouts, remove orientation
With this commit, the "default" layout is replaced by the splith and
splitv layouts. splith is equivalent to default with orientation
horizontal and splitv is equivalent to default with orientation
vertical.
The "split h" and "split v" commands continue to work as before, they
split the current container and you will end up in a split container
with layout splith (after "split h") or splitv (after "split v").
To change a splith container into a splitv container, use either "layout
splitv" or "layout toggle split". The latter command is used in the
default config as mod+l (previously "layout default"). In case you have
"layout default" in your config file, it is recommended to just replace
it by "layout toggle split", which will work as "layout default" did
before when pressing it once, but toggle between horizontal/vertical
when pressing it repeatedly.
The rationale behind this commit is that it’s cleaner to have all
parameters that influence how windows are rendered in the layout itself
rather than having a special parameter in combination with only one
layout. This enables us to change existing split containers in all cases
without breaking existing features (see ticket #464). Also, users should
feel more confident about whether they are actually splitting or just
changing an existing split container now.
As a nice side-effect, this commit brings back the "layout toggle"
feature we once had in i3 version 3 (see the userguide).
AFAIK, it is safe to use in-place restart to upgrade into versions
after this commit (switching to an older version will break your layout,
though).
Fixes #464
2012-08-04 03:04:00 +02:00
|
|
|
|
is($ws->{layout}, 'splitv', 'split v changes workspace orientation');
|
2010-06-01 22:29:19 +02:00
|
|
|
|
|
2011-03-09 20:25:17 +01:00
|
|
|
|
cmd 'open';
|
2010-06-01 22:29:19 +02:00
|
|
|
|
my @content = @{get_ws_content($tmp)};
|
|
|
|
|
|
|
|
|
|
# recursively sums up all nodes and their children
|
|
|
|
|
sub sum_nodes {
|
|
|
|
|
my ($nodes) = @_;
|
|
|
|
|
|
|
|
|
|
return 0 if !@{$nodes};
|
|
|
|
|
|
|
|
|
|
my @children = (map { @{$_->{nodes}} } @{$nodes},
|
2010-11-21 16:34:45 +01:00
|
|
|
|
map { @{$_->{'floating_nodes'}} } @{$nodes});
|
2010-06-01 22:29:19 +02:00
|
|
|
|
|
|
|
|
|
return @{$nodes} + sum_nodes(\@children);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $old_count = sum_nodes(\@content);
|
2011-03-09 20:25:17 +01:00
|
|
|
|
cmd 'split v';
|
2010-06-01 22:29:19 +02:00
|
|
|
|
|
|
|
|
|
@content = @{get_ws_content($tmp)};
|
2010-08-21 18:25:48 +02:00
|
|
|
|
$old_count = sum_nodes(\@content);
|
2010-06-01 22:29:19 +02:00
|
|
|
|
|
2011-03-09 20:25:17 +01:00
|
|
|
|
cmd 'split v';
|
2010-06-01 22:29:19 +02:00
|
|
|
|
|
|
|
|
|
@content = @{get_ws_content($tmp)};
|
|
|
|
|
my $count = sum_nodes(\@content);
|
|
|
|
|
is($count, $old_count, 'not more windows after splitting again');
|
2010-05-10 09:33:10 +02:00
|
|
|
|
|
2012-01-30 17:13:44 +01:00
|
|
|
|
######################################################################
|
|
|
|
|
# In the special case of being inside a stacked or tabbed container, we don’t
|
|
|
|
|
# want this to happen.
|
|
|
|
|
######################################################################
|
|
|
|
|
|
|
|
|
|
$tmp = fresh_workspace;
|
|
|
|
|
|
|
|
|
|
cmd 'open';
|
|
|
|
|
@content = @{get_ws_content($tmp)};
|
|
|
|
|
is(scalar @content, 1, 'Precisely one container on this ws');
|
|
|
|
|
cmd 'layout stacked';
|
|
|
|
|
@content = @{get_ws_content($tmp)};
|
|
|
|
|
is(scalar @content, 1, 'Still one container on this ws');
|
|
|
|
|
is(scalar @{$content[0]->{nodes}}, 1, 'Stacked con has one child node');
|
|
|
|
|
|
|
|
|
|
cmd 'split h';
|
|
|
|
|
cmd 'open';
|
|
|
|
|
@content = @{get_ws_content($tmp)};
|
|
|
|
|
is(scalar @content, 1, 'Still one container on this ws');
|
|
|
|
|
is(scalar @{$content[0]->{nodes}}, 1, 'Stacked con still has one child node');
|
|
|
|
|
|
con_set_layout: always use the parent container, handle workspaces properly
Previously, in case 'layout stacked' (for example) had been called
interactively, con_set_layout would be called with focused->parent,
while with for_window, it’d be called on the actual matching container.
This difference in behavior was the cause for the inability to use
'for_window [class="XTerm"] layout tabbed', which now works \o/, but
more on that below.
The change also allows us to handle the case of the user selecting a
CT_WORKSPACE container properly, that is, by using the special case and
creating a new split container on the workspace which gets all the
contents, but a new layout.
Now, before you are enthusiastic about the change and try to use
for_window magic in your config file, keep in mind: The 'layout' command
acts on the parent split container. That is, when using a line such as
this one:
for_window [class="XTerm"] layout tabbed
…and opening an XTerm when on a workspace with one single other window,
the whole workspace will be set tabbed (just as previously when you
opened an XTerm and sent 'layout tabbed' manually).
Therefore, to open XTerm in its own tabbed split container, you need to
split before:
for_window [class="XTerm"] split v, layout tabbed
The comma here is important! It says that the second command should not
be treated as an entirely unrelated command, but it should also relate
the matching window (while it does work with a ';', that is prone to
race-conditions and should be avoided).
fixes #358
2012-09-05 00:22:38 +02:00
|
|
|
|
################################################################################
|
|
|
|
|
# When focusing the workspace, changing the layout should have an effect on the
|
|
|
|
|
# workspace, not on the parent (CT_CONTENT) container.
|
|
|
|
|
################################################################################
|
|
|
|
|
|
|
|
|
|
sub get_output_content {
|
|
|
|
|
my $tree = i3(get_socket_path())->get_tree->recv;
|
|
|
|
|
|
|
|
|
|
my @outputs = grep { $_->{name} !~ /^__/ } @{$tree->{nodes}};
|
|
|
|
|
is(scalar @outputs, 1, 'exactly one output (testcase not multi-monitor capable)');
|
|
|
|
|
my $output = $outputs[0];
|
|
|
|
|
# get the first (and only) CT_CON
|
2013-12-14 14:50:44 +01:00
|
|
|
|
return first { $_->{type} eq 'con' } @{$output->{nodes}};
|
con_set_layout: always use the parent container, handle workspaces properly
Previously, in case 'layout stacked' (for example) had been called
interactively, con_set_layout would be called with focused->parent,
while with for_window, it’d be called on the actual matching container.
This difference in behavior was the cause for the inability to use
'for_window [class="XTerm"] layout tabbed', which now works \o/, but
more on that below.
The change also allows us to handle the case of the user selecting a
CT_WORKSPACE container properly, that is, by using the special case and
creating a new split container on the workspace which gets all the
contents, but a new layout.
Now, before you are enthusiastic about the change and try to use
for_window magic in your config file, keep in mind: The 'layout' command
acts on the parent split container. That is, when using a line such as
this one:
for_window [class="XTerm"] layout tabbed
…and opening an XTerm when on a workspace with one single other window,
the whole workspace will be set tabbed (just as previously when you
opened an XTerm and sent 'layout tabbed' manually).
Therefore, to open XTerm in its own tabbed split container, you need to
split before:
for_window [class="XTerm"] split v, layout tabbed
The comma here is important! It says that the second command should not
be treated as an entirely unrelated command, but it should also relate
the matching window (while it does work with a ';', that is prone to
race-conditions and should be avoided).
fixes #358
2012-09-05 00:22:38 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$tmp = fresh_workspace;
|
|
|
|
|
|
|
|
|
|
cmd 'open';
|
|
|
|
|
cmd 'split v';
|
|
|
|
|
cmd 'open';
|
|
|
|
|
cmd 'focus parent';
|
|
|
|
|
is(get_output_content()->{layout}, 'splith', 'content container layout ok');
|
|
|
|
|
cmd 'layout stacked';
|
|
|
|
|
is(get_output_content()->{layout}, 'splith', 'content container layout still ok');
|
|
|
|
|
|
2013-01-24 17:56:03 +01:00
|
|
|
|
######################################################################
|
|
|
|
|
# Splitting a workspace that has more than one child
|
|
|
|
|
######################################################################
|
|
|
|
|
|
|
|
|
|
$tmp = fresh_workspace;
|
|
|
|
|
|
|
|
|
|
cmd 'open';
|
|
|
|
|
cmd 'open';
|
|
|
|
|
cmd 'focus parent';
|
|
|
|
|
cmd 'split v';
|
|
|
|
|
cmd 'open';
|
|
|
|
|
|
|
|
|
|
my $content = get_ws_content($tmp);
|
|
|
|
|
my $fst = $content->[0];
|
|
|
|
|
my $snd = $content->[1];
|
|
|
|
|
|
|
|
|
|
is(@{$content}, 2, 'two containers on workspace');
|
|
|
|
|
is(@{$fst->{nodes}}, 2, 'first child has two children');
|
|
|
|
|
is(@{$snd->{nodes}}, 0, 'second child has no children');
|
|
|
|
|
|
2016-01-04 17:31:47 +01:00
|
|
|
|
######################################################################
|
|
|
|
|
# Test split toggle
|
|
|
|
|
######################################################################
|
|
|
|
|
|
|
|
|
|
$tmp = fresh_workspace;
|
|
|
|
|
cmd 'split h';
|
|
|
|
|
cmd 'split toggle';
|
|
|
|
|
$ws = get_ws($tmp);
|
|
|
|
|
is($ws->{layout}, 'splitv', 'toggled workspace split');
|
|
|
|
|
|
|
|
|
|
$tmp = fresh_workspace;
|
|
|
|
|
cmd 'split h';
|
|
|
|
|
cmd 'split toggle';
|
|
|
|
|
cmd 'split toggle';
|
|
|
|
|
$ws = get_ws($tmp);
|
|
|
|
|
is($ws->{layout}, 'splith', 'toggled workspace back and forth');
|
|
|
|
|
|
|
|
|
|
cmd 'open';
|
|
|
|
|
cmd 'open';
|
|
|
|
|
cmd 'split toggle';
|
|
|
|
|
|
|
|
|
|
$content = get_ws_content($tmp);
|
|
|
|
|
my $second = $content->[1];
|
|
|
|
|
is($second->{layout}, 'splitv', 'toggled container orientation to vertical');
|
|
|
|
|
|
|
|
|
|
cmd 'split toggle';
|
|
|
|
|
$content = get_ws_content($tmp);
|
|
|
|
|
$second = $content->[1];
|
|
|
|
|
is($second->{layout}, 'splith', 'toggled container orientation back to horizontal');
|
|
|
|
|
|
2011-03-09 20:25:17 +01:00
|
|
|
|
done_testing;
|