]> git.sur5r.net Git - i3/i3/commitdiff
tests: implement sync_with_i3 and use it instead of sleep()
authorMichael Stapelberg <michael@stapelberg.de>
Fri, 23 Sep 2011 19:37:45 +0000 (20:37 +0100)
committerMichael Stapelberg <michael@stapelberg.de>
Sat, 24 Sep 2011 10:15:08 +0000 (11:15 +0100)
Also use open_standard_window() in a few more places where appropriate

27 files changed:
testcases/t/02-fullscreen.t
testcases/t/05-ipc.t
testcases/t/06-focus.t
testcases/t/08-focus-stack.t
testcases/t/09-stacking.t
testcases/t/11-goto.t
testcases/t/12-floating-resize.t
testcases/t/13-urgent.t
testcases/t/19-match.t
testcases/t/33-size-hints.t
testcases/t/35-floating-focus.t
testcases/t/36-floating-ws-empty.t
testcases/t/37-floating-unmap.t
testcases/t/38-floating-attach.t
testcases/t/40-focus-lost.t
testcases/t/41-resize.t
testcases/t/45-flattening.t
testcases/t/46-floating-reinsert.t
testcases/t/47-regress-floatingmove.t
testcases/t/48-regress-floatingmovews.t
testcases/t/53-floating-originalsize.t
testcases/t/56-fullscreen-focus.t
testcases/t/62-regress-dock-urgent.t
testcases/t/63-wm-state.t
testcases/t/67-workspace_layout.t
testcases/t/70-force_focus_wrapping.t
testcases/t/lib/i3test.pm

index 34e5364e495c821255937cf82d6360b980be96d4..e83e45acf7dcd71922f9754fcdb03cb349b785ce 100644 (file)
@@ -59,11 +59,9 @@ my $new_rect = $window->rect;
 ok(!eq_deeply($new_rect, $original_rect), "Window got repositioned");
 $original_rect = $new_rect;
 
-sleep 0.25;
-
 $window->fullscreen(1);
 
-sleep 0.25;
+sync_with_i3($x);
 
 $new_rect = $window->rect;
 ok(!eq_deeply($new_rect, $original_rect), "Window got repositioned after fullscreen");
@@ -135,12 +133,12 @@ $new_rect = $swindow->rect;
 ok(!eq_deeply($new_rect, $original_rect), "Window got repositioned");
 
 $swindow->fullscreen(1);
-sleep 0.25;
+sync_with_i3($x);
 
 is(fullscreen_windows(), 1, 'amount of fullscreen windows');
 
 $window->fullscreen(0);
-sleep 0.25;
+sync_with_i3($x);
 is(fullscreen_windows(), 0, 'amount of fullscreen windows');
 
 ok($swindow->mapped, 'window mapped after other fullscreen ended');
@@ -152,7 +150,7 @@ ok($swindow->mapped, 'window mapped after other fullscreen ended');
 ###########################################################################
 
 $swindow->fullscreen(0);
-sleep 0.25;
+sync_with_i3($x);
 
 is(fullscreen_windows(), 0, 'amount of fullscreen windows after disabling');
 
index a910c930b19a87e377e1ffa2c57b05ff4de43231..0d18040ec1efb8c8ff157400ddcaf5bed9bd2a8e 100644 (file)
@@ -2,11 +2,6 @@
 # vim:ts=4:sw=4:expandtab
 
 use i3test;
-use X11::XCB qw(:all);
-
-BEGIN {
-    use_ok('X11::XCB::Connection') or BAIL_OUT('Cannot load X11::XCB::Connection');
-}
 
 my $x = X11::XCB::Connection->new;
 
@@ -18,16 +13,14 @@ fresh_workspace;
 
 # Create a window so we can get a focus different from NULL
 my $window = open_standard_window($x);
-diag("window->id = " . $window->id);
-
-sleep 0.25;
+sync_with_i3($x);
 
 my $focus = $x->input_focus;
-diag("old focus = $focus");
 
 # Switch to another workspace
 fresh_workspace;
 
+sync_with_i3($x);
 my $new_focus = $x->input_focus;
 isnt($focus, $new_focus, "Focus changed");
 
index d357c8a9de2d5009d20c93cc7d37b8793e90ff75..b3add32227b5a3542af8cbc116d505a887ab06ba 100644 (file)
@@ -24,7 +24,7 @@ cmd 'split v';
 my $top = open_standard_window($x);
 my $mid = open_standard_window($x);
 my $bottom = open_standard_window($x);
-sleep 0.25;
+##sleep 0.25;
 
 diag("top id = " . $top->id);
 diag("mid id = " . $mid->id);
