]> git.sur5r.net Git - i3/i3/blobdiff - testcases/t/65-for_window.t
Merge branch 'master' into next
[i3/i3] / testcases / t / 65-for_window.t
index 26ccb7cfaa832a4e42f7e758f894812803bc461c..36a20ea9e4394272d1a7de188b5d9d039f9b4d15 100644 (file)
@@ -6,15 +6,9 @@
 use X11::XCB qw(:all);
 use X11::XCB::Connection;
 use i3test;
-use Cwd qw(abs_path);
-use Proc::Background;
-use File::Temp qw(tempfile tempdir);
 
 my $x = X11::XCB::Connection->new;
 
-# assuming we are run by complete-run.pl
-my $i3_path = abs_path("../i3");
-
 ##############################################################
 # 1: test the following directive:
 #    for_window [class="borderless"] border none
@@ -23,22 +17,14 @@ my $i3_path = abs_path("../i3");
 # "borderless" (should get no border)
 ##############################################################
 
-my $socketpath = File::Temp::tempnam('/tmp', 'i3-test-socket-');
-
-my ($fh, $tmpfile) = tempfile();
-say $fh "# i3 config file (v4)";
-say $fh "font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1";
-say $fh "ipc-socket $socketpath";
-say $fh q|for_window [class="borderless"] border none|;
-close($fh);
-
-diag("Starting i3");
-my $i3cmd = "exec " . abs_path("../i3") . " -V -d all --disable-signalhandler -c $tmpfile >/dev/null 2>/dev/null";
-my $process = Proc::Background->new($i3cmd);
-sleep 1;
+my $config = <<EOT;
+# i3 config file (v4)
+font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
+for_window [class="borderless"] border none
+for_window [title="special borderless title"] border none
+EOT
 
-# force update of the cached socket path in lib/i3test
-get_socket_path(0);
+my $process = launch_with_config($config);
 
 my $tmp = fresh_workspace;
 
@@ -46,18 +32,19 @@ my $window = $x->root->create_child(
     class => WINDOW_CLASS_INPUT_OUTPUT,
     rect => [ 0, 0, 30, 30 ],
     background_color => '#00ff00',
+    event_mask => [ 'structure_notify' ],
 );
 
 $window->name('Border window');
 $window->map;
-sleep 0.25;
+wait_for_map $x;
 
 my @content = @{get_ws_content($tmp)};
 cmp_ok(@content, '==', 1, 'one node on this workspace now');
 is($content[0]->{border}, 'normal', 'normal border');
 
 $window->unmap;
-sleep 0.25;
+wait_for_unmap $x;
 
 my @content = @{get_ws_content($tmp)};
 cmp_ok(@content, '==', 0, 'no more nodes');
@@ -67,6 +54,7 @@ $window = $x->root->create_child(
     class => WINDOW_CLASS_INPUT_OUTPUT,
     rect => [ 0, 0, 30, 30 ],
     background_color => '#00ff00',
+    event_mask => [ 'structure_notify' ],
 );
 
 $window->_create;
