From: Michael Stapelberg Date: Thu, 14 Sep 2017 15:49:02 +0000 (+0200) Subject: Reorder tests to not use the same number (#2947) X-Git-Tag: 4.14.1~16 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=5d9db61dda8d114df4d00a083c8cabd27651a838;p=i3%2Fi3 Reorder tests to not use the same number (#2947) Distinct numbers make re-running individual tests easier by helping with tab-completion. Completeness verified using: % for i in $(seq 0 600) do files=$(ls testcases/t/$(printf "%03d" $i)-*.t 2>&- | wc -l) [ "$files" != "0" ] && [ "$files" != "1" ] && echo "clash: $i" done --- diff --git a/testcases/t/165-for_window_tilingfloating.t b/testcases/t/165-for_window_tilingfloating.t deleted file mode 100644 index 760ac53e..00000000 --- a/testcases/t/165-for_window_tilingfloating.t +++ /dev/null @@ -1,49 +0,0 @@ -#!perl -# vim:ts=4:sw=4:expandtab -# -# Please read the following documents before working on tests: -# • http://build.i3wm.org/docs/testsuite.html -# (or docs/testsuite) -# -# • http://build.i3wm.org/docs/lib-i3test.html -# (alternatively: perldoc ./testcases/lib/i3test.pm) -# -# • http://build.i3wm.org/docs/ipc.html -# (or docs/ipc) -# -# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf -# (unless you are already familiar with Perl) -# -use i3test i3_autostart => 0; -use X11::XCB qw(PROP_MODE_REPLACE); - -############################################################## -# 13: check that the tiling / floating criteria work. -############################################################## - -my $config = <<"EOT"; -# i3 config file (v4) -font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1 -for_window [tiling] mark tiled -for_window [floating] mark floated -EOT - -my $pid = launch_with_config($config); -my $tmp = fresh_workspace; - -open_window; -open_floating_window; - -my @nodes = @{get_ws($tmp)->{nodes}}; -cmp_ok(@nodes, '==', 1, 'one tiling container on this workspace'); -is_deeply($nodes[0]->{marks}, [ 'tiled' ], "mark set for 'tiling' criterion"); - -@nodes = @{get_ws($tmp)->{floating_nodes}}; -cmp_ok(@nodes, '==', 1, 'one floating container on this workspace'); -is_deeply($nodes[0]->{nodes}[0]->{marks}, [ 'floated' ], "mark set for 'floating' criterion"); - -exit_gracefully($pid); - -############################################################## - -done_testing; diff --git a/testcases/t/173-regress-focus-assign.t b/testcases/t/173-regress-focus-assign.t deleted file mode 100644 index b010963b..00000000 --- a/testcases/t/173-regress-focus-assign.t +++ /dev/null @@ -1,77 +0,0 @@ -#!perl -# vim:ts=4:sw=4:expandtab -# -# Please read the following documents before working on tests: -# • http://build.i3wm.org/docs/testsuite.html -# (or docs/testsuite) -# -# • http://build.i3wm.org/docs/lib-i3test.html -# (alternatively: perldoc ./testcases/lib/i3test.pm) -# -# • http://build.i3wm.org/docs/ipc.html -# (or docs/ipc) -# -# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf -# (unless you are already familiar with Perl) -# -# Regression: Checks if focus is stolen when a window is managed which is -# assigned to an invisible workspace -# -use i3test i3_autostart => 0; - -sub open_special { - my %args = @_; - $args{name} //= 'special window'; - - # We use dont_map because i3 will not map the window on the current - # workspace. Thus, open_window would time out in wait_for_map (2 seconds). - my $window = open_window( - %args, - wm_class => 'special', - dont_map => 1, - ); - $window->map; - return $window; -} - -##################################################################### -# start a window and see that it does not get assigned with an empty config -##################################################################### - -my $config = <{focused}, 'current workspace focused'); - -my $window = open_special; -sync_with_i3; - -ok(@{get_ws_content($tmp)} == 0, 'special window not on current workspace'); -ok(@{get_ws_content('targetws')} == 1, 'special window on targetws'); -ok(get_ws($tmp)->{focused}, 'current workspace still focused'); - -##################################################################### -# the same test, but with a floating window -##################################################################### - -$window = open_special( - window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_UTILITY'), -); - -ok(@{get_ws_content($tmp)} == 0, 'special window not on current workspace'); -ok(@{get_ws_content('targetws')} == 1, 'special window on targetws'); -ok(get_ws($tmp)->{focused}, 'current workspace still focused'); - -exit_gracefully($pid); - -$window->destroy; - -done_testing; diff --git a/testcases/t/174-regress-focus-toggle.t b/testcases/t/174-regress-focus-toggle.t deleted file mode 100644 index 192e9753..00000000 --- a/testcases/t/174-regress-focus-toggle.t +++ /dev/null @@ -1,30 +0,0 @@ -#!perl -# vim:ts=4:sw=4:expandtab -# -# Please read the following documents before working on tests: -# • http://build.i3wm.org/docs/testsuite.html -# (or docs/testsuite) -# -# • http://build.i3wm.org/docs/lib-i3test.html -# (alternatively: perldoc ./testcases/lib/i3test.pm) -# -# • http://build.i3wm.org/docs/ipc.html -# (or docs/ipc) -# -# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf -# (unless you are already familiar with Perl) -# -# Regression: Checks if i3 still lives after using 'focus mode_toggle' on an -# empty workspace. This regression was fixed in -# 0848844f2d41055f6ffc69af1149d7a873460976. -# -use i3test; -use v5.10; - -my $tmp = fresh_workspace; - -cmd 'focus mode_toggle'; - -does_i3_live; - -done_testing; diff --git a/testcases/t/213-move-branch-position.t b/testcases/t/213-move-branch-position.t deleted file mode 100644 index c2928c9e..00000000 --- a/testcases/t/213-move-branch-position.t +++ /dev/null @@ -1,376 +0,0 @@ -#!perl -# vim:ts=4:sw=4:expandtab -# -# Please read the following documents before working on tests: -# • http://build.i3wm.org/docs/testsuite.html -# (or docs/testsuite) -# -# • http://build.i3wm.org/docs/lib-i3test.html -# (alternatively: perldoc ./testcases/lib/i3test.pm) -# -# • http://build.i3wm.org/docs/ipc.html -# (or docs/ipc) -# -# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf -# (unless you are already familiar with Perl) -# -# Test that movement of a con into a branch will place the moving con at the -# correct position within the branch. -# -# If the direction of movement is the same as the orientation of the branch -# container, append or prepend the container to the branch in the obvious way. -# If the movement is to the right or downward, insert the moving container in -# the first position (i.e., the leftmost or top position resp.) If the movement -# is to the left or upward, insert the moving container in the last position -# (i.e., the rightmost or bottom position resp.) -# -# If the direction of movement is different from the orientation of the branch -# container, insert the container into the branch after the focused-inactive -# container. -# -# For testing purposes, we will demonstrate the behavior for tabbed containers -# to represent the case of split-horizontal branches and stacked containers to -# represent the case of split-vertical branches. -# -# Ticket: #1060 -# Bug still in: 4.6-109-g18cfc36 - -use i3test; - -# Opens tabs on the presently focused branch and adds several additional -# windows. Shifts focus to somewhere in the middle of the tabs so the most -# general case can be assumed. -sub open_tabs { - cmd 'layout tabbed'; - open_window; - open_window; - open_window; - open_window; - cmd 'focus left; focus left' -} - -# Likewise for a stack -sub open_stack { - cmd 'layout stacking'; - open_window; - open_window; - open_window; - open_window; - cmd 'focus up; focus up' -} - -# Gets the position of the given leaf within the given branch. The first -# position is one (1). Returns negative one (-1) if the leaf cannot be found -# within the branch. -sub get_leaf_position { - my ($branch, $leaf) = @_; - my $position = -1; - for my $i (0 .. @{$branch->{nodes}}) { - if ($branch->{nodes}[$i]->{id} == $leaf) { - $position = $i + 1; - last; - }; - } - return $position; -} - -# convenience function to focus a con by id to avoid having to type an ugly -# command each time -sub focus_con { - my $con_id = shift @_; - cmd "[con_id=\"$con_id\"] focus"; -} - -# Places a leaf into a branch and focuses the leaf. The newly created branch -# will have orientation specified by the second parameter. -sub branchify { - my ($con_id, $orientation) = @_; - focus_con($con_id); - $orientation eq 'horizontal' ? cmd 'splith' : cmd 'splitv'; - open_window; - focus_con($con_id); -} - -############################################################################## -# When moving a con right into tabs, the moving con should be placed as the -# first tab in the branch -############################################################################## -my $ws = fresh_workspace; - -# create the target leaf -open_window; -my $target_leaf = get_focused($ws); - -# create the tabbed branch container -open_window; -cmd 'splith'; -open_tabs; - -# move the target leaf into the tabbed branch -focus_con($target_leaf); -cmd 'move right'; - -# the target leaf should be the first in the branch -my $branch = shift @{get_ws_content($ws)}; -is($branch->{nodes}[0]->{id}, $target_leaf, 'moving con right into tabs placed it as the first tab in the branch'); - -# repeat the test when the target is in a branch -cmd 'move up; move left'; -branchify($target_leaf, 'vertical'); -cmd 'move right'; - -$branch = pop @{get_ws_content($ws)}; -is($branch->{nodes}[0]->{id}, $target_leaf, 'moving con right into tabs from a branch placed it as the first tab in the branch'); - -############################################################################## -# When moving a con right into a stack, the moving con should be placed -# below the focused-inactive leaf -############################################################################## -$ws = fresh_workspace; - -# create the target leaf -open_window; -$target_leaf = get_focused($ws); - -# create the stacked branch container and find the focused leaf -open_window; -cmd 'splith'; -open_stack; -my $secondary_leaf = get_focused($ws); - -# move the target leaf into the stacked branch -focus_con($target_leaf); -cmd 'move right'; - -# the secondary focus leaf should be below the target -$branch = shift @{get_ws_content($ws)}; -my $target_leaf_position = get_leaf_position($branch, $target_leaf); -my $secondary_leaf_position = get_leaf_position($branch, $secondary_leaf); - -is($target_leaf_position, $secondary_leaf_position + 1, 'moving con right into a stack placed it below the focused-inactive leaf'); - -# repeat the test when the target is in a branch -cmd 'move up; move left'; -branchify($target_leaf, 'vertical'); -cmd 'move right'; - -$branch = pop @{get_ws_content($ws)}; -$target_leaf_position = get_leaf_position($branch, $target_leaf); -$secondary_leaf_position = get_leaf_position($branch, $secondary_leaf); - -is($target_leaf_position, $secondary_leaf_position + 1, 'moving con right into a stack from a branch placed it below the focused-inactive leaf'); - -############################################################################## -# When moving a con down into a stack, the moving con should be placed at the -# top of the stack -############################################################################## -$ws = fresh_workspace; -cmd 'layout splitv'; - -# create the target leaf -open_window; -$target_leaf = get_focused($ws); - -# create the stacked branch container -open_window; -cmd 'splitv'; -open_stack; - -# move the target leaf into the stacked branch -focus_con($target_leaf); -cmd 'move down'; - -# the target leaf should be on the top of the stack -$branch = shift @{get_ws_content($ws)}; -is($branch->{nodes}[0]->{id}, $target_leaf, 'moving con down into a stack placed it on the top of the stack'); - -# repeat the test when the target is in a branch -cmd 'move right; move up'; -branchify($target_leaf, 'horizontal'); -cmd 'move down'; - -$branch = pop @{get_ws_content($ws)}; -is($branch->{nodes}[0]->{id}, $target_leaf, 'moving con down into a stack from a branch placed it on the top of the stack'); - -############################################################################## -# When moving a con down into tabs, the moving con should be placed after the -# focused-inactive tab -############################################################################## -$ws = fresh_workspace; -cmd 'layout splitv'; - -# create the target leaf -open_window; -$target_leaf = get_focused($ws); - -# create the tabbed branch container and find the focused tab -open_window; -cmd 'splitv'; -open_tabs; -$secondary_leaf = get_focused($ws); - -# move the target leaf into the tabbed branch -focus_con($target_leaf); -cmd 'move down'; - -# the secondary focus tab should be to the right -$branch = shift @{get_ws_content($ws)}; -$target_leaf_position = get_leaf_position($branch, $target_leaf); -$secondary_leaf_position = get_leaf_position($branch, $secondary_leaf); - -is($target_leaf_position, $secondary_leaf_position + 1, 'moving con down into tabs placed it after the focused-inactive tab'); - -# repeat the test when the target is in a branch -cmd 'move right; move up'; -branchify($target_leaf, 'horizontal'); -cmd 'move down'; - -$branch = pop @{get_ws_content($ws)}; -$target_leaf_position = get_leaf_position($branch, $target_leaf); -$secondary_leaf_position = get_leaf_position($branch, $secondary_leaf); - -is($target_leaf_position, $secondary_leaf_position + 1, 'moving con down into tabs from a branch placed it after the focused-inactive tab'); - -############################################################################## -# When moving a con left into tabs, the moving con should be placed as the last -# tab in the branch -############################################################################## -$ws = fresh_workspace; - -# create the tabbed branch container -open_window; -cmd 'splith'; -open_tabs; - -# create the target leaf -cmd 'focus parent'; -open_window; -$target_leaf = get_focused($ws); - -# move the target leaf into the tabbed branch -cmd 'move left'; - -# the target leaf should be last in the branch -$branch = shift @{get_ws_content($ws)}; - -is($branch->{nodes}->[-1]->{id}, $target_leaf, 'moving con left into tabs placed it as the last tab in the branch'); - -# repeat the test when the target leaf is in a branch -cmd 'move up; move right'; -branchify($target_leaf, 'vertical'); -cmd 'move left'; - -$branch = shift @{get_ws_content($ws)}; -is($branch->{nodes}->[-1]->{id}, $target_leaf, 'moving con left into tabs from a branch placed it as the last tab in the branch'); - -############################################################################## -# When moving a con left into a stack, the moving con should be placed below -# the focused-inactive leaf -############################################################################## -$ws = fresh_workspace; - -# create the stacked branch container and find the focused leaf -open_window; -open_stack; -$secondary_leaf = get_focused($ws); - -# create the target leaf to the right -cmd 'focus parent'; -open_window; -$target_leaf = get_focused($ws); - -# move the target leaf into the stacked branch -cmd 'move left'; - -# the secondary focus leaf should be below -$branch = shift @{get_ws_content($ws)}; -$target_leaf_position = get_leaf_position($branch, $target_leaf); -$secondary_leaf_position = get_leaf_position($branch, $secondary_leaf); - -is($target_leaf_position, $secondary_leaf_position + 1, 'moving con left into a stack placed it below the focused-inactive leaf'); - -# repeat the test when the target leaf is in a branch -cmd 'move up; move right'; -branchify($target_leaf, 'vertical'); -cmd 'move left'; - -$branch = shift @{get_ws_content($ws)}; -$target_leaf_position = get_leaf_position($branch, $target_leaf); -$secondary_leaf_position = get_leaf_position($branch, $secondary_leaf); - -is($target_leaf_position, $secondary_leaf_position + 1, 'moving con left into a stack from a branch placed it below the focused-inactive leaf'); - -############################################################################## -# When moving a con up into a stack, the moving con should be placed last in -# the stack -############################################################################## -$ws = fresh_workspace; -cmd 'layout splitv'; - -# create the stacked branch container -open_window; -cmd 'splitv'; -open_stack; - -# create the target leaf -cmd 'focus parent'; -open_window; -$target_leaf = get_focused($ws); - -# move the target leaf into the stacked branch -cmd 'move up'; - -# the target leaf should be on the bottom of the stack -$branch = shift @{get_ws_content($ws)}; - -is($branch->{nodes}->[-1]->{id}, $target_leaf, 'moving con up into stack placed it on the bottom of the stack'); - -# repeat the test when the target leaf is in a branch -cmd 'move right; move down'; -branchify($target_leaf, 'horizontal'); -cmd 'move up'; - -$branch = shift @{get_ws_content($ws)}; - -is($branch->{nodes}->[-1]->{id}, $target_leaf, 'moving con up into stack from a branch placed it on the bottom of the stack'); - -############################################################################## -# When moving a con up into tabs, the moving con should be placed after the -# focused-inactive tab -############################################################################## -$ws = fresh_workspace; -cmd 'layout splitv'; - -# create the tabbed branch container and find the focused leaf -open_window; -cmd 'splitv'; -open_tabs; -$secondary_leaf = get_focused($ws); - -# create the target leaf below -cmd 'focus parent'; -open_window; -$target_leaf = get_focused($ws); - -# move the target leaf into the tabbed branch -cmd 'move up'; - -# the secondary focus tab should be to the right -$branch = shift @{get_ws_content($ws)}; -$target_leaf_position = get_leaf_position($branch, $target_leaf); -$secondary_leaf_position = get_leaf_position($branch, $secondary_leaf); - -is($target_leaf_position, $secondary_leaf_position + 1, 'moving con up into tabs placed it after the focused-inactive tab'); - -# repeat the test when the target leaf is in a branch -cmd 'move right; move down'; -branchify($target_leaf, 'horizontal'); -cmd 'move up'; - -$branch = shift @{get_ws_content($ws)}; -$target_leaf_position = get_leaf_position($branch, $target_leaf); -$secondary_leaf_position = get_leaf_position($branch, $secondary_leaf); - -is($target_leaf_position, $secondary_leaf_position + 1, 'moving con up into tabs from a branch placed it after the focused-inactive tab'); - -done_testing; diff --git a/testcases/t/231-ipc-window-close.t b/testcases/t/231-ipc-window-close.t deleted file mode 100644 index 3483cf42..00000000 --- a/testcases/t/231-ipc-window-close.t +++ /dev/null @@ -1,52 +0,0 @@ -#!perl -# vim:ts=4:sw=4:expandtab -# -# Please read the following documents before working on tests: -# • http://build.i3wm.org/docs/testsuite.html -# (or docs/testsuite) -# -# • http://build.i3wm.org/docs/lib-i3test.html -# (alternatively: perldoc ./testcases/lib/i3test.pm) -# -# • http://build.i3wm.org/docs/ipc.html -# (or docs/ipc) -# -# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf -# (unless you are already familiar with Perl) -# -# Tests that the ipc close event works properly -# -# Bug still in: 4.8-7-gf4a8253 -use i3test; - -my $i3 = i3(get_socket_path()); -$i3->connect()->recv; - -my $cv; -my $t; - -sub reset_test { - $cv = AE::cv; - $t = AE::timer(0.5, 0, sub { $cv->send(0); }); -} - -reset_test; - -$i3->subscribe({ - window => sub { - my ($e) = @_; - if ($e->{change} eq 'close') { - $cv->send($e->{container}); - } - }, - })->recv; - -my $window = open_window; - -cmd 'kill'; -my $con = $cv->recv; - -ok($con, 'closing a window should send the window::close event'); -is($con->{window}, $window->{id}, 'the event should contain information about the window'); - -done_testing; diff --git a/testcases/t/231-ipc-window-move.t b/testcases/t/231-ipc-window-move.t deleted file mode 100644 index 117d27fb..00000000 --- a/testcases/t/231-ipc-window-move.t +++ /dev/null @@ -1,61 +0,0 @@ -#!perl -# vim:ts=4:sw=4:expandtab -# -# Please read the following documents before working on tests: -# • http://build.i3wm.org/docs/testsuite.html -# (or docs/testsuite) -# -# • http://build.i3wm.org/docs/lib-i3test.html -# (alternatively: perldoc ./testcases/lib/i3test.pm) -# -# • http://build.i3wm.org/docs/ipc.html -# (or docs/ipc) -# -# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf -# (unless you are already familiar with Perl) -# -# Tests that the ipc window::move event works properly -# -# Bug still in: 4.8-7-gf4a8253 -use i3test; - -my $i3 = i3(get_socket_path()); -$i3->connect()->recv; - -my $cv; -my $t; - -sub reset_test { - $cv = AE::cv; - $t = AE::timer(0.5, 0, sub { $cv->send(0); }); -} - -reset_test; - -$i3->subscribe({ - window => sub { - my ($e) = @_; - if ($e->{change} eq 'move') { - $cv->send($e->{container}); - } - }, - })->recv; - -my $dummy_window = open_window; -my $window = open_window; - -cmd 'move right'; -my $con = $cv->recv; - -ok($con, 'moving a window should emit the window::move event'); -is($con->{window}, $window->{id}, 'the event should contain info about the window'); - -reset_test; - -cmd 'move to workspace ws_new'; -$con = $cv->recv; - -ok($con, 'moving a window to a different workspace should emit the window::move event'); -is($con->{window}, $window->{id}, 'the event should contain info about the window'); - -done_testing; diff --git a/testcases/t/232-ipc-window-urgent.t b/testcases/t/232-ipc-window-urgent.t deleted file mode 100644 index 09226ff1..00000000 --- a/testcases/t/232-ipc-window-urgent.t +++ /dev/null @@ -1,68 +0,0 @@ -#!perl -# vim:ts=4:sw=4:expandtab -# -# Please read the following documents before working on tests: -# • http://build.i3wm.org/docs/testsuite.html -# (or docs/testsuite) -# -# • http://build.i3wm.org/docs/lib-i3test.html -# (alternatively: perldoc ./testcases/lib/i3test.pm) -# -# • http://build.i3wm.org/docs/ipc.html -# (or docs/ipc) -# -# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf -# (unless you are already familiar with Perl) -# -# Test that the window::urgent event works correctly. The window::urgent event -# should be emitted when a window becomes urgent or loses its urgent status. -# -use i3test; - -my $config = <connect()->recv; - -my $cv; -$i3->subscribe({ - window => sub { - my ($event) = @_; - $cv->send($event) if $event->{change} eq 'urgent'; - } -})->recv; - -my $t; -$t = AnyEvent->timer( - after => 0.5, - cb => sub { - $cv->send(0); - } -); - -$cv = AnyEvent->condvar; -fresh_workspace; -my $win = open_window; -my $dummy_win = open_window; - -$win->add_hint('urgency'); -my $event = $cv->recv; - -isnt($event, 0, 'an urgent con should emit the window::urgent event'); -is($event->{container}->{window}, $win->{id}, 'the event should contain information about the window'); -is($event->{container}->{urgent}, 1, 'the container should be urgent'); - -$cv = AnyEvent->condvar; -$win->delete_hint('urgency'); -$event = $cv->recv; - -isnt($event, 0, 'an urgent con should emit the window::urgent event'); -is($event->{container}->{window}, $win->{id}, 'the event should contain information about the window'); -is($event->{container}->{urgent}, 0, 'the container should not be urgent'); - -done_testing; diff --git a/testcases/t/234-layout-restore-output.t b/testcases/t/234-layout-restore-output.t deleted file mode 100644 index 5a1f3763..00000000 --- a/testcases/t/234-layout-restore-output.t +++ /dev/null @@ -1,234 +0,0 @@ -#!perl -# vim:ts=4:sw=4:expandtab -# -# Please read the following documents before working on tests: -# • http://build.i3wm.org/docs/testsuite.html -# (or docs/testsuite) -# -# • http://build.i3wm.org/docs/lib-i3test.html -# (alternatively: perldoc ./testcases/lib/i3test.pm) -# -# • http://build.i3wm.org/docs/ipc.html -# (or docs/ipc) -# -# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf -# (unless you are already familiar with Perl) -# -# Verifies that entire outputs can be saved and restored properly by i3. -# Ticket: #1306 -# Bug still in: 4.8-26-gf96ec19 -use i3test; -use File::Temp qw(tempfile); -use IO::Handle; - -my $ws = fresh_workspace; - -################################################################################ -# Append a new workspace with a name. -################################################################################ - -ok(!workspace_exists('ws_new'), 'workspace "ws_new" does not exist yet'); - -my ($fh, $filename) = tempfile(UNLINK => 1); -print $fh <<'EOT'; -// vim:ts=4:sw=4:et -{ - // workspace with 1 children - "border": "pixel", - "floating": "auto_off", - "layout": "splith", - "percent": null, - "type": "workspace", - "name": "ws_new", - "nodes": [ - { - "border": "pixel", - "floating": "auto_off", - "geometry": { - "height": 268, - "width": 484, - "x": 0, - "y": 0 - }, - "name": "vals@w00t: ~", - "percent": 1, - "swallows": [ - { - "class": "^URxvt$" - // "instance": "^urxvt$", - // "title": "^vals\\@w00t\\:\\ \\~$" - } - ], - "type": "con" - } - ] -} -EOT -$fh->flush; -cmd "append_layout $filename"; - -ok(workspace_exists('ws_new'), 'workspace "ws_new" exists now'); - -does_i3_live; - -close($fh); - -################################################################################ -# Append a new workspace with a name that clashes with an existing workspace. -################################################################################ - -my @old_workspaces = @{get_workspace_names()}; - -cmd "append_layout $filename"; - -my @new_workspaces = @{get_workspace_names()}; -cmp_ok(scalar @new_workspaces, '>', scalar @old_workspaces, 'more workspaces than before'); - -my %created_workspaces = map { ($_, 1) } @new_workspaces; -delete $created_workspaces{$_} for @old_workspaces; -diag('created workspaces = ' . Dumper(keys %created_workspaces)); -cmp_ok(scalar keys %created_workspaces, '>', 0, 'new workspaces appeared'); - -################################################################################ -# Append a new workspace without a name. -################################################################################ - -ok(!workspace_exists('unnamed'), 'workspace "unnamed" does not exist yet'); - -($fh, $filename) = tempfile(UNLINK => 1); -print $fh <<'EOT'; -// vim:ts=4:sw=4:et -{ - // workspace with 1 children - "border": "pixel", - "floating": "auto_off", - "layout": "splith", - "percent": null, - "type": "workspace", - "nodes": [ - { - "border": "pixel", - "floating": "auto_off", - "geometry": { - "height": 268, - "width": 484, - "x": 0, - "y": 0 - }, - "name": "vals@w00t: ~", - "percent": 1, - "swallows": [ - { - "class": "^URxvt$" - // "instance": "^urxvt$", - // "title": "^vals\\@w00t\\:\\ \\~$" - } - ], - "type": "con" - } - ] -} -EOT -$fh->flush; -cmd "append_layout $filename"; - -ok(workspace_exists('unnamed'), 'workspace "unnamed" exists now'); - -################################################################################ -# Append a workspace with a numeric name, ensure it has ->num set. -################################################################################ - -ok(!workspace_exists('4'), 'workspace "4" does not exist yet'); - -($fh, $filename) = tempfile(UNLINK => 1); -print $fh <<'EOT'; -// vim:ts=4:sw=4:et -{ - // workspace with 1 children - "border": "pixel", - "floating": "auto_off", - "layout": "splith", - "percent": null, - "type": "workspace", - "name": "4", - "nodes": [ - { - "border": "pixel", - "floating": "auto_off", - "geometry": { - "height": 268, - "width": 484, - "x": 0, - "y": 0 - }, - "name": "vals@w00t: ~", - "percent": 1, - "swallows": [ - { - "class": "^URxvt$" - // "instance": "^urxvt$", - // "title": "^vals\\@w00t\\:\\ \\~$" - } - ], - "type": "con" - } - ] -} -EOT -$fh->flush; -cmd "append_layout $filename"; - -ok(workspace_exists('4'), 'workspace "4" exists now'); -$ws = get_ws("4"); -is($ws->{num}, 4, 'workspace number is 4'); - -################################################################################ -# Append a workspace with a numeric name, with the “type” property at the end -# of the JSON blurb (which is valid and sometimes happens). -################################################################################ - -ok(!workspace_exists('5'), 'workspace "5" does not exist yet'); - -($fh, $filename) = tempfile(UNLINK => 1); -print $fh <<'EOT'; -// vim:ts=4:sw=4:et -{ - // workspace with 1 children - "border": "pixel", - "floating": "auto_off", - "layout": "splith", - "percent": null, - "name": "5", - "nodes": [ - { - "border": "pixel", - "floating": "auto_off", - "geometry": { - "height": 268, - "width": 484, - "x": 0, - "y": 0 - }, - "name": "vals@w00t: ~", - "percent": 1, - "swallows": [ - { - "class": "^URxvt$" - // "instance": "^urxvt$", - // "title": "^vals\\@w00t\\:\\ \\~$" - } - ], - "type": "con" - } - ], - "type": "workspace" -} -EOT -$fh->flush; -cmd "append_layout $filename"; - -ok(workspace_exists('5'), 'workspace "5" exists now'); -$ws = get_ws("5"); -is($ws->{num}, 5, 'workspace number is 5'); - -done_testing; diff --git a/testcases/t/234-regress-default-floating-border.t b/testcases/t/234-regress-default-floating-border.t deleted file mode 100644 index d5994f58..00000000 --- a/testcases/t/234-regress-default-floating-border.t +++ /dev/null @@ -1,43 +0,0 @@ -#!perl -# vim:ts=4:sw=4:expandtab -# -# Please read the following documents before working on tests: -# • http://build.i3wm.org/docs/testsuite.html -# (or docs/testsuite) -# -# • http://build.i3wm.org/docs/lib-i3test.html -# (alternatively: perldoc ./testcases/lib/i3test.pm) -# -# • http://build.i3wm.org/docs/ipc.html -# (or docs/ipc) -# -# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf -# (unless you are already familiar with Perl) -# -# This is a regression test for a bug where a normal floating default border is -# not applied when the default tiling border is set to a pixel value. -# Ticket: #1305 -# Bug still in: 4.8-62-g7381b50 -use i3test i3_autostart => 0; - -my $config = <{floating_nodes}}; - -is($floating[0]->{nodes}[0]->{border}, 'normal', 'default floating border is `normal`'); - -exit_gracefully($pid); - -done_testing; diff --git a/testcases/t/235-wm-class-change-handler.t b/testcases/t/235-wm-class-change-handler.t deleted file mode 100644 index ce237b57..00000000 --- a/testcases/t/235-wm-class-change-handler.t +++ /dev/null @@ -1,78 +0,0 @@ -#!perl -# vim:ts=4:sw=4:expandtab -# -# Please read the following documents before working on tests: -# • http://build.i3wm.org/docs/testsuite.html -# (or docs/testsuite) -# -# • http://build.i3wm.org/docs/lib-i3test.html -# (alternatively: perldoc ./testcases/lib/i3test.pm) -# -# • http://build.i3wm.org/docs/ipc.html -# (or docs/ipc) -# -# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf -# (unless you are already familiar with Perl) -# -# Test that changes to WM_CLASS are internally processed by i3 by updating the -# cached property and running assignments. This allows the property to be used -# in criteria selection -# Ticket: #1052 -# Bug still in: 4.8-73-g6bf7f8e -use i3test i3_autostart => 0; -use X11::XCB qw(PROP_MODE_REPLACE); - -my $config = <atom(name => 'WM_CLASS'); - my $atomtype = $x->atom(name => 'STRING'); - $length ||= length($class) + 1; - $x->change_property( - PROP_MODE_REPLACE, - $window->id, - $atomname->id, - $atomtype->id, - 8, - $length, - $class - ); - sync_with_i3; -} - -my $ws = fresh_workspace; - -my $win = open_window; - -change_window_class($win, "special\0Special"); - -my $con = @{get_ws_content($ws)}[0]; - -is($con->{window_properties}->{class}, 'Special', - 'The container class should be updated when a window changes class'); - -is($con->{window_properties}->{instance}, 'special', - 'The container instance should be updated when a window changes instance'); - -# The mark `special_class_mark` is added in a `for_window` assignment in the -# config for testing purposes -is_deeply($con->{marks}, [ 'special_class_mark' ], - 'A `for_window` assignment should run for a match when the window changes class'); - -change_window_class($win, "abcdefghijklmnopqrstuv\0abcd", 24); - -$con = @{get_ws_content($ws)}[0]; - -is($con->{window_properties}->{class}, 'a', - 'Non-null-terminated strings should be handled correctly'); - -exit_gracefully($pid); - -done_testing; diff --git a/testcases/t/238-regress-reload-bindsym.t b/testcases/t/238-regress-reload-bindsym.t deleted file mode 100644 index 6d5d12c3..00000000 --- a/testcases/t/238-regress-reload-bindsym.t +++ /dev/null @@ -1,45 +0,0 @@ -#!perl -# vim:ts=4:sw=4:expandtab -# -# Please read the following documents before working on tests: -# • http://build.i3wm.org/docs/testsuite.html -# (or docs/testsuite) -# -# • http://build.i3wm.org/docs/lib-i3test.html -# (alternatively: perldoc ./testcases/lib/i3test.pm) -# -# • http://build.i3wm.org/docs/ipc.html -# (or docs/ipc) -# -# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf -# (unless you are already familiar with Perl) -# -# Test that the binding event works properly -# Ticket: #1210 -use i3test i3_autostart => 0; - -my $config = < /dev/null); - - skip 'xdotool is required to test the binding event. `[apt-get install|pacman -S] xdotool`', 1 if $?; - - my $pid = launch_with_config($config); - - my $i3 = i3(get_socket_path()); - $i3->connect->recv; - - qx(xdotool key r); - - does_i3_live; - - exit_gracefully($pid); - -} -done_testing; diff --git a/testcases/t/240-tabbed-floating-disable-crash.t b/testcases/t/240-tabbed-floating-disable-crash.t deleted file mode 100644 index 7947158c..00000000 --- a/testcases/t/240-tabbed-floating-disable-crash.t +++ /dev/null @@ -1,44 +0,0 @@ -#!perl -# vim:ts=4:sw=4:expandtab -# -# Please read the following documents before working on tests: -# • http://build.i3wm.org/docs/testsuite.html -# (or docs/testsuite) -# -# • http://build.i3wm.org/docs/lib-i3test.html -# (alternatively: perldoc ./testcases/lib/i3test.pm) -# -# • http://build.i3wm.org/docs/ipc.html -# (or docs/ipc) -# -# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf -# (unless you are already familiar with Perl) -# -# Verifies that i3 does not crash when floating and then unfloating an -# unfocused window within a tabbed container. -# Ticket: #1484 -# Bug still in: 4.9.1-124-g856e1f9 -use i3test i3_autostart => 0; - -my $config = <atom(name => '_NET_WM_STATE_HIDDEN'); - - my ($con) = @_; - my $cookie = $x->get_property( - 0, - $con->{id}, - $x->atom(name => '_NET_WM_STATE')->id, - GET_PROPERTY_TYPE_ANY, - 0, - 4096 - ); - - my $reply = $x->get_property_reply($cookie->{sequence}); - my $len = $reply->{length}; - return 0 if $len == 0; - - my @atoms = unpack("L$len", $reply->{value}); - for (my $i = 0; $i < $len; $i++) { - return 1 if $atoms[$i] == $atom->id; - } - - return 0; -} - -my ($tabA, $tabB, $tabC, $subtabA, $subtabB, $windowA, $windowB); - -############################################################################### -# Given two containers next to each other, when focusing one, then the other -# one does not have _NET_WM_STATE_HIDDEN set. -############################################################################### - -fresh_workspace; -$windowA = open_window; -$windowB = open_window; - -ok(!is_hidden($windowA), 'left window does not have _NET_WM_STATE_HIDDEN set'); -ok(!is_hidden($windowB), 'right window does not have _NET_WM_STATE_HIDDEN set'); - -############################################################################### -# Given two containers on different workspaces, when one is focused, then -# the other one does not have _NET_WM_STATE_HIDDEN set. -############################################################################### - -fresh_workspace; -$windowA = open_window; -fresh_workspace; -$windowB = open_window; - -ok(!is_hidden($windowA), 'left window does not have _NET_WM_STATE_HIDDEN set'); -ok(!is_hidden($windowB), 'right window does not have _NET_WM_STATE_HIDDEN set'); - -############################################################################### -# Given two containers in the same tabbed container, when one is focused, then -# (only) the other one has _NET_WM_STATE_HIDDEN set. -# Given the other tab is focused, then the atom is transferred. -############################################################################### - -fresh_workspace; -$tabA = open_window; -cmd 'layout tabbed'; -$tabB = open_window; - -ok(is_hidden($tabA), 'unfocused tab has _NET_WM_STATE_HIDDEN set'); -ok(!is_hidden($tabB), 'focused tab does not have _NET_WM_STATE_HIDDEN set'); - -cmd 'focus left'; - -ok(!is_hidden($tabA), 'focused tab does not have _NET_WM_STATE_HIDDEN set'); -ok(is_hidden($tabB), 'unfocused tab has _NET_WM_STATE_HIDDEN set'); - -############################################################################### -# Given three containers in the same stacked container, when the focused tab -# is moved to another workspace, then the now focused tab does not have -# _NET_WM_STATE_HIDDEN set anymore. -############################################################################### - -fresh_workspace; -$tabA = open_window; -cmd 'layout stacked'; -$tabB = open_window; -$tabC = open_window; -cmd 'move window to workspace unused'; - -ok(is_hidden($tabA), 'unfocused tab has _NET_WM_STATE_HIDDEN set'); -ok(!is_hidden($tabB), 'focused tab does not have _NET_WM_STATE_HIDDEN set'); -ok(!is_hidden($tabC), 'moved window does not have _NET_WM_STATE_HIDDEN set'); - -############################################################################### -# Given three containers in the same stacked container, when a not focused -# tab is moved to another workspace, then it does not have _NET_WM_STATE_HIDDEN -# set anymore. -############################################################################### - -fresh_workspace; -$tabA = open_window; -cmd 'layout stacked'; -$tabB = open_window; -cmd 'mark moveme'; -$tabC = open_window; -cmd '[con_mark="moveme"] move window to workspace unused'; - -ok(is_hidden($tabA), 'unfocused tab has _NET_WM_STATE_HIDDEN set'); -ok(!is_hidden($tabB), 'moved window does not have _NET_WM_STATE_HIDDEN set'); -ok(!is_hidden($tabC), 'focused tab does not have _NET_WM_STATE_HIDDEN set'); - -############################################################################### -# Given a tabbed container and some other container, when the latter is moved -# into the tabbed container, then all other tabs have _NET_WM_STATE_HIDDEN -# set. -############################################################################### - -fresh_workspace; -$tabA = open_window; -cmd 'layout tabbed'; -$tabB = open_window; -cmd 'focus parent'; -cmd 'split h'; -$tabC = open_window; -cmd 'move left'; - -ok(is_hidden($tabA), 'unfocused tab has _NET_WM_STATE_HIDDEN set'); -ok(is_hidden($tabB), 'unfocused tab has _NET_WM_STATE_HIDDEN set'); -ok(!is_hidden($tabC), 'focused tab does not have _NET_WM_STATE_HIDDEN set'); - -############################################################################### -# Given a stacked container nested inside another tabbed container with the -# inner one being in the currently focused tab, then the focused tab of the -# inner container does not have _NET_WM_STATE_HIDDEN set. -############################################################################### - -fresh_workspace; -$tabA = open_window; -cmd 'layout tabbed'; -$tabB = open_window; -cmd 'split h'; -open_window; -cmd 'split v'; -cmd 'layout stacked'; -$subtabA = open_window; -$subtabB = open_window; - -ok(is_hidden($tabA), 'unfocused outer tab has _NET_WM_STATE_HIDDEN set'); -ok(!is_hidden($tabB), 'focused outer tab does not have _NET_WM_STATE_HIDDEN set'); -ok(is_hidden($subtabA), 'unfocused inner tab has _NET_WM_STATE_HIDDEN set'); -ok(!is_hidden($subtabB), 'focused inner tab does not have _NET_WM_STATE_HIDDEN set'); - -cmd 'focus left'; - -ok(!is_hidden($subtabB), 'focused inner tab does not have _NET_WM_STATE_HIDDEN set'); - -############################################################################### -# Given a stacked container nested inside another tabbed container with the -# inner one being in a currently not focused tab, then all tabs of the inner -# container have _NET_WM_STATE_HIDDEN set. -############################################################################### - -fresh_workspace; -$tabA = open_window; -cmd 'layout tabbed'; -$tabB = open_window; -cmd 'split h'; -open_window; -cmd 'split v'; -cmd 'layout stacked'; -$subtabA = open_window; -$subtabB = open_window; -cmd 'focus parent'; -cmd 'focus parent'; -cmd 'focus left'; - -ok(!is_hidden($tabA), 'focused outer tab does not have _NET_WM_STATE_HIDDEN set'); -ok(is_hidden($tabB), 'unfocused outer tab has _NET_WM_STATE_HIDDEN set'); -ok(is_hidden($subtabA), 'unfocused inner tab has _NET_WM_STATE_HIDDEN set'); -ok(is_hidden($subtabB), 'unfocused inner tab has _NET_WM_STATE_HIDDEN set'); - -############################################################################### - -done_testing; diff --git a/testcases/t/251-ewmh-visible-name.t b/testcases/t/251-ewmh-visible-name.t deleted file mode 100644 index c201b398..00000000 --- a/testcases/t/251-ewmh-visible-name.t +++ /dev/null @@ -1,70 +0,0 @@ -#!perl -# vim:ts=4:sw=4:expandtab -# -# Please read the following documents before working on tests: -# • http://build.i3wm.org/docs/testsuite.html -# (or docs/testsuite) -# -# • http://build.i3wm.org/docs/lib-i3test.html -# (alternatively: perldoc ./testcases/lib/i3test.pm) -# -# • http://build.i3wm.org/docs/ipc.html -# (or docs/ipc) -# -# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf -# (unless you are already familiar with Perl) -# -# Tests that _NET_WM_VISIBLE_NAME is set correctly. -# Ticket: #1872 -use i3test; -use X11::XCB qw(:all); - -my ($con); - -sub get_visible_name { - sync_with_i3; - my ($con) = @_; - - my $cookie = $x->get_property( - 0, - $con->{id}, - $x->atom(name => '_NET_WM_VISIBLE_NAME')->id, - $x->atom(name => 'UTF8_STRING')->id, - 0, - 4096 - ); - - my $reply = $x->get_property_reply($cookie->{sequence}); - return undef if $reply->{value_len} == 0; - return $reply->{value}; -} - -############################################################################### -# 1: _NET_WM_VISIBLE_NAME is set when the title format of a window is changed. -############################################################################### - -fresh_workspace; -$con = open_window(name => 'boring title'); -is(get_visible_name($con), undef, 'sanity check: initially no visible name is set'); - -cmd 'title_format custom'; -is(get_visible_name($con), 'custom', 'the visible name is updated'); - -cmd 'title_format "%title"'; -is(get_visible_name($con), 'boring title', 'markup is returned as is'); - -############################################################################### -# 2: _NET_WM_VISIBLE_NAME is removed if not needed. -############################################################################### - -fresh_workspace; -$con = open_window(name => 'boring title'); -cmd 'title_format custom'; -is(get_visible_name($con), 'custom', 'sanity check: a visible name is set'); - -cmd 'title_format %title'; -is(get_visible_name($con), undef, 'the visible name is removed again'); - -############################################################################### - -done_testing; diff --git a/testcases/t/251-sticky.t b/testcases/t/251-sticky.t deleted file mode 100644 index 85fc11f7..00000000 --- a/testcases/t/251-sticky.t +++ /dev/null @@ -1,113 +0,0 @@ -#!perl -# vim:ts=4:sw=4:expandtab -# -# Please read the following documents before working on tests: -# • http://build.i3wm.org/docs/testsuite.html -# (or docs/testsuite) -# -# • http://build.i3wm.org/docs/lib-i3test.html -# (alternatively: perldoc ./testcases/lib/i3test.pm) -# -# • http://build.i3wm.org/docs/ipc.html -# (or docs/ipc) -# -# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf -# (unless you are already familiar with Perl) -# -# Tests sticky windows. -# Ticket: #1455 -use i3test; - -my ($ws, $tmp, $focused); - -############################################################################### -# 1: Given a sticky tiling container, when the workspace is switched, then -# nothing happens. -############################################################################### -fresh_workspace; -open_window(wm_class => 'findme'); -cmd 'sticky enable'; -$ws = fresh_workspace; - -is(@{get_ws($ws)->{nodes}}, 0, 'tiling sticky container did not move'); -is(@{get_ws($ws)->{floating_nodes}}, 0, 'tiling sticky container did not move'); -cmd '[class="findme"] kill'; - -############################################################################### -# 2: Given a sticky floating container, when the workspace is switched, then -# the container moves to the new workspace. -############################################################################### -$ws = fresh_workspace; -open_floating_window(wm_class => 'findme'); -$focused = get_focused($ws); -cmd 'sticky enable'; -$ws = fresh_workspace; - -is(@{get_ws($ws)->{floating_nodes}}, 1, 'floating sticky container moved to new workspace'); -is(get_focused($ws), $focused, 'sticky container has focus'); -cmd '[class="findme"] kill'; - -############################################################################### -# 3: Given two sticky floating containers, when the workspace is switched, -# then both containers move to the new workspace. -############################################################################### -fresh_workspace; -open_floating_window(wm_class => 'findme'); -cmd 'sticky enable'; -open_floating_window(wm_class => 'findme'); -cmd 'sticky enable'; -$ws = fresh_workspace; - -is(@{get_ws($ws)->{floating_nodes}}, 2, 'multiple sticky windows can be used at the same time'); -cmd '[class="findme"] kill'; - -############################################################################### -# 4: Given an unfocused sticky floating container and a tiling container on the -# target workspace, when the workspace is switched, then the tiling container -# is focused. -############################################################################### -$ws = fresh_workspace; -open_window; -$focused = get_focused($ws); -fresh_workspace; -open_floating_window(wm_class => 'findme'); -cmd 'sticky enable'; -open_window; -cmd 'workspace ' . $ws; - -is(get_focused($ws), $focused, 'the tiling container has focus'); -cmd '[class="findme"] kill'; - -############################################################################### -# 5: Given a focused sticky floating container and a tiling container on the -# target workspace, when the workspace is switched, then the tiling container -# is focused. -############################################################################### -$ws = fresh_workspace; -open_window; -$tmp = fresh_workspace; -open_floating_window(wm_class => 'findme'); -$focused = get_focused($tmp); -cmd 'sticky enable'; -cmd 'workspace ' . $ws; - -is(get_focused($ws), $focused, 'the sticky container has focus'); -cmd '[class="findme"] kill'; - -############################################################################### -# 6: Given a floating container on a non-visible workspace, when the window -# is made sticky, then the window immediately jumps to the currently -# visible workspace. -############################################################################### -fresh_workspace; -open_floating_window(wm_class => 'findme'); -cmd 'mark sticky'; -$ws = fresh_workspace; -cmd '[con_mark=sticky] sticky enable'; - -is(@{get_ws($ws)->{floating_nodes}}, 1, 'the sticky window jumps to the front'); -cmd '[class="findme"] kill'; - -############################################################################### - -done_testing; diff --git a/testcases/t/262-root-window-mouse-binding.t b/testcases/t/262-root-window-mouse-binding.t deleted file mode 100644 index c8fd89ef..00000000 --- a/testcases/t/262-root-window-mouse-binding.t +++ /dev/null @@ -1,42 +0,0 @@ -#!perl -# vim:ts=4:sw=4:expandtab -# -# Please read the following documents before working on tests: -# • http://build.i3wm.org/docs/testsuite.html -# (or docs/testsuite) -# -# • http://build.i3wm.org/docs/lib-i3test.html -# (alternatively: perldoc ./testcases/lib/i3test.pm) -# -# • http://build.i3wm.org/docs/ipc.html -# (or docs/ipc) -# -# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf -# (unless you are already familiar with Perl) -# -# Verifies that mouse bindings work on the root window if -# --whole-window is set. -# Ticket: #2115 -use i3test i3_autostart => 0; -use i3test::XTEST; - -my $config = < 0; - -#################################################################### -# 1: check that the borders are present on a floating windows -##################################################################### - -my $config = <{floating_nodes}}; -ok(@floating == 1, 'one floating container opened'); -is($floating[0]->{nodes}[0]->{current_border_width}, 2, 'floating current border width set to 2'); -is($floatwindow->rect->width, $floating[0]->{rect}->{width} - 2*2, 'floating border width 2'); - -exit_gracefully($pid); - -##################################################################### -# 2: check that the borders are present on a workspace with two tiled -# windows visible -##################################################################### - -$config = <{nodes}}; -ok(@tiled == 2, 'two tiled container opened'); -is($tiled[0]->{current_border_width}, 2, 'first tiled current border width set to 2'); -is($tilewindow->rect->width, $tiled[0]->{rect}->{width} - 2*2, 'first tiled border width 2'); -is($tiled[1]->{current_border_width}, 2, 'second tiled current border width set to 2'); -is($tilewindow2->rect->width, $tiled[1]->{rect}->{width} - 2*2, 'second tiled border width 2'); - -exit_gracefully($pid); - -##################################################################### -# 3: check that the borders are hidden on a workspace with one tiled -# window visible -##################################################################### - -$config = <{nodes}}; -ok(@tiled == 1, 'one tiled container opened'); -is($tiled[0]->{current_border_width}, 2, 'tiled current border width set to 2'); -is($tilewindow->rect->width, $tiled[0]->{rect}->{width} - 2*0, 'single tiled border width 0'); - -exit_gracefully($pid); - -##################################################################### -# 4: check that the borders are present on a workspace with two tiled -# windows visible, recursively -##################################################################### - -$config = < back to one container'); - -cmd 'focus parent'; -my $tilewindow3 = open_window; -ok(@{get_ws_content($tmp)} == 2, 'after split & new window, two containers'); - -$wscontent = get_ws($tmp); - -# Ensure i3’s X11 requests are processed before our inquiry via -# $tilewindow->rect: -sync_with_i3; - -@tiled = @{$wscontent->{nodes}}; -ok(@tiled == 2, 'two tiled container opened in another container'); -is($tiled[0]->{current_border_width}, -1, 'first tiled current border width set to -1'); -is($tilewindow->rect->width, $tiled[0]->{rect}->{width} - 2*2, 'first tiled border width 2'); -is($tiled[1]->{current_border_width}, 2, 'second tiled current border width set to 2'); -is($tilewindow2->rect->width, $tiled[1]->{rect}->{width} - 2*2, 'second tiled border width 2'); - -exit_gracefully($pid); - -done_testing; diff --git a/testcases/t/263-i3-floating-window-atom.t b/testcases/t/263-i3-floating-window-atom.t deleted file mode 100644 index 43b69ccb..00000000 --- a/testcases/t/263-i3-floating-window-atom.t +++ /dev/null @@ -1,70 +0,0 @@ -#!perl -# vim:ts=4:sw=4:expandtab -# -# Please read the following documents before working on tests: -# • http://build.i3wm.org/docs/testsuite.html -# (or docs/testsuite) -# -# • http://build.i3wm.org/docs/lib-i3test.html -# (alternatively: perldoc ./testcases/lib/i3test.pm) -# -# • http://build.i3wm.org/docs/ipc.html -# (or docs/ipc) -# -# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf -# (unless you are already familiar with Perl) -# -# Tests for our proprietary atom I3_FLOATING_WINDOW to allow -# identifying floating windows. -# Ticket: #2223 -use i3test; -use X11::XCB qw(:all); - -my ($con); - -sub has_i3_floating_window { - sync_with_i3; - - my ($con) = @_; - my $cookie = $x->get_property( - 0, - $con->{id}, - $x->atom(name => 'I3_FLOATING_WINDOW')->id, - $x->atom(name => 'CARDINAL')->id, - 0, - 1 - ); - - my $reply = $x->get_property_reply($cookie->{sequence}); - return 0 if $reply->{length} != 1; - - return unpack("L", $reply->{value}); -} - -############################################################################### -# Toggling floating on a container adds / removes I3_FLOATING_WINDOW. -############################################################################### - -fresh_workspace; - -$con = open_window; -is(has_i3_floating_window($con), 0, 'I3_FLOATING_WINDOW is not set'); - -cmd 'floating enable'; -is(has_i3_floating_window($con), 1, 'I3_FLOATING_WINDOW is set'); - -cmd 'floating disable'; -is(has_i3_floating_window($con), 0, 'I3_FLOATING_WINDOW is not set'); - -############################################################################### -# A window that is floated when managed has I3_FLOATING_WINDOW set. -############################################################################### -# -fresh_workspace; - -$con = open_floating_window; -is(has_i3_floating_window($con), 1, 'I3_FLOATING_WINDOW is set'); - -############################################################################### - -done_testing; diff --git a/testcases/t/264-ipc-shutdown-event.t b/testcases/t/264-ipc-shutdown-event.t deleted file mode 100644 index 379b9bf2..00000000 --- a/testcases/t/264-ipc-shutdown-event.t +++ /dev/null @@ -1,71 +0,0 @@ -#!perl -# vim:ts=4:sw=4:expandtab -# -# Please read the following documents before working on tests: -# • http://build.i3wm.org/docs/testsuite.html -# (or docs/testsuite) -# -# • http://build.i3wm.org/docs/lib-i3test.html -# (alternatively: perldoc ./testcases/lib/i3test.pm) -# -# • http://build.i3wm.org/docs/ipc.html -# (or docs/ipc) -# -# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf -# (unless you are already familiar with Perl) -# -# Test the ipc shutdown event. This event is triggered when the connection to -# the ipc is about to shutdown because of a user action such as with a -# `restart` or `exit` command. The `change` field indicates why the ipc is -# shutting down. It can be either "restart" or "exit". -# -# Ticket: #2318 -# Bug still in: 4.12-46-g2123888 -use i3test; - -SKIP: { - skip "AnyEvent::I3 too old (need >= 0.17)", 1 if $AnyEvent::I3::VERSION < 0.17; - -my $i3 = i3(get_socket_path()); -$i3->connect->recv; - -my $cv = AE::cv; -my $timer = AE::timer 0.5, 0, sub { $cv->send(0); }; - -$i3->subscribe({ - shutdown => sub { - $cv->send(shift); - } - })->recv; - -cmd 'restart'; - -my $e = $cv->recv; - -diag "Event:\n", Dumper($e); -ok($e, 'the shutdown event should emit when the ipc is restarted by command'); -is($e->{change}, 'restart', 'the `change` field should tell the reason for the shutdown'); - -# restarting kills the ipc client so we have to make a new one -$i3 = i3(get_socket_path()); -$i3->connect->recv; - -$cv = AE::cv; -$timer = AE::timer 0.5, 0, sub { $cv->send(0); }; - -$i3->subscribe({ - shutdown => sub { - $cv->send(shift); - } - })->recv; - -cmd 'exit'; - -$e = $cv->recv; - -diag "Event:\n", Dumper($e); -ok($e, 'the shutdown event should emit when the ipc is exited by command'); -is($e->{change}, 'exit', 'the `change` field should tell the reason for the shutdown'); -} - -done_testing; diff --git a/testcases/t/264-keypress-numlock.t b/testcases/t/264-keypress-numlock.t deleted file mode 100644 index fcc39ead..00000000 --- a/testcases/t/264-keypress-numlock.t +++ /dev/null @@ -1,390 +0,0 @@ -#!perl -# vim:ts=4:sw=4:expandtab -# -# Please read the following documents before working on tests: -# • http://build.i3wm.org/docs/testsuite.html -# (or docs/testsuite) -# -# • http://build.i3wm.org/docs/lib-i3test.html -# (alternatively: perldoc ./testcases/lib/i3test.pm) -# -# • http://build.i3wm.org/docs/ipc.html -# (or docs/ipc) -# -# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf -# (unless you are already familiar with Perl) -# -# Verifies that one can bind on numpad keys in different numlock states. -# Ticket: #2346 -# Bug still in: 4.12-78-g85bb324 -use i3test i3_autostart => 0; -use i3test::XTEST; -use ExtUtils::PkgConfig; - -SKIP: { - skip "libxcb-xkb too old (need >= 1.11)", 1 unless - ExtUtils::PkgConfig->atleast_version('xcb-xkb', '1.11'); - -my $config = < 0; - -my $config = < 'mark_A'); -$B = open_window(wm_class => 'mark_B'); -$expected_focus = get_focused($ws); - -cmd '[con_mark=B] swap container with mark A'; - -$nodes = get_ws_content($ws); -is($nodes->[0]->{window}, $B->{id}, 'B is on the left'); -is($nodes->[1]->{window}, $A->{id}, 'A is on the right'); -is(get_focused($ws), $expected_focus, 'B is still focused'); - -kill_all_windows; - -############################################################################### -# Swap two containers with different parents. -# In this test, the focus head of the left v-split container is A. -# The focused container is B. -# -# +---+---+ Layout: H1[ V1[ A Y ] V2[ X B ] ] -# | A | X | Focus Stacks: -# +---+---+ H1: V2, V1 -# | Y | B | V1: A, Y -# +---+---+ V2: B, X -############################################################################### -$ws = fresh_workspace; - -$A = open_window(wm_class => 'mark_A'); -$B = open_window(wm_class => 'mark_B'); -cmd 'split v'; -open_window; -cmd 'move up, focus left'; -cmd 'split v'; -open_window; -cmd 'focus up, focus right, focus down'; -$expected_focus = get_focused($ws); - -cmd '[con_mark=B] swap container with mark A'; - -$nodes = get_ws_content($ws); -is($nodes->[0]->{nodes}->[0]->{window}, $B->{id}, 'B is on the top left'); -is($nodes->[1]->{nodes}->[1]->{window}, $A->{id}, 'A is on the bottom right'); -is(get_focused($ws), $expected_focus, 'B is still focused'); - -kill_all_windows; - -############################################################################### -# Swap two containers with different parents. -# In this test, the focus head of the left v-split container is _not_ A. -# The focused container is B. -# -# +---+---+ Layout: H1[ V1[ A Y ] V2[ X B ] ] -# | A | X | Focus Stacks: -# +---+---+ H1: V2, V1 -# | Y | B | V1: Y, A -# +---+---+ V2: B, X -############################################################################### -$ws = fresh_workspace; - -$A = open_window(wm_class => 'mark_A'); -$B = open_window(wm_class => 'mark_B'); -cmd 'split v'; -open_window; -cmd 'move up, focus left'; -cmd 'split v'; -open_window; -cmd 'focus right, focus down'; -$expected_focus = get_focused($ws); - -cmd '[con_mark=B] swap container with mark A'; - -$nodes = get_ws_content($ws); -is($nodes->[0]->{nodes}->[0]->{window}, $B->{id}, 'B is on the top left'); -is($nodes->[1]->{nodes}->[1]->{window}, $A->{id}, 'A is on the bottom right'); -is(get_focused($ws), $expected_focus, 'B is still focused'); - -kill_all_windows; - -############################################################################### -# Swap two containers with one being on a different workspace. -# The focused container is B. -# -# Layout: O1[ W1[ H1 ] W2[ H2 ] ] -# Focus Stacks: -# O1: W2, W1 -# -# +---+---+ Layout: H1[ A X ] -# | A | X | Focus Stacks: -# +---+---+ H1: A, X -# -# +---+---+ Layout: H2[ Y, B ] -# | Y | B | Focus Stacks: -# +---+---+ H2: B, Y -############################################################################### -$ws1 = fresh_workspace; -$A = open_window(wm_class => 'mark_A'); -$expected_focus = get_focused($ws1); -open_window; -cmd 'focus left'; - -$ws2 = fresh_workspace; -open_window; -$B = open_window(wm_class => 'mark_B'); - -cmd '[con_mark=B] swap container with mark A'; - -$nodes = get_ws_content($ws1); -is($nodes->[0]->{window}, $B->{id}, 'B is on ws1:left'); - -$nodes = get_ws_content($ws2); -is($nodes->[1]->{window}, $A->{id}, 'A is on ws1:right'); -is(get_focused($ws2), $expected_focus, 'A is focused'); - -kill_all_windows; - -############################################################################### -# Swap two non-focused containers within the same workspace. -# -# +---+---+ Layout: H1[ V1[ A X ] V2[ F B ] ] -# | A | F | Focus Stacks: -# +---+---+ H1: V2, V1 -# | X | B | V1: A, X -# +---+---+ V2: F, B -############################################################################### -$ws = fresh_workspace; - -$A = open_window(wm_class => 'mark_A'); -$B = open_window(wm_class => 'mark_B'); -cmd 'split v'; -open_window; -cmd 'move up, focus left'; -cmd 'split v'; -open_window; -cmd 'focus up, focus right'; -$expected_focus = get_focused($ws); - -cmd '[con_mark=B] swap container with mark A'; - -$nodes = get_ws_content($ws); -is($nodes->[0]->{nodes}->[0]->{window}, $B->{id}, 'B is on the top left'); -is($nodes->[1]->{nodes}->[1]->{window}, $A->{id}, 'A is on the bottom right'); -is(get_focused($ws), $expected_focus, 'F is still focused'); - -kill_all_windows; - -############################################################################### -# Swap two non-focused containers which are both on different workspaces. -# -# Layout: O1[ W1[ A ] W2[ B ] W3[ F ] ] -# Focus Stacks: -# O1: W3, W2, W1 -# -# +---+ -# | A | -# +---+ -# -# +---+ -# | B | -# +---+ -# -# +---+ -# | F | -# +---+ -############################################################################### -$ws1 = fresh_workspace; -$A = open_window(wm_class => 'mark_A'); - -$ws2 = fresh_workspace; -$B = open_window(wm_class => 'mark_B'); - -$ws3 = fresh_workspace; -open_window; -$expected_focus = get_focused($ws3); - -cmd '[con_mark=B] swap container with mark A'; - -$nodes = get_ws_content($ws1); -is($nodes->[0]->{window}, $B->{id}, 'B is on the first workspace'); - -$nodes = get_ws_content($ws2); -is($nodes->[0]->{window}, $A->{id}, 'A is on the second workspace'); - -is(get_focused($ws3), $expected_focus, 'F is still focused'); - -kill_all_windows; - -############################################################################### -# Swap two non-focused containers with one being on a different workspace. -# -# Layout: O1[ W1[ A ] W2[ H2 ] ] -# Focus Stacks: -# O1: W2, W1 -# -# +---+ -# | A | -# +---+ -# -# +---+---+ Layout: H2[ B, F ] -# | B | F | Focus Stacks: -# +---+---+ H2: F, B -############################################################################### - -$ws1 = fresh_workspace; -$A = open_window(wm_class => 'mark_A'); - -$ws2 = fresh_workspace; -$B = open_window(wm_class => 'mark_B'); -open_window; -$expected_focus = get_focused($ws2); - -cmd '[con_mark=B] swap container with mark A'; - -$nodes = get_ws_content($ws1); -is($nodes->[0]->{window}, $B->{id}, 'B is on the first workspace'); - -$nodes = get_ws_content($ws2); -is($nodes->[0]->{window}, $A->{id}, 'A is on the left of the second workspace'); -is(get_focused($ws2), $expected_focus, 'F is still focused'); - -kill_all_windows; - -############################################################################### -# 1. A container cannot be swapped with its parent. -# 2. A container cannot be swapped with one of its children. -# -# ↓A↓ -# +---+---+ Layout: H1[ X V1[ Y B ] ] -# | | Y | (with A := V1) -# | X +---+ -# | | B | -# +---+---+ -############################################################################### -$ws = fresh_workspace; -open_window; -open_window; -cmd 'split v'; -$B = open_window(wm_class => 'mark_B'); -cmd 'focus parent, mark A, focus child'; - -$result = cmd '[con_mark=B] swap container with mark A'; -is($result->[0]->{success}, 0, 'B cannot be swappd with its parent'); - -$result = cmd '[con_mark=A] swap container with mark B'; -is($result->[0]->{success}, 0, 'A cannot be swappd with one of its children'); - -kill_all_windows; - -############################################################################### -# Swapping two containers preserves the geometry of the container they are -# being swapped with. -# -# Before: -# +---+-------+ -# | A | B | -# +---+-------+ -# -# After: -# +---+-------+ -# | B | A | -# +---+-------+ -############################################################################### -$ws = fresh_workspace; -$A = open_window(wm_class => 'mark_A'); -$B = open_window(wm_class => 'mark_B'); -cmd 'resize grow width 0 or 25 ppt'; - -# sanity checks -$nodes = get_ws_content($ws); -cmp_float($nodes->[0]->{percent}, 0.25, 'A has 25% width'); -cmp_float($nodes->[1]->{percent}, 0.75, 'B has 75% width'); - -cmd '[con_mark=B] swap container with mark A'; - -$nodes = get_ws_content($ws); -cmp_float($nodes->[0]->{percent}, 0.25, 'B has 25% width'); -cmp_float($nodes->[1]->{percent}, 0.75, 'A has 75% width'); - -kill_all_windows; - -############################################################################### -# Swapping containers not sharing the same parent preserves the geometry of -# the container they are swapped with. -# -# Before: -# +---+-----+ -# | A | | -# +---+ B | -# | | | -# | Y +-----+ -# | | X | -# +---+-----+ -# -# After: -# +---+-----+ -# | B | | -# +---+ A | -# | | | -# | Y +-----+ -# | | X | -# +---+-----+ -############################################################################### -$ws = fresh_workspace; - -$A = open_window(wm_class => 'mark_A'); -$B = open_window(wm_class => 'mark_B'); -cmd 'split v'; -open_window; -cmd 'focus up, resize grow height 0 or 25 ppt'; -cmd 'focus left, split v'; -open_window; -cmd 'resize grow height 0 or 25 ppt'; - -# sanity checks -$nodes = get_ws_content($ws); -cmp_float($nodes->[0]->{nodes}->[0]->{percent}, 0.25, 'A has 25% height'); -cmp_float($nodes->[1]->{nodes}->[0]->{percent}, 0.75, 'B has 75% height'); - -cmd '[con_mark=B] swap container with mark A'; - -$nodes = get_ws_content($ws); -cmp_float($nodes->[0]->{nodes}->[0]->{percent}, 0.25, 'B has 25% height'); -cmp_float($nodes->[1]->{nodes}->[0]->{percent}, 0.75, 'A has 75% height'); - -kill_all_windows; - -############################################################################### -# Swapping containers moves the urgency hint correctly. -############################################################################### - -$ws1 = fresh_workspace; -$A = open_window(wm_class => 'mark_A'); -$ws2 = fresh_workspace; -$B = open_window(wm_class => 'mark_B'); -open_window; - -$B->add_hint('urgency'); -sync_with_i3; - -cmd '[con_mark=B] swap container with mark A'; - -@urgent = grep { $_->{urgent} } @{get_ws_content($ws1)}; -is(@urgent, 1, 'B is marked urgent'); -is(get_ws($ws1)->{urgent}, 1, 'the first workspace is marked urgent'); - -@urgent = grep { $_->{urgent} } @{get_ws_content($ws2)}; -is(@urgent, 0, 'A is not marked urgent'); -is(get_ws($ws2)->{urgent}, 0, 'the second workspace is not marked urgent'); - -kill_all_windows; - -############################################################################### - -exit_gracefully($pid); - -done_testing; diff --git a/testcases/t/271-for_window_tilingfloating.t b/testcases/t/271-for_window_tilingfloating.t new file mode 100644 index 00000000..760ac53e --- /dev/null +++ b/testcases/t/271-for_window_tilingfloating.t @@ -0,0 +1,49 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • http://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • http://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • http://build.i3wm.org/docs/ipc.html +# (or docs/ipc) +# +# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf +# (unless you are already familiar with Perl) +# +use i3test i3_autostart => 0; +use X11::XCB qw(PROP_MODE_REPLACE); + +############################################################## +# 13: check that the tiling / floating criteria work. +############################################################## + +my $config = <<"EOT"; +# i3 config file (v4) +font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1 +for_window [tiling] mark tiled +for_window [floating] mark floated +EOT + +my $pid = launch_with_config($config); +my $tmp = fresh_workspace; + +open_window; +open_floating_window; + +my @nodes = @{get_ws($tmp)->{nodes}}; +cmp_ok(@nodes, '==', 1, 'one tiling container on this workspace'); +is_deeply($nodes[0]->{marks}, [ 'tiled' ], "mark set for 'tiling' criterion"); + +@nodes = @{get_ws($tmp)->{floating_nodes}}; +cmp_ok(@nodes, '==', 1, 'one floating container on this workspace'); +is_deeply($nodes[0]->{nodes}[0]->{marks}, [ 'floated' ], "mark set for 'floating' criterion"); + +exit_gracefully($pid); + +############################################################## + +done_testing; diff --git a/testcases/t/272-regress-focus-assign.t b/testcases/t/272-regress-focus-assign.t new file mode 100644 index 00000000..b010963b --- /dev/null +++ b/testcases/t/272-regress-focus-assign.t @@ -0,0 +1,77 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • http://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • http://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • http://build.i3wm.org/docs/ipc.html +# (or docs/ipc) +# +# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf +# (unless you are already familiar with Perl) +# +# Regression: Checks if focus is stolen when a window is managed which is +# assigned to an invisible workspace +# +use i3test i3_autostart => 0; + +sub open_special { + my %args = @_; + $args{name} //= 'special window'; + + # We use dont_map because i3 will not map the window on the current + # workspace. Thus, open_window would time out in wait_for_map (2 seconds). + my $window = open_window( + %args, + wm_class => 'special', + dont_map => 1, + ); + $window->map; + return $window; +} + +##################################################################### +# start a window and see that it does not get assigned with an empty config +##################################################################### + +my $config = <{focused}, 'current workspace focused'); + +my $window = open_special; +sync_with_i3; + +ok(@{get_ws_content($tmp)} == 0, 'special window not on current workspace'); +ok(@{get_ws_content('targetws')} == 1, 'special window on targetws'); +ok(get_ws($tmp)->{focused}, 'current workspace still focused'); + +##################################################################### +# the same test, but with a floating window +##################################################################### + +$window = open_special( + window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_UTILITY'), +); + +ok(@{get_ws_content($tmp)} == 0, 'special window not on current workspace'); +ok(@{get_ws_content('targetws')} == 1, 'special window on targetws'); +ok(get_ws($tmp)->{focused}, 'current workspace still focused'); + +exit_gracefully($pid); + +$window->destroy; + +done_testing; diff --git a/testcases/t/273-regress-focus-toggle.t b/testcases/t/273-regress-focus-toggle.t new file mode 100644 index 00000000..192e9753 --- /dev/null +++ b/testcases/t/273-regress-focus-toggle.t @@ -0,0 +1,30 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • http://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • http://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • http://build.i3wm.org/docs/ipc.html +# (or docs/ipc) +# +# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf +# (unless you are already familiar with Perl) +# +# Regression: Checks if i3 still lives after using 'focus mode_toggle' on an +# empty workspace. This regression was fixed in +# 0848844f2d41055f6ffc69af1149d7a873460976. +# +use i3test; +use v5.10; + +my $tmp = fresh_workspace; + +cmd 'focus mode_toggle'; + +does_i3_live; + +done_testing; diff --git a/testcases/t/274-move-branch-position.t b/testcases/t/274-move-branch-position.t new file mode 100644 index 00000000..c2928c9e --- /dev/null +++ b/testcases/t/274-move-branch-position.t @@ -0,0 +1,376 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • http://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • http://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • http://build.i3wm.org/docs/ipc.html +# (or docs/ipc) +# +# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf +# (unless you are already familiar with Perl) +# +# Test that movement of a con into a branch will place the moving con at the +# correct position within the branch. +# +# If the direction of movement is the same as the orientation of the branch +# container, append or prepend the container to the branch in the obvious way. +# If the movement is to the right or downward, insert the moving container in +# the first position (i.e., the leftmost or top position resp.) If the movement +# is to the left or upward, insert the moving container in the last position +# (i.e., the rightmost or bottom position resp.) +# +# If the direction of movement is different from the orientation of the branch +# container, insert the container into the branch after the focused-inactive +# container. +# +# For testing purposes, we will demonstrate the behavior for tabbed containers +# to represent the case of split-horizontal branches and stacked containers to +# represent the case of split-vertical branches. +# +# Ticket: #1060 +# Bug still in: 4.6-109-g18cfc36 + +use i3test; + +# Opens tabs on the presently focused branch and adds several additional +# windows. Shifts focus to somewhere in the middle of the tabs so the most +# general case can be assumed. +sub open_tabs { + cmd 'layout tabbed'; + open_window; + open_window; + open_window; + open_window; + cmd 'focus left; focus left' +} + +# Likewise for a stack +sub open_stack { + cmd 'layout stacking'; + open_window; + open_window; + open_window; + open_window; + cmd 'focus up; focus up' +} + +# Gets the position of the given leaf within the given branch. The first +# position is one (1). Returns negative one (-1) if the leaf cannot be found +# within the branch. +sub get_leaf_position { + my ($branch, $leaf) = @_; + my $position = -1; + for my $i (0 .. @{$branch->{nodes}}) { + if ($branch->{nodes}[$i]->{id} == $leaf) { + $position = $i + 1; + last; + }; + } + return $position; +} + +# convenience function to focus a con by id to avoid having to type an ugly +# command each time +sub focus_con { + my $con_id = shift @_; + cmd "[con_id=\"$con_id\"] focus"; +} + +# Places a leaf into a branch and focuses the leaf. The newly created branch +# will have orientation specified by the second parameter. +sub branchify { + my ($con_id, $orientation) = @_; + focus_con($con_id); + $orientation eq 'horizontal' ? cmd 'splith' : cmd 'splitv'; + open_window; + focus_con($con_id); +} + +############################################################################## +# When moving a con right into tabs, the moving con should be placed as the +# first tab in the branch +############################################################################## +my $ws = fresh_workspace; + +# create the target leaf +open_window; +my $target_leaf = get_focused($ws); + +# create the tabbed branch container +open_window; +cmd 'splith'; +open_tabs; + +# move the target leaf into the tabbed branch +focus_con($target_leaf); +cmd 'move right'; + +# the target leaf should be the first in the branch +my $branch = shift @{get_ws_content($ws)}; +is($branch->{nodes}[0]->{id}, $target_leaf, 'moving con right into tabs placed it as the first tab in the branch'); + +# repeat the test when the target is in a branch +cmd 'move up; move left'; +branchify($target_leaf, 'vertical'); +cmd 'move right'; + +$branch = pop @{get_ws_content($ws)}; +is($branch->{nodes}[0]->{id}, $target_leaf, 'moving con right into tabs from a branch placed it as the first tab in the branch'); + +############################################################################## +# When moving a con right into a stack, the moving con should be placed +# below the focused-inactive leaf +############################################################################## +$ws = fresh_workspace; + +# create the target leaf +open_window; +$target_leaf = get_focused($ws); + +# create the stacked branch container and find the focused leaf +open_window; +cmd 'splith'; +open_stack; +my $secondary_leaf = get_focused($ws); + +# move the target leaf into the stacked branch +focus_con($target_leaf); +cmd 'move right'; + +# the secondary focus leaf should be below the target +$branch = shift @{get_ws_content($ws)}; +my $target_leaf_position = get_leaf_position($branch, $target_leaf); +my $secondary_leaf_position = get_leaf_position($branch, $secondary_leaf); + +is($target_leaf_position, $secondary_leaf_position + 1, 'moving con right into a stack placed it below the focused-inactive leaf'); + +# repeat the test when the target is in a branch +cmd 'move up; move left'; +branchify($target_leaf, 'vertical'); +cmd 'move right'; + +$branch = pop @{get_ws_content($ws)}; +$target_leaf_position = get_leaf_position($branch, $target_leaf); +$secondary_leaf_position = get_leaf_position($branch, $secondary_leaf); + +is($target_leaf_position, $secondary_leaf_position + 1, 'moving con right into a stack from a branch placed it below the focused-inactive leaf'); + +############################################################################## +# When moving a con down into a stack, the moving con should be placed at the +# top of the stack +############################################################################## +$ws = fresh_workspace; +cmd 'layout splitv'; + +# create the target leaf +open_window; +$target_leaf = get_focused($ws); + +# create the stacked branch container +open_window; +cmd 'splitv'; +open_stack; + +# move the target leaf into the stacked branch +focus_con($target_leaf); +cmd 'move down'; + +# the target leaf should be on the top of the stack +$branch = shift @{get_ws_content($ws)}; +is($branch->{nodes}[0]->{id}, $target_leaf, 'moving con down into a stack placed it on the top of the stack'); + +# repeat the test when the target is in a branch +cmd 'move right; move up'; +branchify($target_leaf, 'horizontal'); +cmd 'move down'; + +$branch = pop @{get_ws_content($ws)}; +is($branch->{nodes}[0]->{id}, $target_leaf, 'moving con down into a stack from a branch placed it on the top of the stack'); + +############################################################################## +# When moving a con down into tabs, the moving con should be placed after the +# focused-inactive tab +############################################################################## +$ws = fresh_workspace; +cmd 'layout splitv'; + +# create the target leaf +open_window; +$target_leaf = get_focused($ws); + +# create the tabbed branch container and find the focused tab +open_window; +cmd 'splitv'; +open_tabs; +$secondary_leaf = get_focused($ws); + +# move the target leaf into the tabbed branch +focus_con($target_leaf); +cmd 'move down'; + +# the secondary focus tab should be to the right +$branch = shift @{get_ws_content($ws)}; +$target_leaf_position = get_leaf_position($branch, $target_leaf); +$secondary_leaf_position = get_leaf_position($branch, $secondary_leaf); + +is($target_leaf_position, $secondary_leaf_position + 1, 'moving con down into tabs placed it after the focused-inactive tab'); + +# repeat the test when the target is in a branch +cmd 'move right; move up'; +branchify($target_leaf, 'horizontal'); +cmd 'move down'; + +$branch = pop @{get_ws_content($ws)}; +$target_leaf_position = get_leaf_position($branch, $target_leaf); +$secondary_leaf_position = get_leaf_position($branch, $secondary_leaf); + +is($target_leaf_position, $secondary_leaf_position + 1, 'moving con down into tabs from a branch placed it after the focused-inactive tab'); + +############################################################################## +# When moving a con left into tabs, the moving con should be placed as the last +# tab in the branch +############################################################################## +$ws = fresh_workspace; + +# create the tabbed branch container +open_window; +cmd 'splith'; +open_tabs; + +# create the target leaf +cmd 'focus parent'; +open_window; +$target_leaf = get_focused($ws); + +# move the target leaf into the tabbed branch +cmd 'move left'; + +# the target leaf should be last in the branch +$branch = shift @{get_ws_content($ws)}; + +is($branch->{nodes}->[-1]->{id}, $target_leaf, 'moving con left into tabs placed it as the last tab in the branch'); + +# repeat the test when the target leaf is in a branch +cmd 'move up; move right'; +branchify($target_leaf, 'vertical'); +cmd 'move left'; + +$branch = shift @{get_ws_content($ws)}; +is($branch->{nodes}->[-1]->{id}, $target_leaf, 'moving con left into tabs from a branch placed it as the last tab in the branch'); + +############################################################################## +# When moving a con left into a stack, the moving con should be placed below +# the focused-inactive leaf +############################################################################## +$ws = fresh_workspace; + +# create the stacked branch container and find the focused leaf +open_window; +open_stack; +$secondary_leaf = get_focused($ws); + +# create the target leaf to the right +cmd 'focus parent'; +open_window; +$target_leaf = get_focused($ws); + +# move the target leaf into the stacked branch +cmd 'move left'; + +# the secondary focus leaf should be below +$branch = shift @{get_ws_content($ws)}; +$target_leaf_position = get_leaf_position($branch, $target_leaf); +$secondary_leaf_position = get_leaf_position($branch, $secondary_leaf); + +is($target_leaf_position, $secondary_leaf_position + 1, 'moving con left into a stack placed it below the focused-inactive leaf'); + +# repeat the test when the target leaf is in a branch +cmd 'move up; move right'; +branchify($target_leaf, 'vertical'); +cmd 'move left'; + +$branch = shift @{get_ws_content($ws)}; +$target_leaf_position = get_leaf_position($branch, $target_leaf); +$secondary_leaf_position = get_leaf_position($branch, $secondary_leaf); + +is($target_leaf_position, $secondary_leaf_position + 1, 'moving con left into a stack from a branch placed it below the focused-inactive leaf'); + +############################################################################## +# When moving a con up into a stack, the moving con should be placed last in +# the stack +############################################################################## +$ws = fresh_workspace; +cmd 'layout splitv'; + +# create the stacked branch container +open_window; +cmd 'splitv'; +open_stack; + +# create the target leaf +cmd 'focus parent'; +open_window; +$target_leaf = get_focused($ws); + +# move the target leaf into the stacked branch +cmd 'move up'; + +# the target leaf should be on the bottom of the stack +$branch = shift @{get_ws_content($ws)}; + +is($branch->{nodes}->[-1]->{id}, $target_leaf, 'moving con up into stack placed it on the bottom of the stack'); + +# repeat the test when the target leaf is in a branch +cmd 'move right; move down'; +branchify($target_leaf, 'horizontal'); +cmd 'move up'; + +$branch = shift @{get_ws_content($ws)}; + +is($branch->{nodes}->[-1]->{id}, $target_leaf, 'moving con up into stack from a branch placed it on the bottom of the stack'); + +############################################################################## +# When moving a con up into tabs, the moving con should be placed after the +# focused-inactive tab +############################################################################## +$ws = fresh_workspace; +cmd 'layout splitv'; + +# create the tabbed branch container and find the focused leaf +open_window; +cmd 'splitv'; +open_tabs; +$secondary_leaf = get_focused($ws); + +# create the target leaf below +cmd 'focus parent'; +open_window; +$target_leaf = get_focused($ws); + +# move the target leaf into the tabbed branch +cmd 'move up'; + +# the secondary focus tab should be to the right +$branch = shift @{get_ws_content($ws)}; +$target_leaf_position = get_leaf_position($branch, $target_leaf); +$secondary_leaf_position = get_leaf_position($branch, $secondary_leaf); + +is($target_leaf_position, $secondary_leaf_position + 1, 'moving con up into tabs placed it after the focused-inactive tab'); + +# repeat the test when the target leaf is in a branch +cmd 'move right; move down'; +branchify($target_leaf, 'horizontal'); +cmd 'move up'; + +$branch = shift @{get_ws_content($ws)}; +$target_leaf_position = get_leaf_position($branch, $target_leaf); +$secondary_leaf_position = get_leaf_position($branch, $secondary_leaf); + +is($target_leaf_position, $secondary_leaf_position + 1, 'moving con up into tabs from a branch placed it after the focused-inactive tab'); + +done_testing; diff --git a/testcases/t/275-ipc-window-close.t b/testcases/t/275-ipc-window-close.t new file mode 100644 index 00000000..3483cf42 --- /dev/null +++ b/testcases/t/275-ipc-window-close.t @@ -0,0 +1,52 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • http://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • http://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • http://build.i3wm.org/docs/ipc.html +# (or docs/ipc) +# +# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf +# (unless you are already familiar with Perl) +# +# Tests that the ipc close event works properly +# +# Bug still in: 4.8-7-gf4a8253 +use i3test; + +my $i3 = i3(get_socket_path()); +$i3->connect()->recv; + +my $cv; +my $t; + +sub reset_test { + $cv = AE::cv; + $t = AE::timer(0.5, 0, sub { $cv->send(0); }); +} + +reset_test; + +$i3->subscribe({ + window => sub { + my ($e) = @_; + if ($e->{change} eq 'close') { + $cv->send($e->{container}); + } + }, + })->recv; + +my $window = open_window; + +cmd 'kill'; +my $con = $cv->recv; + +ok($con, 'closing a window should send the window::close event'); +is($con->{window}, $window->{id}, 'the event should contain information about the window'); + +done_testing; diff --git a/testcases/t/276-ipc-window-move.t b/testcases/t/276-ipc-window-move.t new file mode 100644 index 00000000..117d27fb --- /dev/null +++ b/testcases/t/276-ipc-window-move.t @@ -0,0 +1,61 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • http://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • http://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • http://build.i3wm.org/docs/ipc.html +# (or docs/ipc) +# +# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf +# (unless you are already familiar with Perl) +# +# Tests that the ipc window::move event works properly +# +# Bug still in: 4.8-7-gf4a8253 +use i3test; + +my $i3 = i3(get_socket_path()); +$i3->connect()->recv; + +my $cv; +my $t; + +sub reset_test { + $cv = AE::cv; + $t = AE::timer(0.5, 0, sub { $cv->send(0); }); +} + +reset_test; + +$i3->subscribe({ + window => sub { + my ($e) = @_; + if ($e->{change} eq 'move') { + $cv->send($e->{container}); + } + }, + })->recv; + +my $dummy_window = open_window; +my $window = open_window; + +cmd 'move right'; +my $con = $cv->recv; + +ok($con, 'moving a window should emit the window::move event'); +is($con->{window}, $window->{id}, 'the event should contain info about the window'); + +reset_test; + +cmd 'move to workspace ws_new'; +$con = $cv->recv; + +ok($con, 'moving a window to a different workspace should emit the window::move event'); +is($con->{window}, $window->{id}, 'the event should contain info about the window'); + +done_testing; diff --git a/testcases/t/277-ipc-window-urgent.t b/testcases/t/277-ipc-window-urgent.t new file mode 100644 index 00000000..09226ff1 --- /dev/null +++ b/testcases/t/277-ipc-window-urgent.t @@ -0,0 +1,68 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • http://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • http://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • http://build.i3wm.org/docs/ipc.html +# (or docs/ipc) +# +# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf +# (unless you are already familiar with Perl) +# +# Test that the window::urgent event works correctly. The window::urgent event +# should be emitted when a window becomes urgent or loses its urgent status. +# +use i3test; + +my $config = <connect()->recv; + +my $cv; +$i3->subscribe({ + window => sub { + my ($event) = @_; + $cv->send($event) if $event->{change} eq 'urgent'; + } +})->recv; + +my $t; +$t = AnyEvent->timer( + after => 0.5, + cb => sub { + $cv->send(0); + } +); + +$cv = AnyEvent->condvar; +fresh_workspace; +my $win = open_window; +my $dummy_win = open_window; + +$win->add_hint('urgency'); +my $event = $cv->recv; + +isnt($event, 0, 'an urgent con should emit the window::urgent event'); +is($event->{container}->{window}, $win->{id}, 'the event should contain information about the window'); +is($event->{container}->{urgent}, 1, 'the container should be urgent'); + +$cv = AnyEvent->condvar; +$win->delete_hint('urgency'); +$event = $cv->recv; + +isnt($event, 0, 'an urgent con should emit the window::urgent event'); +is($event->{container}->{window}, $win->{id}, 'the event should contain information about the window'); +is($event->{container}->{urgent}, 0, 'the container should not be urgent'); + +done_testing; diff --git a/testcases/t/278-layout-restore-output.t b/testcases/t/278-layout-restore-output.t new file mode 100644 index 00000000..5a1f3763 --- /dev/null +++ b/testcases/t/278-layout-restore-output.t @@ -0,0 +1,234 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • http://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • http://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • http://build.i3wm.org/docs/ipc.html +# (or docs/ipc) +# +# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf +# (unless you are already familiar with Perl) +# +# Verifies that entire outputs can be saved and restored properly by i3. +# Ticket: #1306 +# Bug still in: 4.8-26-gf96ec19 +use i3test; +use File::Temp qw(tempfile); +use IO::Handle; + +my $ws = fresh_workspace; + +################################################################################ +# Append a new workspace with a name. +################################################################################ + +ok(!workspace_exists('ws_new'), 'workspace "ws_new" does not exist yet'); + +my ($fh, $filename) = tempfile(UNLINK => 1); +print $fh <<'EOT'; +// vim:ts=4:sw=4:et +{ + // workspace with 1 children + "border": "pixel", + "floating": "auto_off", + "layout": "splith", + "percent": null, + "type": "workspace", + "name": "ws_new", + "nodes": [ + { + "border": "pixel", + "floating": "auto_off", + "geometry": { + "height": 268, + "width": 484, + "x": 0, + "y": 0 + }, + "name": "vals@w00t: ~", + "percent": 1, + "swallows": [ + { + "class": "^URxvt$" + // "instance": "^urxvt$", + // "title": "^vals\\@w00t\\:\\ \\~$" + } + ], + "type": "con" + } + ] +} +EOT +$fh->flush; +cmd "append_layout $filename"; + +ok(workspace_exists('ws_new'), 'workspace "ws_new" exists now'); + +does_i3_live; + +close($fh); + +################################################################################ +# Append a new workspace with a name that clashes with an existing workspace. +################################################################################ + +my @old_workspaces = @{get_workspace_names()}; + +cmd "append_layout $filename"; + +my @new_workspaces = @{get_workspace_names()}; +cmp_ok(scalar @new_workspaces, '>', scalar @old_workspaces, 'more workspaces than before'); + +my %created_workspaces = map { ($_, 1) } @new_workspaces; +delete $created_workspaces{$_} for @old_workspaces; +diag('created workspaces = ' . Dumper(keys %created_workspaces)); +cmp_ok(scalar keys %created_workspaces, '>', 0, 'new workspaces appeared'); + +################################################################################ +# Append a new workspace without a name. +################################################################################ + +ok(!workspace_exists('unnamed'), 'workspace "unnamed" does not exist yet'); + +($fh, $filename) = tempfile(UNLINK => 1); +print $fh <<'EOT'; +// vim:ts=4:sw=4:et +{ + // workspace with 1 children + "border": "pixel", + "floating": "auto_off", + "layout": "splith", + "percent": null, + "type": "workspace", + "nodes": [ + { + "border": "pixel", + "floating": "auto_off", + "geometry": { + "height": 268, + "width": 484, + "x": 0, + "y": 0 + }, + "name": "vals@w00t: ~", + "percent": 1, + "swallows": [ + { + "class": "^URxvt$" + // "instance": "^urxvt$", + // "title": "^vals\\@w00t\\:\\ \\~$" + } + ], + "type": "con" + } + ] +} +EOT +$fh->flush; +cmd "append_layout $filename"; + +ok(workspace_exists('unnamed'), 'workspace "unnamed" exists now'); + +################################################################################ +# Append a workspace with a numeric name, ensure it has ->num set. +################################################################################ + +ok(!workspace_exists('4'), 'workspace "4" does not exist yet'); + +($fh, $filename) = tempfile(UNLINK => 1); +print $fh <<'EOT'; +// vim:ts=4:sw=4:et +{ + // workspace with 1 children + "border": "pixel", + "floating": "auto_off", + "layout": "splith", + "percent": null, + "type": "workspace", + "name": "4", + "nodes": [ + { + "border": "pixel", + "floating": "auto_off", + "geometry": { + "height": 268, + "width": 484, + "x": 0, + "y": 0 + }, + "name": "vals@w00t: ~", + "percent": 1, + "swallows": [ + { + "class": "^URxvt$" + // "instance": "^urxvt$", + // "title": "^vals\\@w00t\\:\\ \\~$" + } + ], + "type": "con" + } + ] +} +EOT +$fh->flush; +cmd "append_layout $filename"; + +ok(workspace_exists('4'), 'workspace "4" exists now'); +$ws = get_ws("4"); +is($ws->{num}, 4, 'workspace number is 4'); + +################################################################################ +# Append a workspace with a numeric name, with the “type” property at the end +# of the JSON blurb (which is valid and sometimes happens). +################################################################################ + +ok(!workspace_exists('5'), 'workspace "5" does not exist yet'); + +($fh, $filename) = tempfile(UNLINK => 1); +print $fh <<'EOT'; +// vim:ts=4:sw=4:et +{ + // workspace with 1 children + "border": "pixel", + "floating": "auto_off", + "layout": "splith", + "percent": null, + "name": "5", + "nodes": [ + { + "border": "pixel", + "floating": "auto_off", + "geometry": { + "height": 268, + "width": 484, + "x": 0, + "y": 0 + }, + "name": "vals@w00t: ~", + "percent": 1, + "swallows": [ + { + "class": "^URxvt$" + // "instance": "^urxvt$", + // "title": "^vals\\@w00t\\:\\ \\~$" + } + ], + "type": "con" + } + ], + "type": "workspace" +} +EOT +$fh->flush; +cmd "append_layout $filename"; + +ok(workspace_exists('5'), 'workspace "5" exists now'); +$ws = get_ws("5"); +is($ws->{num}, 5, 'workspace number is 5'); + +done_testing; diff --git a/testcases/t/279-regress-default-floating-border.t b/testcases/t/279-regress-default-floating-border.t new file mode 100644 index 00000000..d5994f58 --- /dev/null +++ b/testcases/t/279-regress-default-floating-border.t @@ -0,0 +1,43 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • http://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • http://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • http://build.i3wm.org/docs/ipc.html +# (or docs/ipc) +# +# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf +# (unless you are already familiar with Perl) +# +# This is a regression test for a bug where a normal floating default border is +# not applied when the default tiling border is set to a pixel value. +# Ticket: #1305 +# Bug still in: 4.8-62-g7381b50 +use i3test i3_autostart => 0; + +my $config = <{floating_nodes}}; + +is($floating[0]->{nodes}[0]->{border}, 'normal', 'default floating border is `normal`'); + +exit_gracefully($pid); + +done_testing; diff --git a/testcases/t/280-wm-class-change-handler.t b/testcases/t/280-wm-class-change-handler.t new file mode 100644 index 00000000..ce237b57 --- /dev/null +++ b/testcases/t/280-wm-class-change-handler.t @@ -0,0 +1,78 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • http://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • http://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • http://build.i3wm.org/docs/ipc.html +# (or docs/ipc) +# +# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf +# (unless you are already familiar with Perl) +# +# Test that changes to WM_CLASS are internally processed by i3 by updating the +# cached property and running assignments. This allows the property to be used +# in criteria selection +# Ticket: #1052 +# Bug still in: 4.8-73-g6bf7f8e +use i3test i3_autostart => 0; +use X11::XCB qw(PROP_MODE_REPLACE); + +my $config = <atom(name => 'WM_CLASS'); + my $atomtype = $x->atom(name => 'STRING'); + $length ||= length($class) + 1; + $x->change_property( + PROP_MODE_REPLACE, + $window->id, + $atomname->id, + $atomtype->id, + 8, + $length, + $class + ); + sync_with_i3; +} + +my $ws = fresh_workspace; + +my $win = open_window; + +change_window_class($win, "special\0Special"); + +my $con = @{get_ws_content($ws)}[0]; + +is($con->{window_properties}->{class}, 'Special', + 'The container class should be updated when a window changes class'); + +is($con->{window_properties}->{instance}, 'special', + 'The container instance should be updated when a window changes instance'); + +# The mark `special_class_mark` is added in a `for_window` assignment in the +# config for testing purposes +is_deeply($con->{marks}, [ 'special_class_mark' ], + 'A `for_window` assignment should run for a match when the window changes class'); + +change_window_class($win, "abcdefghijklmnopqrstuv\0abcd", 24); + +$con = @{get_ws_content($ws)}[0]; + +is($con->{window_properties}->{class}, 'a', + 'Non-null-terminated strings should be handled correctly'); + +exit_gracefully($pid); + +done_testing; diff --git a/testcases/t/281-regress-reload-bindsym.t b/testcases/t/281-regress-reload-bindsym.t new file mode 100644 index 00000000..6d5d12c3 --- /dev/null +++ b/testcases/t/281-regress-reload-bindsym.t @@ -0,0 +1,45 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • http://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • http://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • http://build.i3wm.org/docs/ipc.html +# (or docs/ipc) +# +# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf +# (unless you are already familiar with Perl) +# +# Test that the binding event works properly +# Ticket: #1210 +use i3test i3_autostart => 0; + +my $config = < /dev/null); + + skip 'xdotool is required to test the binding event. `[apt-get install|pacman -S] xdotool`', 1 if $?; + + my $pid = launch_with_config($config); + + my $i3 = i3(get_socket_path()); + $i3->connect->recv; + + qx(xdotool key r); + + does_i3_live; + + exit_gracefully($pid); + +} +done_testing; diff --git a/testcases/t/282-tabbed-floating-disable-crash.t b/testcases/t/282-tabbed-floating-disable-crash.t new file mode 100644 index 00000000..7947158c --- /dev/null +++ b/testcases/t/282-tabbed-floating-disable-crash.t @@ -0,0 +1,44 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • http://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • http://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • http://build.i3wm.org/docs/ipc.html +# (or docs/ipc) +# +# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf +# (unless you are already familiar with Perl) +# +# Verifies that i3 does not crash when floating and then unfloating an +# unfocused window within a tabbed container. +# Ticket: #1484 +# Bug still in: 4.9.1-124-g856e1f9 +use i3test i3_autostart => 0; + +my $config = <atom(name => '_NET_WM_STATE_HIDDEN'); + + my ($con) = @_; + my $cookie = $x->get_property( + 0, + $con->{id}, + $x->atom(name => '_NET_WM_STATE')->id, + GET_PROPERTY_TYPE_ANY, + 0, + 4096 + ); + + my $reply = $x->get_property_reply($cookie->{sequence}); + my $len = $reply->{length}; + return 0 if $len == 0; + + my @atoms = unpack("L$len", $reply->{value}); + for (my $i = 0; $i < $len; $i++) { + return 1 if $atoms[$i] == $atom->id; + } + + return 0; +} + +my ($tabA, $tabB, $tabC, $subtabA, $subtabB, $windowA, $windowB); + +############################################################################### +# Given two containers next to each other, when focusing one, then the other +# one does not have _NET_WM_STATE_HIDDEN set. +############################################################################### + +fresh_workspace; +$windowA = open_window; +$windowB = open_window; + +ok(!is_hidden($windowA), 'left window does not have _NET_WM_STATE_HIDDEN set'); +ok(!is_hidden($windowB), 'right window does not have _NET_WM_STATE_HIDDEN set'); + +############################################################################### +# Given two containers on different workspaces, when one is focused, then +# the other one does not have _NET_WM_STATE_HIDDEN set. +############################################################################### + +fresh_workspace; +$windowA = open_window; +fresh_workspace; +$windowB = open_window; + +ok(!is_hidden($windowA), 'left window does not have _NET_WM_STATE_HIDDEN set'); +ok(!is_hidden($windowB), 'right window does not have _NET_WM_STATE_HIDDEN set'); + +############################################################################### +# Given two containers in the same tabbed container, when one is focused, then +# (only) the other one has _NET_WM_STATE_HIDDEN set. +# Given the other tab is focused, then the atom is transferred. +############################################################################### + +fresh_workspace; +$tabA = open_window; +cmd 'layout tabbed'; +$tabB = open_window; + +ok(is_hidden($tabA), 'unfocused tab has _NET_WM_STATE_HIDDEN set'); +ok(!is_hidden($tabB), 'focused tab does not have _NET_WM_STATE_HIDDEN set'); + +cmd 'focus left'; + +ok(!is_hidden($tabA), 'focused tab does not have _NET_WM_STATE_HIDDEN set'); +ok(is_hidden($tabB), 'unfocused tab has _NET_WM_STATE_HIDDEN set'); + +############################################################################### +# Given three containers in the same stacked container, when the focused tab +# is moved to another workspace, then the now focused tab does not have +# _NET_WM_STATE_HIDDEN set anymore. +############################################################################### + +fresh_workspace; +$tabA = open_window; +cmd 'layout stacked'; +$tabB = open_window; +$tabC = open_window; +cmd 'move window to workspace unused'; + +ok(is_hidden($tabA), 'unfocused tab has _NET_WM_STATE_HIDDEN set'); +ok(!is_hidden($tabB), 'focused tab does not have _NET_WM_STATE_HIDDEN set'); +ok(!is_hidden($tabC), 'moved window does not have _NET_WM_STATE_HIDDEN set'); + +############################################################################### +# Given three containers in the same stacked container, when a not focused +# tab is moved to another workspace, then it does not have _NET_WM_STATE_HIDDEN +# set anymore. +############################################################################### + +fresh_workspace; +$tabA = open_window; +cmd 'layout stacked'; +$tabB = open_window; +cmd 'mark moveme'; +$tabC = open_window; +cmd '[con_mark="moveme"] move window to workspace unused'; + +ok(is_hidden($tabA), 'unfocused tab has _NET_WM_STATE_HIDDEN set'); +ok(!is_hidden($tabB), 'moved window does not have _NET_WM_STATE_HIDDEN set'); +ok(!is_hidden($tabC), 'focused tab does not have _NET_WM_STATE_HIDDEN set'); + +############################################################################### +# Given a tabbed container and some other container, when the latter is moved +# into the tabbed container, then all other tabs have _NET_WM_STATE_HIDDEN +# set. +############################################################################### + +fresh_workspace; +$tabA = open_window; +cmd 'layout tabbed'; +$tabB = open_window; +cmd 'focus parent'; +cmd 'split h'; +$tabC = open_window; +cmd 'move left'; + +ok(is_hidden($tabA), 'unfocused tab has _NET_WM_STATE_HIDDEN set'); +ok(is_hidden($tabB), 'unfocused tab has _NET_WM_STATE_HIDDEN set'); +ok(!is_hidden($tabC), 'focused tab does not have _NET_WM_STATE_HIDDEN set'); + +############################################################################### +# Given a stacked container nested inside another tabbed container with the +# inner one being in the currently focused tab, then the focused tab of the +# inner container does not have _NET_WM_STATE_HIDDEN set. +############################################################################### + +fresh_workspace; +$tabA = open_window; +cmd 'layout tabbed'; +$tabB = open_window; +cmd 'split h'; +open_window; +cmd 'split v'; +cmd 'layout stacked'; +$subtabA = open_window; +$subtabB = open_window; + +ok(is_hidden($tabA), 'unfocused outer tab has _NET_WM_STATE_HIDDEN set'); +ok(!is_hidden($tabB), 'focused outer tab does not have _NET_WM_STATE_HIDDEN set'); +ok(is_hidden($subtabA), 'unfocused inner tab has _NET_WM_STATE_HIDDEN set'); +ok(!is_hidden($subtabB), 'focused inner tab does not have _NET_WM_STATE_HIDDEN set'); + +cmd 'focus left'; + +ok(!is_hidden($subtabB), 'focused inner tab does not have _NET_WM_STATE_HIDDEN set'); + +############################################################################### +# Given a stacked container nested inside another tabbed container with the +# inner one being in a currently not focused tab, then all tabs of the inner +# container have _NET_WM_STATE_HIDDEN set. +############################################################################### + +fresh_workspace; +$tabA = open_window; +cmd 'layout tabbed'; +$tabB = open_window; +cmd 'split h'; +open_window; +cmd 'split v'; +cmd 'layout stacked'; +$subtabA = open_window; +$subtabB = open_window; +cmd 'focus parent'; +cmd 'focus parent'; +cmd 'focus left'; + +ok(!is_hidden($tabA), 'focused outer tab does not have _NET_WM_STATE_HIDDEN set'); +ok(is_hidden($tabB), 'unfocused outer tab has _NET_WM_STATE_HIDDEN set'); +ok(is_hidden($subtabA), 'unfocused inner tab has _NET_WM_STATE_HIDDEN set'); +ok(is_hidden($subtabB), 'unfocused inner tab has _NET_WM_STATE_HIDDEN set'); + +############################################################################### + +done_testing; diff --git a/testcases/t/284-ewmh-visible-name.t b/testcases/t/284-ewmh-visible-name.t new file mode 100644 index 00000000..c201b398 --- /dev/null +++ b/testcases/t/284-ewmh-visible-name.t @@ -0,0 +1,70 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • http://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • http://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • http://build.i3wm.org/docs/ipc.html +# (or docs/ipc) +# +# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf +# (unless you are already familiar with Perl) +# +# Tests that _NET_WM_VISIBLE_NAME is set correctly. +# Ticket: #1872 +use i3test; +use X11::XCB qw(:all); + +my ($con); + +sub get_visible_name { + sync_with_i3; + my ($con) = @_; + + my $cookie = $x->get_property( + 0, + $con->{id}, + $x->atom(name => '_NET_WM_VISIBLE_NAME')->id, + $x->atom(name => 'UTF8_STRING')->id, + 0, + 4096 + ); + + my $reply = $x->get_property_reply($cookie->{sequence}); + return undef if $reply->{value_len} == 0; + return $reply->{value}; +} + +############################################################################### +# 1: _NET_WM_VISIBLE_NAME is set when the title format of a window is changed. +############################################################################### + +fresh_workspace; +$con = open_window(name => 'boring title'); +is(get_visible_name($con), undef, 'sanity check: initially no visible name is set'); + +cmd 'title_format custom'; +is(get_visible_name($con), 'custom', 'the visible name is updated'); + +cmd 'title_format "%title"'; +is(get_visible_name($con), 'boring title', 'markup is returned as is'); + +############################################################################### +# 2: _NET_WM_VISIBLE_NAME is removed if not needed. +############################################################################### + +fresh_workspace; +$con = open_window(name => 'boring title'); +cmd 'title_format custom'; +is(get_visible_name($con), 'custom', 'sanity check: a visible name is set'); + +cmd 'title_format %title'; +is(get_visible_name($con), undef, 'the visible name is removed again'); + +############################################################################### + +done_testing; diff --git a/testcases/t/285-sticky.t b/testcases/t/285-sticky.t new file mode 100644 index 00000000..85fc11f7 --- /dev/null +++ b/testcases/t/285-sticky.t @@ -0,0 +1,113 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • http://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • http://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • http://build.i3wm.org/docs/ipc.html +# (or docs/ipc) +# +# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf +# (unless you are already familiar with Perl) +# +# Tests sticky windows. +# Ticket: #1455 +use i3test; + +my ($ws, $tmp, $focused); + +############################################################################### +# 1: Given a sticky tiling container, when the workspace is switched, then +# nothing happens. +############################################################################### +fresh_workspace; +open_window(wm_class => 'findme'); +cmd 'sticky enable'; +$ws = fresh_workspace; + +is(@{get_ws($ws)->{nodes}}, 0, 'tiling sticky container did not move'); +is(@{get_ws($ws)->{floating_nodes}}, 0, 'tiling sticky container did not move'); +cmd '[class="findme"] kill'; + +############################################################################### +# 2: Given a sticky floating container, when the workspace is switched, then +# the container moves to the new workspace. +############################################################################### +$ws = fresh_workspace; +open_floating_window(wm_class => 'findme'); +$focused = get_focused($ws); +cmd 'sticky enable'; +$ws = fresh_workspace; + +is(@{get_ws($ws)->{floating_nodes}}, 1, 'floating sticky container moved to new workspace'); +is(get_focused($ws), $focused, 'sticky container has focus'); +cmd '[class="findme"] kill'; + +############################################################################### +# 3: Given two sticky floating containers, when the workspace is switched, +# then both containers move to the new workspace. +############################################################################### +fresh_workspace; +open_floating_window(wm_class => 'findme'); +cmd 'sticky enable'; +open_floating_window(wm_class => 'findme'); +cmd 'sticky enable'; +$ws = fresh_workspace; + +is(@{get_ws($ws)->{floating_nodes}}, 2, 'multiple sticky windows can be used at the same time'); +cmd '[class="findme"] kill'; + +############################################################################### +# 4: Given an unfocused sticky floating container and a tiling container on the +# target workspace, when the workspace is switched, then the tiling container +# is focused. +############################################################################### +$ws = fresh_workspace; +open_window; +$focused = get_focused($ws); +fresh_workspace; +open_floating_window(wm_class => 'findme'); +cmd 'sticky enable'; +open_window; +cmd 'workspace ' . $ws; + +is(get_focused($ws), $focused, 'the tiling container has focus'); +cmd '[class="findme"] kill'; + +############################################################################### +# 5: Given a focused sticky floating container and a tiling container on the +# target workspace, when the workspace is switched, then the tiling container +# is focused. +############################################################################### +$ws = fresh_workspace; +open_window; +$tmp = fresh_workspace; +open_floating_window(wm_class => 'findme'); +$focused = get_focused($tmp); +cmd 'sticky enable'; +cmd 'workspace ' . $ws; + +is(get_focused($ws), $focused, 'the sticky container has focus'); +cmd '[class="findme"] kill'; + +############################################################################### +# 6: Given a floating container on a non-visible workspace, when the window +# is made sticky, then the window immediately jumps to the currently +# visible workspace. +############################################################################### +fresh_workspace; +open_floating_window(wm_class => 'findme'); +cmd 'mark sticky'; +$ws = fresh_workspace; +cmd '[con_mark=sticky] sticky enable'; + +is(@{get_ws($ws)->{floating_nodes}}, 1, 'the sticky window jumps to the front'); +cmd '[class="findme"] kill'; + +############################################################################### + +done_testing; diff --git a/testcases/t/286-root-window-mouse-binding.t b/testcases/t/286-root-window-mouse-binding.t new file mode 100644 index 00000000..c8fd89ef --- /dev/null +++ b/testcases/t/286-root-window-mouse-binding.t @@ -0,0 +1,42 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • http://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • http://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • http://build.i3wm.org/docs/ipc.html +# (or docs/ipc) +# +# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf +# (unless you are already familiar with Perl) +# +# Verifies that mouse bindings work on the root window if +# --whole-window is set. +# Ticket: #2115 +use i3test i3_autostart => 0; +use i3test::XTEST; + +my $config = < 0; + +#################################################################### +# 1: check that the borders are present on a floating windows +##################################################################### + +my $config = <{floating_nodes}}; +ok(@floating == 1, 'one floating container opened'); +is($floating[0]->{nodes}[0]->{current_border_width}, 2, 'floating current border width set to 2'); +is($floatwindow->rect->width, $floating[0]->{rect}->{width} - 2*2, 'floating border width 2'); + +exit_gracefully($pid); + +##################################################################### +# 2: check that the borders are present on a workspace with two tiled +# windows visible +##################################################################### + +$config = <{nodes}}; +ok(@tiled == 2, 'two tiled container opened'); +is($tiled[0]->{current_border_width}, 2, 'first tiled current border width set to 2'); +is($tilewindow->rect->width, $tiled[0]->{rect}->{width} - 2*2, 'first tiled border width 2'); +is($tiled[1]->{current_border_width}, 2, 'second tiled current border width set to 2'); +is($tilewindow2->rect->width, $tiled[1]->{rect}->{width} - 2*2, 'second tiled border width 2'); + +exit_gracefully($pid); + +##################################################################### +# 3: check that the borders are hidden on a workspace with one tiled +# window visible +##################################################################### + +$config = <{nodes}}; +ok(@tiled == 1, 'one tiled container opened'); +is($tiled[0]->{current_border_width}, 2, 'tiled current border width set to 2'); +is($tilewindow->rect->width, $tiled[0]->{rect}->{width} - 2*0, 'single tiled border width 0'); + +exit_gracefully($pid); + +##################################################################### +# 4: check that the borders are present on a workspace with two tiled +# windows visible, recursively +##################################################################### + +$config = < back to one container'); + +cmd 'focus parent'; +my $tilewindow3 = open_window; +ok(@{get_ws_content($tmp)} == 2, 'after split & new window, two containers'); + +$wscontent = get_ws($tmp); + +# Ensure i3’s X11 requests are processed before our inquiry via +# $tilewindow->rect: +sync_with_i3; + +@tiled = @{$wscontent->{nodes}}; +ok(@tiled == 2, 'two tiled container opened in another container'); +is($tiled[0]->{current_border_width}, -1, 'first tiled current border width set to -1'); +is($tilewindow->rect->width, $tiled[0]->{rect}->{width} - 2*2, 'first tiled border width 2'); +is($tiled[1]->{current_border_width}, 2, 'second tiled current border width set to 2'); +is($tilewindow2->rect->width, $tiled[1]->{rect}->{width} - 2*2, 'second tiled border width 2'); + +exit_gracefully($pid); + +done_testing; diff --git a/testcases/t/288-i3-floating-window-atom.t b/testcases/t/288-i3-floating-window-atom.t new file mode 100644 index 00000000..43b69ccb --- /dev/null +++ b/testcases/t/288-i3-floating-window-atom.t @@ -0,0 +1,70 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • http://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • http://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • http://build.i3wm.org/docs/ipc.html +# (or docs/ipc) +# +# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf +# (unless you are already familiar with Perl) +# +# Tests for our proprietary atom I3_FLOATING_WINDOW to allow +# identifying floating windows. +# Ticket: #2223 +use i3test; +use X11::XCB qw(:all); + +my ($con); + +sub has_i3_floating_window { + sync_with_i3; + + my ($con) = @_; + my $cookie = $x->get_property( + 0, + $con->{id}, + $x->atom(name => 'I3_FLOATING_WINDOW')->id, + $x->atom(name => 'CARDINAL')->id, + 0, + 1 + ); + + my $reply = $x->get_property_reply($cookie->{sequence}); + return 0 if $reply->{length} != 1; + + return unpack("L", $reply->{value}); +} + +############################################################################### +# Toggling floating on a container adds / removes I3_FLOATING_WINDOW. +############################################################################### + +fresh_workspace; + +$con = open_window; +is(has_i3_floating_window($con), 0, 'I3_FLOATING_WINDOW is not set'); + +cmd 'floating enable'; +is(has_i3_floating_window($con), 1, 'I3_FLOATING_WINDOW is set'); + +cmd 'floating disable'; +is(has_i3_floating_window($con), 0, 'I3_FLOATING_WINDOW is not set'); + +############################################################################### +# A window that is floated when managed has I3_FLOATING_WINDOW set. +############################################################################### +# +fresh_workspace; + +$con = open_floating_window; +is(has_i3_floating_window($con), 1, 'I3_FLOATING_WINDOW is set'); + +############################################################################### + +done_testing; diff --git a/testcases/t/289-ipc-shutdown-event.t b/testcases/t/289-ipc-shutdown-event.t new file mode 100644 index 00000000..379b9bf2 --- /dev/null +++ b/testcases/t/289-ipc-shutdown-event.t @@ -0,0 +1,71 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • http://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • http://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • http://build.i3wm.org/docs/ipc.html +# (or docs/ipc) +# +# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf +# (unless you are already familiar with Perl) +# +# Test the ipc shutdown event. This event is triggered when the connection to +# the ipc is about to shutdown because of a user action such as with a +# `restart` or `exit` command. The `change` field indicates why the ipc is +# shutting down. It can be either "restart" or "exit". +# +# Ticket: #2318 +# Bug still in: 4.12-46-g2123888 +use i3test; + +SKIP: { + skip "AnyEvent::I3 too old (need >= 0.17)", 1 if $AnyEvent::I3::VERSION < 0.17; + +my $i3 = i3(get_socket_path()); +$i3->connect->recv; + +my $cv = AE::cv; +my $timer = AE::timer 0.5, 0, sub { $cv->send(0); }; + +$i3->subscribe({ + shutdown => sub { + $cv->send(shift); + } + })->recv; + +cmd 'restart'; + +my $e = $cv->recv; + +diag "Event:\n", Dumper($e); +ok($e, 'the shutdown event should emit when the ipc is restarted by command'); +is($e->{change}, 'restart', 'the `change` field should tell the reason for the shutdown'); + +# restarting kills the ipc client so we have to make a new one +$i3 = i3(get_socket_path()); +$i3->connect->recv; + +$cv = AE::cv; +$timer = AE::timer 0.5, 0, sub { $cv->send(0); }; + +$i3->subscribe({ + shutdown => sub { + $cv->send(shift); + } + })->recv; + +cmd 'exit'; + +$e = $cv->recv; + +diag "Event:\n", Dumper($e); +ok($e, 'the shutdown event should emit when the ipc is exited by command'); +is($e->{change}, 'exit', 'the `change` field should tell the reason for the shutdown'); +} + +done_testing; diff --git a/testcases/t/290-keypress-numlock.t b/testcases/t/290-keypress-numlock.t new file mode 100644 index 00000000..fcc39ead --- /dev/null +++ b/testcases/t/290-keypress-numlock.t @@ -0,0 +1,390 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • http://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • http://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • http://build.i3wm.org/docs/ipc.html +# (or docs/ipc) +# +# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf +# (unless you are already familiar with Perl) +# +# Verifies that one can bind on numpad keys in different numlock states. +# Ticket: #2346 +# Bug still in: 4.12-78-g85bb324 +use i3test i3_autostart => 0; +use i3test::XTEST; +use ExtUtils::PkgConfig; + +SKIP: { + skip "libxcb-xkb too old (need >= 1.11)", 1 unless + ExtUtils::PkgConfig->atleast_version('xcb-xkb', '1.11'); + +my $config = < 0; + +my $config = < 'mark_A'); +$B = open_window(wm_class => 'mark_B'); +$expected_focus = get_focused($ws); + +cmd '[con_mark=B] swap container with mark A'; + +$nodes = get_ws_content($ws); +is($nodes->[0]->{window}, $B->{id}, 'B is on the left'); +is($nodes->[1]->{window}, $A->{id}, 'A is on the right'); +is(get_focused($ws), $expected_focus, 'B is still focused'); + +kill_all_windows; + +############################################################################### +# Swap two containers with different parents. +# In this test, the focus head of the left v-split container is A. +# The focused container is B. +# +# +---+---+ Layout: H1[ V1[ A Y ] V2[ X B ] ] +# | A | X | Focus Stacks: +# +---+---+ H1: V2, V1 +# | Y | B | V1: A, Y +# +---+---+ V2: B, X +############################################################################### +$ws = fresh_workspace; + +$A = open_window(wm_class => 'mark_A'); +$B = open_window(wm_class => 'mark_B'); +cmd 'split v'; +open_window; +cmd 'move up, focus left'; +cmd 'split v'; +open_window; +cmd 'focus up, focus right, focus down'; +$expected_focus = get_focused($ws); + +cmd '[con_mark=B] swap container with mark A'; + +$nodes = get_ws_content($ws); +is($nodes->[0]->{nodes}->[0]->{window}, $B->{id}, 'B is on the top left'); +is($nodes->[1]->{nodes}->[1]->{window}, $A->{id}, 'A is on the bottom right'); +is(get_focused($ws), $expected_focus, 'B is still focused'); + +kill_all_windows; + +############################################################################### +# Swap two containers with different parents. +# In this test, the focus head of the left v-split container is _not_ A. +# The focused container is B. +# +# +---+---+ Layout: H1[ V1[ A Y ] V2[ X B ] ] +# | A | X | Focus Stacks: +# +---+---+ H1: V2, V1 +# | Y | B | V1: Y, A +# +---+---+ V2: B, X +############################################################################### +$ws = fresh_workspace; + +$A = open_window(wm_class => 'mark_A'); +$B = open_window(wm_class => 'mark_B'); +cmd 'split v'; +open_window; +cmd 'move up, focus left'; +cmd 'split v'; +open_window; +cmd 'focus right, focus down'; +$expected_focus = get_focused($ws); + +cmd '[con_mark=B] swap container with mark A'; + +$nodes = get_ws_content($ws); +is($nodes->[0]->{nodes}->[0]->{window}, $B->{id}, 'B is on the top left'); +is($nodes->[1]->{nodes}->[1]->{window}, $A->{id}, 'A is on the bottom right'); +is(get_focused($ws), $expected_focus, 'B is still focused'); + +kill_all_windows; + +############################################################################### +# Swap two containers with one being on a different workspace. +# The focused container is B. +# +# Layout: O1[ W1[ H1 ] W2[ H2 ] ] +# Focus Stacks: +# O1: W2, W1 +# +# +---+---+ Layout: H1[ A X ] +# | A | X | Focus Stacks: +# +---+---+ H1: A, X +# +# +---+---+ Layout: H2[ Y, B ] +# | Y | B | Focus Stacks: +# +---+---+ H2: B, Y +############################################################################### +$ws1 = fresh_workspace; +$A = open_window(wm_class => 'mark_A'); +$expected_focus = get_focused($ws1); +open_window; +cmd 'focus left'; + +$ws2 = fresh_workspace; +open_window; +$B = open_window(wm_class => 'mark_B'); + +cmd '[con_mark=B] swap container with mark A'; + +$nodes = get_ws_content($ws1); +is($nodes->[0]->{window}, $B->{id}, 'B is on ws1:left'); + +$nodes = get_ws_content($ws2); +is($nodes->[1]->{window}, $A->{id}, 'A is on ws1:right'); +is(get_focused($ws2), $expected_focus, 'A is focused'); + +kill_all_windows; + +############################################################################### +# Swap two non-focused containers within the same workspace. +# +# +---+---+ Layout: H1[ V1[ A X ] V2[ F B ] ] +# | A | F | Focus Stacks: +# +---+---+ H1: V2, V1 +# | X | B | V1: A, X +# +---+---+ V2: F, B +############################################################################### +$ws = fresh_workspace; + +$A = open_window(wm_class => 'mark_A'); +$B = open_window(wm_class => 'mark_B'); +cmd 'split v'; +open_window; +cmd 'move up, focus left'; +cmd 'split v'; +open_window; +cmd 'focus up, focus right'; +$expected_focus = get_focused($ws); + +cmd '[con_mark=B] swap container with mark A'; + +$nodes = get_ws_content($ws); +is($nodes->[0]->{nodes}->[0]->{window}, $B->{id}, 'B is on the top left'); +is($nodes->[1]->{nodes}->[1]->{window}, $A->{id}, 'A is on the bottom right'); +is(get_focused($ws), $expected_focus, 'F is still focused'); + +kill_all_windows; + +############################################################################### +# Swap two non-focused containers which are both on different workspaces. +# +# Layout: O1[ W1[ A ] W2[ B ] W3[ F ] ] +# Focus Stacks: +# O1: W3, W2, W1 +# +# +---+ +# | A | +# +---+ +# +# +---+ +# | B | +# +---+ +# +# +---+ +# | F | +# +---+ +############################################################################### +$ws1 = fresh_workspace; +$A = open_window(wm_class => 'mark_A'); + +$ws2 = fresh_workspace; +$B = open_window(wm_class => 'mark_B'); + +$ws3 = fresh_workspace; +open_window; +$expected_focus = get_focused($ws3); + +cmd '[con_mark=B] swap container with mark A'; + +$nodes = get_ws_content($ws1); +is($nodes->[0]->{window}, $B->{id}, 'B is on the first workspace'); + +$nodes = get_ws_content($ws2); +is($nodes->[0]->{window}, $A->{id}, 'A is on the second workspace'); + +is(get_focused($ws3), $expected_focus, 'F is still focused'); + +kill_all_windows; + +############################################################################### +# Swap two non-focused containers with one being on a different workspace. +# +# Layout: O1[ W1[ A ] W2[ H2 ] ] +# Focus Stacks: +# O1: W2, W1 +# +# +---+ +# | A | +# +---+ +# +# +---+---+ Layout: H2[ B, F ] +# | B | F | Focus Stacks: +# +---+---+ H2: F, B +############################################################################### + +$ws1 = fresh_workspace; +$A = open_window(wm_class => 'mark_A'); + +$ws2 = fresh_workspace; +$B = open_window(wm_class => 'mark_B'); +open_window; +$expected_focus = get_focused($ws2); + +cmd '[con_mark=B] swap container with mark A'; + +$nodes = get_ws_content($ws1); +is($nodes->[0]->{window}, $B->{id}, 'B is on the first workspace'); + +$nodes = get_ws_content($ws2); +is($nodes->[0]->{window}, $A->{id}, 'A is on the left of the second workspace'); +is(get_focused($ws2), $expected_focus, 'F is still focused'); + +kill_all_windows; + +############################################################################### +# 1. A container cannot be swapped with its parent. +# 2. A container cannot be swapped with one of its children. +# +# ↓A↓ +# +---+---+ Layout: H1[ X V1[ Y B ] ] +# | | Y | (with A := V1) +# | X +---+ +# | | B | +# +---+---+ +############################################################################### +$ws = fresh_workspace; +open_window; +open_window; +cmd 'split v'; +$B = open_window(wm_class => 'mark_B'); +cmd 'focus parent, mark A, focus child'; + +$result = cmd '[con_mark=B] swap container with mark A'; +is($result->[0]->{success}, 0, 'B cannot be swappd with its parent'); + +$result = cmd '[con_mark=A] swap container with mark B'; +is($result->[0]->{success}, 0, 'A cannot be swappd with one of its children'); + +kill_all_windows; + +############################################################################### +# Swapping two containers preserves the geometry of the container they are +# being swapped with. +# +# Before: +# +---+-------+ +# | A | B | +# +---+-------+ +# +# After: +# +---+-------+ +# | B | A | +# +---+-------+ +############################################################################### +$ws = fresh_workspace; +$A = open_window(wm_class => 'mark_A'); +$B = open_window(wm_class => 'mark_B'); +cmd 'resize grow width 0 or 25 ppt'; + +# sanity checks +$nodes = get_ws_content($ws); +cmp_float($nodes->[0]->{percent}, 0.25, 'A has 25% width'); +cmp_float($nodes->[1]->{percent}, 0.75, 'B has 75% width'); + +cmd '[con_mark=B] swap container with mark A'; + +$nodes = get_ws_content($ws); +cmp_float($nodes->[0]->{percent}, 0.25, 'B has 25% width'); +cmp_float($nodes->[1]->{percent}, 0.75, 'A has 75% width'); + +kill_all_windows; + +############################################################################### +# Swapping containers not sharing the same parent preserves the geometry of +# the container they are swapped with. +# +# Before: +# +---+-----+ +# | A | | +# +---+ B | +# | | | +# | Y +-----+ +# | | X | +# +---+-----+ +# +# After: +# +---+-----+ +# | B | | +# +---+ A | +# | | | +# | Y +-----+ +# | | X | +# +---+-----+ +############################################################################### +$ws = fresh_workspace; + +$A = open_window(wm_class => 'mark_A'); +$B = open_window(wm_class => 'mark_B'); +cmd 'split v'; +open_window; +cmd 'focus up, resize grow height 0 or 25 ppt'; +cmd 'focus left, split v'; +open_window; +cmd 'resize grow height 0 or 25 ppt'; + +# sanity checks +$nodes = get_ws_content($ws); +cmp_float($nodes->[0]->{nodes}->[0]->{percent}, 0.25, 'A has 25% height'); +cmp_float($nodes->[1]->{nodes}->[0]->{percent}, 0.75, 'B has 75% height'); + +cmd '[con_mark=B] swap container with mark A'; + +$nodes = get_ws_content($ws); +cmp_float($nodes->[0]->{nodes}->[0]->{percent}, 0.25, 'B has 25% height'); +cmp_float($nodes->[1]->{nodes}->[0]->{percent}, 0.75, 'A has 75% height'); + +kill_all_windows; + +############################################################################### +# Swapping containers moves the urgency hint correctly. +############################################################################### + +$ws1 = fresh_workspace; +$A = open_window(wm_class => 'mark_A'); +$ws2 = fresh_workspace; +$B = open_window(wm_class => 'mark_B'); +open_window; + +$B->add_hint('urgency'); +sync_with_i3; + +cmd '[con_mark=B] swap container with mark A'; + +@urgent = grep { $_->{urgent} } @{get_ws_content($ws1)}; +is(@urgent, 1, 'B is marked urgent'); +is(get_ws($ws1)->{urgent}, 1, 'the first workspace is marked urgent'); + +@urgent = grep { $_->{urgent} } @{get_ws_content($ws2)}; +is(@urgent, 0, 'A is not marked urgent'); +is(get_ws($ws2)->{urgent}, 0, 'the second workspace is not marked urgent'); + +kill_all_windows; + +############################################################################### + +exit_gracefully($pid); + +done_testing; diff --git a/testcases/t/528-workspace-next-prev.t b/testcases/t/528-workspace-next-prev.t deleted file mode 100644 index 1a83de23..00000000 --- a/testcases/t/528-workspace-next-prev.t +++ /dev/null @@ -1,129 +0,0 @@ -#!perl -# vim:ts=4:sw=4:expandtab -# -# Please read the following documents before working on tests: -# • http://build.i3wm.org/docs/testsuite.html -# (or docs/testsuite) -# -# • http://build.i3wm.org/docs/lib-i3test.html -# (alternatively: perldoc ./testcases/lib/i3test.pm) -# -# • http://build.i3wm.org/docs/ipc.html -# (or docs/ipc) -# -# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf -# (unless you are already familiar with Perl) -# -# Tests whether 'workspace next' works correctly. -# -use List::Util qw(first); -use i3test i3_autostart => 0; - -sub assert_next { - my ($expected) = @_; - - cmd 'workspace next'; - # We need to sync after changing focus to a different output to wait for the - # EnterNotify to be processed, otherwise it will be processed at some point - # later in time and mess up our subsequent tests. - sync_with_i3; - - is(focused_ws, $expected, "workspace $expected focused"); -} - -sub assert_prev { - my ($expected) = @_; - - cmd 'workspace prev'; - # We need to sync after changing focus to a different output to wait for the - # EnterNotify to be processed, otherwise it will be processed at some point - # later in time and mess up our subsequent tests. - sync_with_i3; - - is(focused_ws, $expected, "workspace $expected focused"); -} - -my $config = <root->warp_pointer(0, 0); -sync_with_i3; - -################################################################################ -# Setup workspaces so that they stay open (with an empty container). -# open_window ensures, this -# -# numbered named -# output 1 (left) : 1, 2, 3, 6, 7, B, F, C -# output 2 (right): 4, 5, A, D, E -# -################################################################################ - -cmd 'focus output right'; -cmd 'workspace A'; open_window; -cmd 'workspace D'; open_window; -cmd 'workspace 4'; open_window; -cmd 'workspace 5'; open_window; -cmd 'workspace E'; open_window; - -cmd 'focus output left'; -cmd 'workspace 1'; open_window; -cmd 'workspace 2'; open_window; -cmd 'workspace B'; open_window; -cmd 'workspace 3'; open_window; -cmd 'workspace F'; open_window; -cmd 'workspace 6'; open_window; -cmd 'workspace C'; open_window; -cmd 'workspace 7'; open_window; - -################################################################################ -# Use workspace next and verify the correct order. -# numbered -> numerical sort -# named -> sort by creation time -################################################################################ -cmd 'workspace 1'; -is(focused_ws, '1', 'back on workspace 1'); - -assert_next('2'); -assert_next('3'); -assert_next('4'); -assert_next('5'); -assert_next('6'); -assert_next('7'); - -assert_next('B'); -assert_next('F'); -assert_next('C'); -assert_next('A'); -assert_next('D'); -assert_next('E'); -assert_next('1'); - -cmd 'workspace 1'; -is(focused_ws, '1', 'back on workspace 1'); - -assert_prev('E'); -assert_prev('D'); -assert_prev('A'); -assert_prev('C'); -assert_prev('F'); -assert_prev('B'); - -assert_prev('7'); -assert_prev('6'); -assert_prev('5'); -assert_prev('4'); -assert_prev('3'); -assert_prev('2'); -assert_prev('1'); - - -exit_gracefully($pid); - -done_testing; diff --git a/testcases/t/529-net-wm-desktop_mm.t b/testcases/t/529-net-wm-desktop_mm.t deleted file mode 100644 index 77238946..00000000 --- a/testcases/t/529-net-wm-desktop_mm.t +++ /dev/null @@ -1,75 +0,0 @@ -#!perl -# vim:ts=4:sw=4:expandtab -# -# Please read the following documents before working on tests: -# • http://build.i3wm.org/docs/testsuite.html -# (or docs/testsuite) -# -# • http://build.i3wm.org/docs/lib-i3test.html -# (alternatively: perldoc ./testcases/lib/i3test.pm) -# -# • http://build.i3wm.org/docs/ipc.html -# (or docs/ipc) -# -# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf -# (unless you are already familiar with Perl) -# -# Tests for _NET_WM_DESKTOP. -# Ticket: #2153 -use i3test i3_autostart => 0; -use X11::XCB qw(:all); - -sub get_net_wm_desktop { - sync_with_i3; - - my ($con) = @_; - my $cookie = $x->get_property( - 0, - $con->{id}, - $x->atom(name => '_NET_WM_DESKTOP')->id, - $x->atom(name => 'CARDINAL')->id, - 0, - 1 - ); - - my $reply = $x->get_property_reply($cookie->{sequence}); - return undef if $reply->{length} != 1; - - return unpack("L", $reply->{value}); -} - -my $config = < 0; + +sub assert_next { + my ($expected) = @_; + + cmd 'workspace next'; + # We need to sync after changing focus to a different output to wait for the + # EnterNotify to be processed, otherwise it will be processed at some point + # later in time and mess up our subsequent tests. + sync_with_i3; + + is(focused_ws, $expected, "workspace $expected focused"); +} + +sub assert_prev { + my ($expected) = @_; + + cmd 'workspace prev'; + # We need to sync after changing focus to a different output to wait for the + # EnterNotify to be processed, otherwise it will be processed at some point + # later in time and mess up our subsequent tests. + sync_with_i3; + + is(focused_ws, $expected, "workspace $expected focused"); +} + +my $config = <root->warp_pointer(0, 0); +sync_with_i3; + +################################################################################ +# Setup workspaces so that they stay open (with an empty container). +# open_window ensures, this +# +# numbered named +# output 1 (left) : 1, 2, 3, 6, 7, B, F, C +# output 2 (right): 4, 5, A, D, E +# +################################################################################ + +cmd 'focus output right'; +cmd 'workspace A'; open_window; +cmd 'workspace D'; open_window; +cmd 'workspace 4'; open_window; +cmd 'workspace 5'; open_window; +cmd 'workspace E'; open_window; + +cmd 'focus output left'; +cmd 'workspace 1'; open_window; +cmd 'workspace 2'; open_window; +cmd 'workspace B'; open_window; +cmd 'workspace 3'; open_window; +cmd 'workspace F'; open_window; +cmd 'workspace 6'; open_window; +cmd 'workspace C'; open_window; +cmd 'workspace 7'; open_window; + +################################################################################ +# Use workspace next and verify the correct order. +# numbered -> numerical sort +# named -> sort by creation time +################################################################################ +cmd 'workspace 1'; +is(focused_ws, '1', 'back on workspace 1'); + +assert_next('2'); +assert_next('3'); +assert_next('4'); +assert_next('5'); +assert_next('6'); +assert_next('7'); + +assert_next('B'); +assert_next('F'); +assert_next('C'); +assert_next('A'); +assert_next('D'); +assert_next('E'); +assert_next('1'); + +cmd 'workspace 1'; +is(focused_ws, '1', 'back on workspace 1'); + +assert_prev('E'); +assert_prev('D'); +assert_prev('A'); +assert_prev('C'); +assert_prev('F'); +assert_prev('B'); + +assert_prev('7'); +assert_prev('6'); +assert_prev('5'); +assert_prev('4'); +assert_prev('3'); +assert_prev('2'); +assert_prev('1'); + + +exit_gracefully($pid); + +done_testing; diff --git a/testcases/t/536-net-wm-desktop_mm.t b/testcases/t/536-net-wm-desktop_mm.t new file mode 100644 index 00000000..77238946 --- /dev/null +++ b/testcases/t/536-net-wm-desktop_mm.t @@ -0,0 +1,75 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • http://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • http://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • http://build.i3wm.org/docs/ipc.html +# (or docs/ipc) +# +# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf +# (unless you are already familiar with Perl) +# +# Tests for _NET_WM_DESKTOP. +# Ticket: #2153 +use i3test i3_autostart => 0; +use X11::XCB qw(:all); + +sub get_net_wm_desktop { + sync_with_i3; + + my ($con) = @_; + my $cookie = $x->get_property( + 0, + $con->{id}, + $x->atom(name => '_NET_WM_DESKTOP')->id, + $x->atom(name => 'CARDINAL')->id, + 0, + 1 + ); + + my $reply = $x->get_property_reply($cookie->{sequence}); + return undef if $reply->{length} != 1; + + return unpack("L", $reply->{value}); +} + +my $config = <