index f8143979164e777cc19b5e6f9b5ce3d370eb6652..33a5884a2fc24d85b5336ecc6a6f8f1dcc12eb8b 100644 (file)
@@ -4,11 +4,6 @@
 # over an unfocused tiling client and destroying the floating one again.
 
 use i3test;
-use X11::XCB qw(:all);
-
-BEGIN {
-    use_ok('X11::XCB::Window') or BAIL_OUT('Could not load X11::XCB::Window');
-}
 
 my $x = X11::XCB::Connection->new;
 
@@ -19,30 +14,21 @@ cmd 'split h';
 my $tiled_left = open_standard_window($x);
 my $tiled_right = open_standard_window($x);
 
-sleep 0.25;
+sync_with_i3($x);
 
 # Get input focus before creating the floating window
 my $focus = $x->input_focus;
 
 # Create a floating window which is smaller than the minimum enforced size of i3
-my $window = $x->root->create_child(
-    class => WINDOW_CLASS_INPUT_OUTPUT,
-    rect => [ 1, 1, 30, 30],
-    background_color => '#C0C0C0',
-    type => $x->atom(name => '_NET_WM_WINDOW_TYPE_UTILITY'),
-);
-
-isa_ok($window, 'X11::XCB::Window');
-
-$window->map;
+my $window = open_standard_window($x, undef, 1);
+sync_with_i3($x);
 
-sleep 1;
-sleep 0.25;
 is($x->input_focus, $window->id, 'floating window focused');
 
 $window->unmap;
 
-sleep 0.25;
+# TODO: wait for unmap
+sync_with_i3($x);
 
 is($x->input_focus, $focus, 'Focus correctly restored');
 
index 1cb205ed9a192188206303973a90bedee600fcc0..cc285f32788162d946c1dac5a47d2830d725d8ea 100644 (file)
@@ -27,9 +27,7 @@ $i3->command('9')->recv;
 #####################################################################
 
 my $top = i3test::open_standard_window($x);
-sleep(0.25);
 my $mid = i3test::open_standard_window($x);
-sleep(0.25);
 my $bottom = i3test::open_standard_window($x);
 sleep(0.25);
 
index 542dc828bd146fa316fc881493f603152ada0249..44cf55abe69b37d1be919918f0bb67d920a2d501 100644 (file)
@@ -21,11 +21,8 @@ cmd 'split h';
 #####################################################################
 
 my $top = open_standard_window($x);
-sleep 0.25;
 my $mid = open_standard_window($x);
-sleep 0.25;
 my $bottom = open_standard_window($x);
-sleep 0.25;
 
 diag("top id = " . $top->id);
 diag("mid id = " . $mid->id);
@@ -39,6 +36,7 @@ sub focus_after {
     my $msg = shift;
 
     cmd $msg;
+    sync_with_i3($x);
     return $x->input_focus;
 }
 
index 09297df0d6015eb6551900f3801215ba3329b10a..1aec9573fb56acda1337c0ebbaa8611f1716fef7 100644 (file)
@@ -1,8 +1,5 @@
 #!perl
 # vim:ts=4:sw=4:expandtab
-# Beware that this test uses workspace 9 to perform some tests (it expects
-# the workspace to be empty).
-# TODO: skip it by default?
 
 use i3test;
 use X11::XCB qw(:all);
@@ -20,30 +17,22 @@ fresh_workspace;
 #####################################################################
 
 # Create a floating window
-my $window = $x->root->create_child(
-    class => WINDOW_CLASS_INPUT_OUTPUT,
-    rect => [ 0, 0, 30, 30],
-    background_color => '#C0C0C0',
-    # replace the type with 'utility' as soon as the coercion works again in X11::XCB
-    window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_UTILITY'),
-);
-
-isa_ok($window, 'X11::XCB::Window');
-
-$window->map;
-sleep 0.25;
+my $window = open_standard_window($x, undef, 1);
 
 # See if configurerequests cause window movements (they should not)
 my ($a, $t) = $window->rect;
 $window->rect(X11::XCB::Rect->new(x => $a->x, y => $a->y, width => $a->width, height => $a->height));
 