@@ -93,14 +81,14 @@ sub set_wm_class {
 set_wm_class($window->id, 'borderless', 'borderless');
 $window->name('Borderless window');
 $window->map;
-sleep 0.25;
+wait_for_map $x;
 
 @content = @{get_ws_content($tmp)};
 cmp_ok(@content, '==', 1, 'one node on this workspace now');
 is($content[0]->{border}, 'none', 'no border');
 
 $window->unmap;
-sleep 0.25;
+wait_for_unmap $x;
 
 @content = @{get_ws_content($tmp)};
 cmp_ok(@content, '==', 0, 'no more nodes');
@@ -112,21 +100,14 @@ exit_gracefully($process->pid);
 # only once
 ##############################################################
 
-($fh, $tmpfile) = tempfile();
-say $fh "# i3 config file (v4)";
-say $fh "font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1";
-say $fh "ipc-socket $socketpath";
-say $fh q|for_window [class="borderless"] border none|;
-say $fh q|for_window [title="special borderless title"] border none|;
-close($fh);
+$config = <<EOT;
+# i3 config file (v4)
+font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
+for_window [class="borderless"] border none
+for_window [title="special borderless title"] border none
+EOT
 
-diag("Starting i3");
-my $i3cmd = "exec " . abs_path("../i3") . " -V -d all --disable-signalhandler -c $tmpfile >/dev/null 2>/dev/null";
-my $process = Proc::Background->new($i3cmd);
-sleep 1;
-
-# force update of the cached socket path in lib/i3test
-get_socket_path(0);
+$process = launch_with_config($config);
 
 $tmp = fresh_workspace;
 
@@ -134,24 +115,25 @@ $window = $x->root->create_child(
     class => WINDOW_CLASS_INPUT_OUTPUT,
     rect => [ 0, 0, 30, 30 ],
     background_color => '#00ff00',
+    event_mask => [ 'structure_notify' ],
 );
 
 $window->name('special title');
 $window->map;
-sleep 0.25;
+wait_for_map $x;
 
 @content = @{get_ws_content($tmp)};
 cmp_ok(@content, '==', 1, 'one node on this workspace now');
 is($content[0]->{border}, 'normal', 'normal border');
 
 $window->name('special borderless title');
-sleep 0.25;
+sync_with_i3 $x;
 
 @content = @{get_ws_content($tmp)};
 is($content[0]->{border}, 'none', 'no border');
 
 $window->name('special title');
-sleep 0.25;
+sync_with_i3 $x;
 
 cmd 'border normal';
 
@@ -159,13 +141,13 @@ cmd 'border normal';
 is($content[0]->{border}, 'normal', 'border reset to normal');
 
 $window->name('special borderless title');
-sleep 0.25;
+sync_with_i3 $x;
 
 @content = @{get_ws_content($tmp)};
 is($content[0]->{border}, 'normal', 'still normal border');
 
 $window->unmap;
-sleep 0.25;
+wait_for_unmap $x;
 
 @content = @{get_ws_content($tmp)};
 cmp_ok(@content, '==', 0, 'no more nodes');
@@ -176,22 +158,16 @@ exit_gracefully($process->pid);
 # 3: match on the title, set border style *and* a mark
 ##############################################################
 
-($fh, $tmpfile) = tempfile();
-say $fh "# i3 config file (v4)";
-say $fh "font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1";
-say $fh "ipc-socket $socketpath";
-say $fh q|for_window [class="borderless"] border none|;
-say $fh q|for_window [title="special borderless title"] border none|;
-say $fh q|for_window [title="special mark title"] border none, mark bleh|;
-close($fh);
-
-diag("Starting i3");
-my $i3cmd = "exec " . abs_path("../i3") . " -V -d all --disable-signalhandler -c $tmpfile >/dev/null 2>/dev/null";
-my $process = Proc::Background->new($i3cmd);
-sleep 1;
+$config = <<EOT;
+# i3 config file (v4)
+font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
+for_window [class="borderless" title="usethis"] border none
+for_window [class="borderless"] border none
+for_window [title="special borderless title"] border none
+for_window [title="special mark title"] border none, mark bleh
+EOT
 
-# force update of the cached socket path in lib/i3test
-get_socket_path(0);
+$process = launch_with_config($config);
 
 $tmp = fresh_workspace;
 
@@ -199,17 +175,18 @@ $window = $x->root->create_child(
     class => WINDOW_CLASS_INPUT_OUTPUT,
     rect => [ 0, 0, 30, 30 ],
     background_color => '#00ff00',
+    event_mask => [ 'structure_notify' ],
 );
 
 $window->name('special mark title');
 $window->map;
-sleep 0.25;
+wait_for_map $x;
 
 @content = @{get_ws_content($tmp)};
 cmp_ok(@content, '==', 1, 'one node on this workspace now');
 is($content[0]->{border}, 'none', 'no border');
 
-my $other = open_standard_window($x);
+my $other = open_window($x);
 
 @content = @{get_ws_content($tmp)};
 cmp_ok(@content, '==', 2, 'two nodes');
@@ -228,20 +205,13 @@ exit_gracefully($process->pid);
 # 4: multiple criteria for the for_window command
 ##############################################################
 
-($fh, $tmpfile) = tempfile();
-say $fh "# i3 config file (v4)";
-say $fh "font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1";
-say $fh "ipc-socket $socketpath";
-say $fh q|for_window [class="borderless" title="usethis"] border none|;
-close($fh);
+$config = <<EOT;
+# i3 config file (v4)
+font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
+for_window [class="borderless" title="usethis"] border none
+EOT
 
-diag("Starting i3");
-my $i3cmd = "exec " . abs_path("../i3") . " -V -d all --disable-signalhandler -c $tmpfile >/tmp/a 2>/dev/null";
-my $process = Proc::Background->new($i3cmd);
-sleep 1;
-
-# force update of the cached socket path in lib/i3test
-get_socket_path(0);
+$process = launch_with_config($config);
 
 $tmp = fresh_workspace;
 
@@ -249,6 +219,7 @@ $window = $x->root->create_child(
     class => WINDOW_CLASS_INPUT_OUTPUT,
     rect => [ 0, 0, 30, 30 ],
     background_color => '#00ff00',
+    event_mask => [ 'structure_notify' ],
 );
 
 $window->_create;
@@ -256,14 +227,14 @@ $window->_create;
 set_wm_class($window->id, 'borderless', 'borderless');
 $window->name('usethis');
 $window->map;
-sleep 0.25;
+wait_for_map $x;
 
 @content = @{get_ws_content($tmp)};
 cmp_ok(@content, '==', 1, 'one node on this workspace now');
 is($content[0]->{border}, 'none', 'no border');
 
 $window->unmap;
-sleep 0.25;
+wait_for_unmap $x;
 
 @content = @{get_ws_content($tmp)};
 cmp_ok(@content, '==', 0, 'no nodes on this workspace now');
@@ -271,7 +242,7 @@ cmp_ok(@content, '==', 0, 'no nodes on this workspace now');
 set_wm_class($window->id, 'borderless', 'borderless');
 $window->name('notthis');
 $window->map;
-sleep 0.25;
+wait_for_map $x;
 
 @content = @{get_ws_content($tmp)};
 cmp_ok(@content, '==', 1, 'one node on this workspace now');
@@ -280,4 +251,216 @@ is($content[0]->{border}, 'normal', 'no border');
 
 exit_gracefully($process->pid);
 
+##############################################################
+# 5: check that a class criterion does not match the instance
+##############################################################
+
+$config = <<EOT;
+# i3 config file (v4)
+font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
+for_window [class="foo"] border 1pixel
+EOT
+
+$process = launch_with_config($config);
+
+$tmp = fresh_workspace;
+
+$window = $x->root->create_child(
+    class => WINDOW_CLASS_INPUT_OUTPUT,
+    rect => [ 0, 0, 30, 30 ],
+    background_color => '#00ff00',
+    event_mask => [ 'structure_notify' ],
+);
+
+$window->_create;
+
+set_wm_class($window->id, 'bar', 'foo');
+$window->name('usethis');
+$window->map;
+wait_for_map $x;
+
+@content = @{get_ws_content($tmp)};
+cmp_ok(@content, '==', 1, 'one node on this workspace now');
+is($content[0]->{border}, 'normal', 'normal border, not matched');
+
+exit_gracefully($process->pid);
+
+##############################################################
+# 6: check that the 'instance' criterion works
+##############################################################
+
+$config = <<EOT;
+# i3 config file (v4)
+font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
+for_window [class="foo"] border 1pixel
+for_window [instance="foo"] border none
+EOT
+
+$process = launch_with_config($config);
+
+$tmp = fresh_workspace;
+
+$window = $x->root->create_child(
+    class => WINDOW_CLASS_INPUT_OUTPUT,
+    rect => [ 0, 0, 30, 30 ],
+    background_color => '#00ff00',
+    event_mask => [ 'structure_notify' ],
+);
+
+$window->_create;
+
+set_wm_class($window->id, 'bar', 'foo');
+$window->name('usethis');
+$window->map;
+wait_for_map $x;
+
+@content = @{get_ws_content($tmp)};
+cmp_ok(@content, '==', 1, 'one node on this workspace now');
+is($content[0]->{border}, 'none', 'no border');
+
+exit_gracefully($process->pid);
+
+##############################################################
+# 7: check that invalid criteria don’t end up matching all windows
+##############################################################
+
+# this configuration is broken because "asdf" is not a valid integer
+# the for_window should therefore recognize this error and don’t add the
+# assignment
+$config = <<EOT;
+# i3 config file (v4)
+font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
+for_window [id="asdf"] border none
+EOT
+
+$process = launch_with_config($config);
+
+$tmp = fresh_workspace;
+
+$window = $x->root->create_child(
+    class => WINDOW_CLASS_INPUT_OUTPUT,
+    rect => [ 0, 0, 30, 30 ],
+    background_color => '#00ff00',
+    event_mask => [ 'structure_notify' ],
+);
+
+$window->_create;
+
+set_wm_class($window->id, 'bar', 'foo');
+$window->name('usethis');
+$window->map;
+wait_for_map $x;
+
+@content = @{get_ws_content($tmp)};
+cmp_ok(@content, '==', 1, 'one node on this workspace now');
+is($content[0]->{border}, 'normal', 'normal border');
+
+exit_gracefully($process->pid);
+
+##############################################################
+# 8: check that the role criterion works properly
+##############################################################
+
+# this configuration is broken because "asdf" is not a valid integer
+# the for_window should therefore recognize this error and don’t add the
+# assignment
+$config = <<EOT;
+# i3 config file (v4)
+font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
+for_window [window_role="i3test"] border none
+EOT
+
+$process = launch_with_config($config);
+
+$tmp = fresh_workspace;
+
+$window = $x->root->create_child(
+    class => WINDOW_CLASS_INPUT_OUTPUT,
+    rect => [ 0, 0, 30, 30 ],
+    background_color => '#00ff00',
+    event_mask => [ 'structure_notify' ],
+);
+
+$window->_create;
+
+my $atomname = $x->atom(name => 'WM_WINDOW_ROLE');
+my $atomtype = $x->atom(name => 'STRING');
+$x->change_property(
+  PROP_MODE_REPLACE,
+  $window->id,
+  $atomname->id,
+  $atomtype->id,
+  8,
+  length("i3test") + 1,
+  "i3test\x00"
+);
+
+$window->name('usethis');
+$window->map;
+wait_for_map $x;
+
+@content = @{get_ws_content($tmp)};
+cmp_ok(@content, '==', 1, 'one node on this workspace now');
+is($content[0]->{border}, 'none', 'no border (window_role)');
+
+exit_gracefully($process->pid);
+
+##############################################################
+# 9: another test for the window_role, but this time it changes
+#    *after* the window has been mapped
+##############################################################
+
+# this configuration is broken because "asdf" is not a valid integer
+# the for_window should therefore recognize this error and don’t add the
+# assignment
+$config = <<EOT;
+# i3 config file (v4)
+font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
+for_window [window_role="i3test"] border none
+EOT
+
+$process = launch_with_config($config);
+
+$tmp = fresh_workspace;
+
+$window = $x->root->create_child(
+    class => WINDOW_CLASS_INPUT_OUTPUT,
+    rect => [ 0, 0, 30, 30 ],
+    background_color => '#00ff00',
+    event_mask => [ 'structure_notify' ],
+);
+
+$window->_create;
+
+$window->name('usethis');
+$window->map;
+wait_for_map $x;
+
+@content = @{get_ws_content($tmp)};
+cmp_ok(@content, '==', 1, 'one node on this workspace now');
+is($content[0]->{border}, 'normal', 'normal border (window_role 2)');
+
+$atomname = $x->atom(name => 'WM_WINDOW_ROLE');
+$atomtype = $x->atom(name => 'STRING');
+$x->change_property(
+  PROP_MODE_REPLACE,
+  $window->id,
+  $atomname->id,
+  $atomtype->id,
+  8,
+  length("i3test") + 1,
+  "i3test\x00"
+);
+
+$x->flush;
+
+sync_with_i3 $x;
+
+@content = @{get_ws_content($tmp)};
+cmp_ok(@content, '==', 1, 'one node on this workspace now');
+is($content[0]->{border}, 'none', 'no border (window_role 2)');
+
+exit_gracefully($process->pid);
+
+
 done_testing;