-sleep 0.25;
+sync_with_i3($x);
+
 my ($na, $nt) = $window->rect;
 is_deeply($na, $a, 'Rects are equal after configurerequest');
 
 sub test_resize {
     $window->rect(X11::XCB::Rect->new(x => 0, y => 0, width => 100, height => 100));
 
+    sync_with_i3($x);
+
     my ($absolute, $top) = $window->rect;
 
     # Make sure the width/height are different from what we’re gonna test, so
@@ -52,7 +41,8 @@ sub test_resize {
     isnt($absolute->height, 500, 'height != 500');
 
     $window->rect(X11::XCB::Rect->new(x => 0, y => 0, width => 300, height => 500));
-    sleep 0.25;
+
+    sync_with_i3($x);
 
     ($absolute, $top) = $window->rect;
 
index f40b72fb9c7691b9894b1da2d0d02317db9cfd85..83c36a980ac7fa0d0bde2cafac0d6d37b7fd4c48 100644 (file)
@@ -31,7 +31,7 @@ is(@urgent, 0, 'no window got the urgent flag');
 # Add the urgency hint, switch to a different workspace and back again
 #####################################################################
 $top->add_hint('urgency');
-sleep 0.5;
+sync_with_i3($x);
 
 @content = @{get_ws_content($tmp)};
 @urgent = grep { $_->{urgent} } @content;
@@ -48,7 +48,7 @@ cmd '[id="' . $top->id . '"] focus';
 is(@urgent, 0, 'no window got the urgent flag after focusing');
 
 $top->add_hint('urgency');
-sleep 0.5;
+sync_with_i3($x);
 
 @urgent = grep { $_->{urgent} } @{get_ws_content($tmp)};
 is(@urgent, 0, 'no window got the urgent flag after re-setting urgency hint');
@@ -62,7 +62,7 @@ ok(!$ws->{urgent}, 'urgent flag not set on workspace');
 my $otmp = fresh_workspace;
 
 $top->add_hint('urgency');
-sleep 0.5;
+sync_with_i3($x);
 
 $ws = get_ws($tmp);
 ok($ws->{urgent}, 'urgent flag set on workspace');
index e4fc6ec0225bbbd5116c6c8a7fac26676e2ed86e..93822f1f846b632223728e441039dbc98613c7dd 100644 (file)
@@ -12,20 +12,7 @@ ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
 
 # Open a new window
 my $x = X11::XCB::Connection->new;
-my $window = $x->root->create_child(
-    class => WINDOW_CLASS_INPUT_OUTPUT,
-    rect => [ 0, 0, 30, 30 ],
-    background_color => '#C0C0C0',
-);
-
-$window->map;
-# give it some time to be picked up by the window manager
-# TODO: better check for $window->mapped or something like that?
-# maybe we can even wait for getting mapped?
-my $c = 0;
-while (@{get_ws_content($tmp)} == 0 and $c++ < 5) {
-    sleep 0.25;
-}
+my $window = open_standard_window($x);
 my $content = get_ws_content($tmp);
 ok(@{$content} == 1, 'window mapped');
 my $win = $content->[0];
@@ -114,7 +101,7 @@ ok(@{$content} == 2, 'two windows opened');
 
 cmd '[class="special" title="left"] kill';
 
-sleep 0.25;
+sync_with_i3($x);
 
 $content = get_ws_content($tmp);
 is(@{$content}, 1, 'one window still there');
index 05897c88aa4e106f59ab575ccab89a9710388601..e212dc7204844fccec1e09611c2793ac15a94604 100644 (file)
@@ -32,7 +32,7 @@ sleep 0.25;
 $win->hints->aspect($aspect);
 $x->flush;
 
-sleep 0.25;
+sync_with_i3($x);
 
 my $rect = $win->rect;
 my $ar = $rect->width / $rect->height;
index 6adad246292a50ae06b01574523dc9f36c1a1b2c..fc94c440fd6f4145e9af683afb93a3a7129dd473 100644 (file)
@@ -16,6 +16,8 @@ my $tmp = fresh_workspace;
 my $first = open_standard_window($x);
 my $second = open_standard_window($x);
 
+sync_with_i3($x);
+
 is($x->input_focus, $second->id, 'second window focused');
 
 cmd 'floating enable';
@@ -34,12 +36,16 @@ $first = open_standard_window($x);    # window 2
 $second = open_standard_window($x);   # window 3
 my $third = open_standard_window($x); # window 4
 
+sync_with_i3($x);
+
 is($x->input_focus, $third->id, 'last container focused');
 
 cmd 'floating enable';
 
 cmd '[id="' . $second->id . '"] focus';
 
+sync_with_i3($x);
+
 is($x->input_focus, $second->id, 'second con focused');
 
 cmd 'floating enable';
@@ -47,7 +53,8 @@ cmd 'floating enable';
 # now kill the third one (it's floating). focus should stay unchanged
 cmd '[id="' . $third->id . '"] kill';
 
-sleep 0.25;
+# TODO: wait for unmapnotify
+sync_with_i3($x);
 
 is($x->input_focus, $second->id, 'second con still focused after killing third');
 
@@ -63,12 +70,16 @@ $first = open_standard_window($x, '#ff0000');    # window 5
 $second = open_standard_window($x, '#00ff00');   # window 6
 my $third = open_standard_window($x, '#0000ff'); # window 7
 
+sync_with_i3($x);
+
 is($x->input_focus, $third->id, 'last container focused');
 
 cmd 'floating enable';
 
 cmd '[id="' . $second->id . '"] focus';
 
+sync_with_i3($x);
+
 is($x->input_focus, $second->id, 'second con focused');
 
 cmd 'floating enable';
@@ -77,13 +88,14 @@ cmd 'floating enable';
 # also floating
 cmd 'kill';
 
-sleep 0.25;
+# TODO: wait for unmapnotify
+sync_with_i3($x);
 
 is($x->input_focus, $third->id, 'third con focused');
 
 cmd 'kill';
-
-sleep 0.25;
+# TODO: wait for unmapnotify
+sync_with_i3($x);
 
 is($x->input_focus, $first->id, 'first con focused after killing all floating cons');
 
@@ -99,29 +111,34 @@ cmd 'layout stacked';
 $second = open_standard_window($x, '#00ff00');   # window 6
 $third = open_standard_window($x, '#0000ff'); # window 7
 
+sync_with_i3($x);
+
 is($x->input_focus, $third->id, 'last container focused');
 
 cmd 'floating enable';
 
 cmd '[id="' . $second->id . '"] focus';
 
+sync_with_i3($x);
+
 is($x->input_focus, $second->id, 'second con focused');
 
 cmd 'floating enable';
 
-sleep 0.5;
+sync_with_i3($x);
 
 # now kill the second one. focus should fall back to the third one, which is
 # also floating
 cmd 'kill';
 
-sleep 0.25;
+# TODO: wait for unmapnotify
+sync_with_i3($x);
 
-is($x->input_focus, $third->id, 'second con focused');
+is($x->input_focus, $third->id, 'third con focused');
 
 cmd 'kill';
-
-sleep 0.25;
+# TODO: wait for unmapnotify
+sync_with_i3($x);
 
 is($x->input_focus, $first->id, 'first con focused after killing all floating cons');
 
@@ -134,6 +151,8 @@ $tmp = fresh_workspace;
 $first = open_standard_window($x, '#ff0000');    # window 8
 $second = open_standard_window($x, '#00ff00');   # window 9
 
+sync_with_i3($x);
+
 is($x->input_focus, $second->id, 'second container focused');
 
 cmd 'floating enable';
@@ -142,31 +161,31 @@ is($x->input_focus, $second->id, 'second container focused');
 
 cmd 'focus tiling';
 
-sleep 0.25;
+sync_with_i3($x);
 
 is($x->input_focus, $first->id, 'first (tiling) container focused');
 
 cmd 'focus floating';
 
-sleep 0.25;
+sync_with_i3($x);
 
 is($x->input_focus, $second->id, 'second (floating) container focused');
 
 cmd 'focus floating';
 
-sleep 0.25;
+sync_with_i3($x);
 
 is($x->input_focus, $second->id, 'second (floating) container still focused');
 
 cmd 'focus mode_toggle';
 
-sleep 0.25;
+sync_with_i3($x);
 
 is($x->input_focus, $first->id, 'first (tiling) container focused');
 
 cmd 'focus mode_toggle';
 
-sleep 0.25;
+sync_with_i3($x);
 
 is($x->input_focus, $second->id, 'second (floating) container focused');
 
@@ -180,35 +199,37 @@ $first = open_standard_window($x, '#ff0000', 1);    # window 10
 $second = open_standard_window($x, '#00ff00', 1);   # window 11
 $third = open_standard_window($x, '#0000ff', 1);   # window 12
 
+sync_with_i3($x);
+
 is($x->input_focus, $third->id, 'third container focused');
 
 cmd 'focus left';
 
-sleep 0.25;
+sync_with_i3($x);
 
 is($x->input_focus, $second->id, 'second container focused');
 
 cmd 'focus left';
 
-sleep 0.25;
+sync_with_i3($x);
 
 is($x->input_focus, $first->id, 'first container focused');
 
 cmd 'focus left';
 
-sleep 0.25;
+sync_with_i3($x);
 
 is($x->input_focus, $third->id, 'focus wrapped to third container');
 
 cmd 'focus right';
 
-sleep 0.25;
+sync_with_i3($x);
 
 is($x->input_focus, $first->id, 'focus wrapped to first container');
 
 cmd 'focus right';
 
-sleep 0.25;
+sync_with_i3($x);
 
 is($x->input_focus, $second->id, 'focus on second container');
 
index f33d04dbcd1b093a433bdcdb433ebe843e8a083d..91467ed3785ff1b3a054e3e5a03809349d2e1a60 100644 (file)
@@ -22,20 +22,7 @@ ok(workspace_exists($tmp), "workspace $tmp exists");
 my $x = X11::XCB::Connection->new;
 
 # Create a floating window which is smaller than the minimum enforced size of i3
-my $window = $x->root->create_child(
-    class => WINDOW_CLASS_INPUT_OUTPUT,
-    rect => [ 0, 0, 30, 30],
-    background_color => '#C0C0C0',
-    # replace the type with 'utility' as soon as the coercion works again in X11::XCB
-    window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_UTILITY'),
-);
-
-isa_ok($window, 'X11::XCB::Window');
-
-$window->map;
-
-sleep 0.25;
-
+my $window = open_standard_window($x, undef, 1);
 ok($window->mapped, 'Window is mapped');
 
 # switch to a different workspace, see if the window is still mapped?
index 3ae4b12d95a2e3a50030d53405f0147434021793..b3be1348b7b8e6ecb4f3c6a1ea6c372118a19983 100644 (file)
@@ -21,27 +21,14 @@ my $tmp = fresh_workspace;
 my $x = X11::XCB::Connection->new;
 
 # Create a floating window which is smaller than the minimum enforced size of i3
-my $window = $x->root->create_child(
-    class => WINDOW_CLASS_INPUT_OUTPUT,
-    rect => [ 0, 0, 30, 30],
-    background_color => '#C0C0C0',
-    # replace the type with 'utility' as soon as the coercion works again in X11::XCB
-    window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_UTILITY'),
-);
-
-isa_ok($window, 'X11::XCB::Window');
-
-$window->map;
-
-sleep 0.25;
-
+my $window = open_standard_window($x, undef, 1);
 ok($window->mapped, 'Window is mapped');
 
 # switch to a different workspace, see if the window is still mapped?
 
 my $otmp = fresh_workspace;
 
-sleep 0.25;
+sync_with_i3($x);
 
 ok(!$window->mapped, 'Window is not mapped after switching ws');
 
index 31bddafde61df1a71fbff77e315d3541713ee79f..411ffa8e8423a0701134e42be2e7bce0a1c75e96 100644 (file)
@@ -5,7 +5,6 @@
 
 use i3test;
 use X11::XCB qw(:all);
-use Time::HiRes qw(sleep);
 
 BEGIN {
     use_ok('X11::XCB::Window');
@@ -22,20 +21,7 @@ my $tmp = fresh_workspace;
 my $x = X11::XCB::Connection->new;
 
 # Create a floating window
-my $window = $x->root->create_child(
-    class => WINDOW_CLASS_INPUT_OUTPUT,
-    rect => [ 0, 0, 30, 30],
-    background_color => '#C0C0C0',
-    # replace the type with 'utility' as soon as the coercion works again in X11::XCB
-    window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_UTILITY'),
-);
-
-isa_ok($window, 'X11::XCB::Window');
-
-$window->map;
-
-sleep 0.25;
-
+my $window = open_standard_window($x, undef, 1);
 ok($window->mapped, 'Window is mapped');
 
 my $ws = get_ws($tmp);
@@ -45,17 +31,7 @@ is(@{$ws->{floating_nodes}}, 1, 'one floating node');
 is(@{$nodes}, 0, 'no tiling nodes');
 
 # Create a tiling window
-my $twindow = $x->root->create_child(
-    class => WINDOW_CLASS_INPUT_OUTPUT,
-    rect => [ 0, 0, 30, 30],
-    background_color => '#C0C0C0',
-);
-
-isa_ok($twindow, 'X11::XCB::Window');
-
-$twindow->map;
-
-sleep 0.25;
+my $twindow = open_standard_window($x);
 
 ($nodes, $focus) = get_ws_content($tmp);
 
@@ -78,20 +54,7 @@ is(@{$ws->{floating_nodes}}, 0, 'no floating nodes so far');
 is(@{$ws->{nodes}}, 1, 'one tiling node (stacked con)');
 
 # Create a floating window
-my $window = $x->root->create_child(
-    class => WINDOW_CLASS_INPUT_OUTPUT,
-    rect => [ 0, 0, 30, 30],
-    background_color => '#C0C0C0',
-    # replace the type with 'utility' as soon as the coercion works again in X11::XCB
-    window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_UTILITY'),
-);
-
-isa_ok($window, 'X11::XCB::Window');
-
-$window->map;
-
-sleep 0.25;
-
+my $window = open_standard_window($x, undef, 1);
 ok($window->mapped, 'Window is mapped');
 
 $ws = get_ws($tmp);
index 9df220d16dab4920ddee4f3bb882f889b889330d..1121f124bbb270a92187926d29230a0b81ee6806 100644 (file)
@@ -4,7 +4,6 @@
 # bug introduced by 77d0d42ed2d7ac8cafe267c92b35a81c1b9491eb
 use i3test;
 use X11::XCB qw(:all);
-use Time::HiRes qw(sleep);
 
 BEGIN {
     use_ok('X11::XCB::Window');
@@ -26,11 +25,10 @@ sub check_order {
 my $tmp = fresh_workspace;
 
 my $left = open_standard_window($x);
-sleep 0.25;
 my $mid = open_standard_window($x);
-sleep 0.25;
 my $right = open_standard_window($x);
-sleep 0.25;
+
+sync_with_i3($x);
 
 diag("left = " . $left->id . ", mid = " . $mid->id . ", right = " . $right->id);
 
index 1d1b1206667c42de6c1ce04566535b87609780d5..2a3846d81a72bda2905dc78c9c90198e2b4ee8ec 100644 (file)
@@ -15,9 +15,9 @@ my $tmp = fresh_workspace;
 cmd 'split v';
 
 my $top = open_standard_window($x);
-sleep 0.25;
 my $bottom = open_standard_window($x);
-sleep 0.25;
+
+sync_with_i3($x);
 
 diag("top = " . $top->id . ", bottom = " . $bottom->id);
 
@@ -55,9 +55,7 @@ $tmp = fresh_workspace;
 cmd 'split v';
 
 $top = open_standard_window($x);
-sleep 0.25;
 $bottom = open_standard_window($x);
-sleep 0.25;
 
 cmd 'split h';
 cmd 'layout stacked';
@@ -79,7 +77,6 @@ is($nodes->[1]->{percent}, 0.75, 'bottom window got 75%');
 $tmp = fresh_workspace;
 
 $top = open_standard_window($x);
-sleep 0.25;
 
 cmd 'floating enable';
 
index 98b93ef1793cb2457b5c70da98e8dd1f322c2d14..4a57f21154b3eacee9f1f4ea3f1060527cb3f758 100644 (file)
@@ -18,11 +18,8 @@ my $x = X11::XCB::Connection->new;
 my $tmp = fresh_workspace;
 
 my $left = open_standard_window($x);
-sleep 0.25;
 my $mid = open_standard_window($x);
-sleep 0.25;
 my $right = open_standard_window($x);
-sleep 0.25;
 
 cmd 'move before v';
 cmd 'move after h';
index a4e90d4d1bfa96202b80e8f52e55eac90db5b63c..07f78956e95f45bd40882e6e1eb94083ac0dcaca 100644 (file)
@@ -2,7 +2,6 @@
 # vim:ts=4:sw=4:expandtab
 #
 use X11::XCB qw(:all);
-use Time::HiRes qw(sleep);
 use i3test;
 
 BEGIN {
@@ -14,13 +13,10 @@ my $x = X11::XCB::Connection->new;
 my $tmp = fresh_workspace;
 
 my $left = open_standard_window($x);
-sleep 0.25;
 my $mid = open_standard_window($x);
-sleep 0.25;
 
 cmd 'split v';
 my $bottom = open_standard_window($x);
-sleep 0.25;
 
 my ($nodes, $focus) = get_ws_content($tmp);
 
@@ -31,20 +27,7 @@ my ($nodes, $focus) = get_ws_content($tmp);
 my $x = X11::XCB::Connection->new;
 
 # Create a floating window
-my $window = $x->root->create_child(
-    class => WINDOW_CLASS_INPUT_OUTPUT,
-    rect => [ 0, 0, 30, 30],
-    background_color => '#C0C0C0',
-    # replace the type with 'utility' as soon as the coercion works again in X11::XCB
-    window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_UTILITY'),
-);
-
-isa_ok($window, 'X11::XCB::Window');
-
-$window->map;
-
-sleep 0.25;
-
+my $window = open_standard_window($x, undef, 1);
 ok($window->mapped, 'Window is mapped');
 
 ($nodes, $focus) = get_ws_content($tmp);
index 6e04916d98edddd05af68e1c97b632a823e57000..8425f6d9c6de342e1bacb03c3f26897d81ab678c 100644 (file)
@@ -17,11 +17,8 @@ my $x = X11::XCB::Connection->new;
 my $tmp = fresh_workspace;
 
 my $left = open_standard_window($x);
-sleep 0.25;
 my $mid = open_standard_window($x);
-sleep 0.25;
 my $right = open_standard_window($x);
-sleep 0.25;
 
 # go to workspace level
 cmd 'level up';
index 0bec541832ba18de45c79361eacd0d272f6bd8a7..355e697ade7d4e0dd58a6faaf25f2a2bff4e2a75 100644 (file)
@@ -17,20 +17,20 @@ my $tmp = fresh_workspace;
 
 # open a tiling window on the first workspace
 open_standard_window($x);
-sleep 0.25;
+#sleep 0.25;
 my $first = get_focused($tmp);
 
 # on a different ws, open a floating window
 my $otmp = fresh_workspace;
 open_standard_window($x);
-sleep 0.25;
+#sleep 0.25;
 my $float = get_focused($otmp);
 cmd 'mode toggle';
-sleep 0.25;
+#sleep 0.25;
 
 # move the floating con to first workspace
 cmd "move workspace $tmp";
-sleep 0.25;
+#sleep 0.25;
 
 # switch to the first ws and check focus
 is(get_focused($tmp), $float, 'floating client correctly focused');
index 16e62c2078da89334c7f04788bd460b69c245bed..1daa27095df512bdfd8f9cf4e7cbafba31d1a24d 100644 (file)
@@ -30,7 +30,7 @@ cmp_ok($absolute->{width}, '>', 400, 'i3 raised the width');
 cmp_ok($absolute->{height}, '>', 150, 'i3 raised the height');
 
 cmd 'floating toggle';
-sleep 0.25;
+sync_with_i3($x);
 
 ($absolute, $top) = $window->rect;
 
index ee60dc7ae0bc5e17d49edc6d6332030a88fa08c5..89af62196e90e3f8f7c882b9f4b8d4b2589a8be8 100644 (file)
@@ -56,7 +56,7 @@ cmd "move workspace $tmp2";
 
 # verify that the third window has the focus
 
-sleep 0.25;
+sync_with_i3($x);
 
 is($x->input_focus, $third->id, 'third window focused');
 
index 8d188738a537901bb0e3dc5d7aa1d24dcba80dd9..5fb88129ea3c6e320e1f1916f603809680a9641d 100644 (file)
@@ -52,7 +52,7 @@ is($docknode->{rect}->{height}, 30, 'dock node has unchanged height');
 
 $window->add_hint('urgency');
 
-sleep 0.25;
+sync_with_i3($x);
 
 does_i3_live;
 
index 7e983289aba5d64cf66ef806a9246b95da4640df..b91614007567ece6da6f381a073eaffd241dda7b 100644 (file)
@@ -16,25 +16,18 @@ BEGIN {
 
 my $x = X11::XCB::Connection->new;
 
-my $window = $x->root->create_child(
-    class => WINDOW_CLASS_INPUT_OUTPUT,
-    rect => [ 0, 0, 30, 30 ],
-    background_color => '#00ff00',
-    event_mask => [ 'structure_notify' ],
-);
+my $window = open_standard_window($x);
 
-$window->name('Window 1');
-$window->map;
+sync_with_i3($x);
 
 diag('window mapped');
 
-sleep 0.5;
-
 is($window->state, ICCCM_WM_STATE_NORMAL, 'WM_STATE normal');
 
 $window->unmap;
 
-sleep 0.5;
+# TODO: wait for unmapnotify
+sync_with_i3($x);
 
 is($window->state, ICCCM_WM_STATE_WITHDRAWN, 'WM_STATE withdrawn');
 
index 2b9f6e5656cb757484bd1d3299c23043bb00e18e..0e07ebf7957f10534aeabf378a67a710a65899bb 100644 (file)
@@ -30,6 +30,8 @@ ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
 my $first = open_standard_window($x);
 my $second = open_standard_window($x);
 
+sync_with_i3($x);
+
 is($x->input_focus, $second->id, 'second window focused');
 ok(@{get_ws_content($tmp)} == 2, 'two containers opened');
 isnt($content[0]->{layout}, 'stacked', 'layout not stacked');
@@ -57,6 +59,8 @@ ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
 $first = open_standard_window($x);
 $second = open_standard_window($x);
 
+sync_with_i3($x);
+
 is($x->input_focus, $second->id, 'second window focused');
 my @content = @{get_ws_content($tmp)};
 ok(@content == 1, 'one con at workspace level');
index f2dfc18eb6a9a30510471e915d170e89b34afc99..cf1c32168b4794fe958d6ef83cb8c5b0a672d620 100644 (file)
@@ -73,6 +73,9 @@ cmd 'layout tabbed';
 cmd 'focus parent';
 
 $third = open_standard_window($x);
+
+sync_with_i3($x);
+
 is($x->input_focus, $third->id, 'third window focused');
 
 cmd 'focus left';
index 9ded49429012e2adaa0b0f81449a4dd7dcbf819a..2a51dad65c4e8c7ef4a4bbfca67f973defd2b9c5 100644 (file)
@@ -40,6 +40,7 @@ our @EXPORT = qw(
 
 my $tester = Test::Builder->new();
 my $_cached_socket_path = undef;
+my $_sync_window = undef;
 my $tmp_socket_path = undef;
 
 BEGIN {
@@ -66,6 +67,44 @@ use warnings;
     goto \&Exporter::import;
 }
 
+#
+# Waits for the next event and calls the given callback for every event to
+# determine if this is the event we are waiting for.
+#
+# Can be used to wait until a window is mapped, until a ClientMessage is
+# received, etc.
+#
+# wait_for_event $x, 0.25, sub { $_[0]->{response_type} == MAP_NOTIFY };
+#
+sub wait_for_event {
+    my ($x, $timeout, $cb) = @_;
+
+    my $cv = AE::cv;
+
+    my $prep = EV::prepare sub {
+        $x->flush;
+    };
+
+    my $check = EV::check sub {
+        while (defined(my $event = $x->poll_for_event)) {
+            if ($cb->($event)) {
+                $cv->send(1);
+                last;
+            }
+        }
+    };
+
+    my $watcher = EV::io $x->get_file_descriptor, EV::READ, sub {
+        # do nothing, we only need this watcher so that EV picks up the events
+    };
+
+    # Trigger timeout after $timeout seconds (can be fractional)
+    my $timeout = AE::timer $timeout, 0, sub { say STDERR "timeout"; $cv->send(0) };
+
+    my $result = $cv->recv;
+    return $result;
+}
+
 sub open_standard_window {
     my ($x, $color, $floating) = @_;
 
@@ -88,29 +127,7 @@ sub open_standard_window {
     $window->name('Window ' . counter_window());
     $window->map;
 
-    # wait for the mapped event with a timeout of 0.25s
-    my $cv = AE::cv;
-
-    my $prep = EV::prepare sub {
-        $x->flush;
-    };
-
-    my $check = EV::check sub {
-        while (defined(my $event = $x->poll_for_event)) {
-            if ($event->{response_type} == MAP_NOTIFY) {
-                $cv->send(0)
-            }
-        }
-    };
-
-    my $watcher = EV::io $x->get_file_descriptor, EV::READ, sub {
-        # do nothing, we only need this watcher so that EV picks up the events
-    };
-
-    # Trigger timeout after 0.25s
-    my $timeout = AE::timer 0.5, 0, sub { say STDERR "timeout"; $cv->send(1) };
-
-    my $result = $cv->recv;
+    wait_for_event $x, 0.5, sub { $_[0]->{response_type} == MAP_NOTIFY };
 
     return $window;
 }
@@ -239,6 +256,69 @@ sub focused_ws {
     }
 }
 
+#
+# Sends an I3_SYNC ClientMessage with a random value to the root window.
+# i3 will reply with the same value, but, due to the order of events it
+# processes, only after all other events are done.
+#
+# This can be used to ensure the results of a cmd 'focus left' are pushed to
+# X11 and that $x->input_focus returns the correct value afterwards.
+#
+# See also docs/testsuite for a long explanation
+#
+sub sync_with_i3 {
+    my ($x) = @_;
+
+    # Since we need a (mapped) window for receiving a ClientMessage, we create
+    # one on the first call of sync_with_i3. It will be re-used in all
+    # subsequent calls.
+    if (!defined($_sync_window)) {
+        $_sync_window = $x->root->create_child(
+            class => WINDOW_CLASS_INPUT_OUTPUT,
+            rect => X11::XCB::Rect->new(x => -15, y => -15, width => 10, height => 10 ),
+            override_redirect => 1,
+            background_color => '#ff0000',
+            event_mask => [ 'structure_notify' ],
+        );
+
+        $_sync_window->map;
+
+        wait_for_event $x, 0.5, sub { $_[0]->{response_type} == MAP_NOTIFY };
+    }
+
+    my $root = $x->root->id;
+    # Generate a random number to identify this particular ClientMessage.
+    my $myrnd = int(rand(255)) + 1;
+
+    # Generate a ClientMessage, see xcb_client_message_t
+    my $msg = pack "CCSLLLLLLL",
+         CLIENT_MESSAGE, # response_type
+         32,     # format
+         0,      # sequence
+         $root,  # destination window
+         $x->atom(name => 'I3_SYNC')->id,
+
+         $_sync_window->id,    # data[0]: our own window id
+         $myrnd, # data[1]: a random value to identify the request
+         0,
+         0,
+         0;
+
+    # Send it to the root window -- since i3 uses the SubstructureRedirect
+    # event mask, it will get the ClientMessage.
+    $x->send_event(0, $root, EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);
+
+    # now wait until the reply is here
+    return wait_for_event $x, 1, sub {
+        my ($event) = @_;
+        # TODO: const
+        return 0 unless $event->{response_type} == 161;
+
+        my ($win, $rnd) = unpack "LL", $event->{data};
+        return ($rnd == $myrnd);
+    };
+}
+
 sub does_i3_live {
     my $tree = i3(get_socket_path())->get_tree->recv;
     my @nodes = @{$tree->{nodes}};