It now returns a pid directly, not a Proc::Background object.
# default case: socket will be created in /tmp/i3-<username>/ipc-socket.<pid>
#####################################################################
-my ($fh, $tmpfile) = tempfile('/tmp/i3-test-config.XXXXXX', UNLINK => 1);
-say $fh "# i3 config file (v4)";
-say $fh "font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1";
-close($fh);
+my $config = <<EOT;
+# i3 config file (v4)
+font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
+EOT
-diag("Starting i3");
-my $i3cmd = "unset XDG_RUNTIME_DIR; exec " . abs_path("../i3") . " -V -d all --disable-signalhandler -c $tmpfile >/dev/null 2>/dev/null";
-my $process = Proc::Background->new($i3cmd);
-sleep 1;
-
-diag("pid = " . $process->pid);
+# ensure XDG_RUNTIME_DIR is not set
+delete $ENV{XDG_RUNTIME_DIR};
+my $pid = launch_with_config($config, 1);
my $folder = "/tmp/i3-" . getpwuid(getuid());
ok(-d $folder, "folder $folder exists");
-my $socketpath = "$folder/ipc-socket." . $process->pid;
+my $socketpath = "$folder/ipc-socket." . $pid;
ok(-S $socketpath, "file $socketpath exists and is a socket");
-exit_gracefully($process->pid, $socketpath);
-
-sleep 0.25;
+exit_gracefully($pid);
#####################################################################
# XDG_RUNTIME_DIR case: socket gets created in $XDG_RUNTIME_DIR/i3/ipc-socket.<pid>
ok(! -e "$rtdir/i3", "$rtdir/i3 does not exist yet");
-$i3cmd = "export XDG_RUNTIME_DIR=$rtdir; exec " . abs_path("../i3") . " -V -d all --disable-signalhandler -c $tmpfile >/dev/null 2>/dev/null";
-$process = Proc::Background->new($i3cmd);
-sleep 1;
+$ENV{XDG_RUNTIME_DIR} = $rtdir;
+
+$pid = launch_with_config($config, 1);
ok(-d "$rtdir/i3", "$rtdir/i3 exists and is a directory");
-$socketpath = "$rtdir/i3/ipc-socket." . $process->pid;
+$socketpath = "$rtdir/i3/ipc-socket." . $pid;
ok(-S $socketpath, "file $socketpath exists and is a socket");
-exit_gracefully($process->pid, $socketpath);
-
-sleep 0.25;
+exit_gracefully($pid);
#####################################################################
# configuration file case: socket gets placed whereever we specify
$socketpath = $tmpdir . "/config.sock";
ok(! -e $socketpath, "$socketpath does not exist yet");
-($fh, $tmpfile) = tempfile('/tmp/i3-test-config.XXXXXX', UNLINK => 1);
-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";
-close($fh);
+$config = <<EOT;
+# i3 config file (v4)
+font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
+ipc-socket $socketpath
+EOT
-$i3cmd = "export XDG_RUNTIME_DIR=$rtdir; exec " . abs_path("../i3") . " -V -d all --disable-signalhandler -c $tmpfile >/dev/null 2>/dev/null";
-$process = Proc::Background->new($i3cmd);
-sleep 1;
+$pid = launch_with_config($config, 1);
ok(-S $socketpath, "file $socketpath exists and is a socket");
-exit_gracefully($process->pid, $socketpath);
+exit_gracefully($pid);
done_testing;
for_window [title="special borderless title"] border none
EOT
-my $process = launch_with_config($config);
+my $pid = launch_with_config($config);
my $tmp = fresh_workspace;
@content = @{get_ws_content($tmp)};
cmp_ok(@content, '==', 0, 'no more nodes');
-exit_gracefully($process->pid);
+exit_gracefully($pid);
##############################################################
# 2: match on the title, check if for_window is really executed
for_window [title="special borderless title"] border none
EOT
-$process = launch_with_config($config);
+$pid = launch_with_config($config);
$tmp = fresh_workspace;
@content = @{get_ws_content($tmp)};
cmp_ok(@content, '==', 0, 'no more nodes');
-exit_gracefully($process->pid);
+exit_gracefully($pid);
##############################################################
# 3: match on the title, set border style *and* a mark
for_window [title="special mark title"] border none, mark bleh
EOT
-$process = launch_with_config($config);
+$pid = launch_with_config($config);
$tmp = fresh_workspace;
@content = @{get_ws_content($tmp)};
ok($content[0]->{focused}, 'first node focused');
-exit_gracefully($process->pid);
+exit_gracefully($pid);
##############################################################
# 4: multiple criteria for the for_window command
for_window [class="borderless" title="usethis"] border none
EOT
-$process = launch_with_config($config);
+$pid = launch_with_config($config);
$tmp = fresh_workspace;
cmp_ok(@content, '==', 1, 'one node on this workspace now');
is($content[0]->{border}, 'none', 'no border');
-$window->unmap;
+cmd 'kill';
wait_for_unmap $x;
+$window->destroy;
@content = @{get_ws_content($tmp)};
cmp_ok(@content, '==', 0, 'no nodes on this workspace now');
+$window->_create;
+
set_wm_class($window->id, 'borderless', 'borderless');
$window->name('notthis');
$window->map;
is($content[0]->{border}, 'normal', 'no border');
-exit_gracefully($process->pid);
+exit_gracefully($pid);
##############################################################
# 5: check that a class criterion does not match the instance
for_window [class="foo"] border 1pixel
EOT
-$process = launch_with_config($config);
+$pid = launch_with_config($config);
$tmp = fresh_workspace;
cmp_ok(@content, '==', 1, 'one node on this workspace now');
is($content[0]->{border}, 'normal', 'normal border, not matched');
-exit_gracefully($process->pid);
+exit_gracefully($pid);
##############################################################
# 6: check that the 'instance' criterion works
for_window [instance="foo"] border none
EOT
-$process = launch_with_config($config);
+$pid = launch_with_config($config);
$tmp = fresh_workspace;
cmp_ok(@content, '==', 1, 'one node on this workspace now');
is($content[0]->{border}, 'none', 'no border');
-exit_gracefully($process->pid);
+exit_gracefully($pid);
##############################################################
# 7: check that invalid criteria don’t end up matching all windows
for_window [id="asdf"] border none
EOT
-$process = launch_with_config($config);
+$pid = launch_with_config($config);
$tmp = fresh_workspace;
cmp_ok(@content, '==', 1, 'one node on this workspace now');
is($content[0]->{border}, 'normal', 'normal border');
-exit_gracefully($process->pid);
+exit_gracefully($pid);
##############################################################
# 8: check that the role criterion works properly
for_window [window_role="i3test"] border none
EOT
-$process = launch_with_config($config);
+$pid = launch_with_config($config);
$tmp = fresh_workspace;
cmp_ok(@content, '==', 1, 'one node on this workspace now');
is($content[0]->{border}, 'none', 'no border (window_role)');
-exit_gracefully($process->pid);
+exit_gracefully($pid);
##############################################################
# 9: another test for the window_role, but this time it changes
for_window [window_role="i3test"] border none
EOT
-$process = launch_with_config($config);
+$pid = launch_with_config($config);
$tmp = fresh_workspace;
cmp_ok(@content, '==', 1, 'one node on this workspace now');
is($content[0]->{border}, 'none', 'no border (window_role 2)');
-exit_gracefully($process->pid);
+exit_gracefully($pid);
done_testing;
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
EOT
-my $process = launch_with_config($config);
+my $pid = launch_with_config($config);
my $tmp = fresh_workspace;
ok(@{get_ws_content($tmp)} == 1, 'special window got managed to current (random) workspace');
-exit_gracefully($process->pid);
+exit_gracefully($pid);
$window->destroy;
assign "special" → targetws
EOT
-$process = launch_with_config($config);
+$pid = launch_with_config($config);
$tmp = fresh_workspace;
$window->destroy;
-exit_gracefully($process->pid);
+exit_gracefully($pid);
sleep 0.25;
# already, next to the existing node.
#####################################################################
-$process = launch_with_config($config);
+$pid = launch_with_config($config);
# initialize the target workspace, then go to a fresh one
ok(!("targetws" ~~ @{get_workspace_names()}), 'targetws does not exist yet');
ok(@{get_ws_content($tmp)} == 0, 'still no containers');
ok(@{get_ws_content('targetws')} == 2, 'two containers on targetws');
-exit_gracefully($process->pid);
+exit_gracefully($pid);
#####################################################################
# start a window and see that it gets assigned to a workspace which has content
assign "special" → ~
EOT
-$process = launch_with_config($config);
+$pid = launch_with_config($config);
$tmp = fresh_workspace;
$window->destroy;
-exit_gracefully($process->pid);
+exit_gracefully($pid);
sleep 0.25;
assign "special" → ~
EOT
-$process = launch_with_config($config);
+$pid = launch_with_config($config);
$tmp = fresh_workspace;
$window->destroy;
-exit_gracefully($process->pid);
+exit_gracefully($pid);
sleep 0.25;
assign "special" → ~
EOT
-$process = launch_with_config($config);
+$pid = launch_with_config($config);
+
+# TODO: replace this with checking the process hierarchy
+# XXX: give i3-nagbar some time to start up
+sleep 1;
$tmp = fresh_workspace;
does_i3_live;
-exit_gracefully($process->pid);
+exit_gracefully($pid);
sleep 0.25;
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
EOT
-my $process = launch_with_config($config);
+my $pid = launch_with_config($config);
my $tmp = fresh_workspace;
isnt($content[0]->{layout}, 'stacked', 'layout not stacked');
isnt($content[1]->{layout}, 'stacked', 'layout not stacked');
-exit_gracefully($process->pid);
+exit_gracefully($pid);
#####################################################################
# 2: set workspace_layout stacked, check that when opening two cons,
workspace_layout stacked
EOT
-$process = launch_with_config($config);
+$pid = launch_with_config($config);
$tmp = fresh_workspace;
is(@content, 1, 'one con on target workspace');
is($content[0]->{layout}, 'stacked', 'layout stacked');
-exit_gracefully($process->pid);
+exit_gracefully($pid);
done_testing;
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
EOT
-my $process = launch_with_config($config);
+my $pid = launch_with_config($config);
my $tmp = fresh_workspace;
cmd 'focus right';
is($x->input_focus, $third->id, 'third window focused');
-exit_gracefully($process->pid);
+exit_gracefully($pid);
#####################################################################
# 2: test the wrapping behaviour with force_focus_wrapping
force_focus_wrapping true
EOT
-$process = launch_with_config($config);
+$pid = launch_with_config($config);
$tmp = fresh_workspace;
cmd 'focus right';
is($x->input_focus, $first->id, 'first window focused');
-exit_gracefully($process->pid);
+exit_gracefully($pid);
done_testing;
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
EOT
-my $process = launch_with_config($config);
+my $pid = launch_with_config($config);
my @names = @{get_workspace_names()};
cmp_deeply(\@names, [ '1' ], 'i3 starts on workspace 1 without any configuration');
-exit_gracefully($process->pid);
+exit_gracefully($pid);
##############################################################
# 2: with named workspaces, i3 should start on the first named one
bindsym Mod1+1 workspace foobar
EOT
-$process = launch_with_config($config);
+$pid = launch_with_config($config);
my @names = @{get_workspace_names()};
cmp_deeply(\@names, [ 'foobar' ], 'i3 starts on named workspace foobar');
-exit_gracefully($process->pid);
+exit_gracefully($pid);
##############################################################
# 3: the same test as 2, but with a quoted workspace name
bindsym Mod1+1 workspace "foobar"
EOT
-$process = launch_with_config($config);
+$pid = launch_with_config($config);
my @names = @{get_workspace_names()};
cmp_deeply(\@names, [ 'foobar' ], 'i3 starts on named workspace foobar');
-exit_gracefully($process->pid);
+exit_gracefully($pid);
done_testing;
assign "special" → targetws
EOT
-my $process = launch_with_config($config);
+my $pid = launch_with_config($config);
my $tmp = fresh_workspace;
ok(@{get_ws_content('targetws')} == 1, 'special window on targetws');
ok(get_ws($tmp)->{focused}, 'current workspace still focused');
-exit_gracefully($process->pid);
+exit_gracefully($pid);
$window->destroy;
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
EOT
-my $process = launch_with_config($config);
+my $pid = launch_with_config($config);
my $tmp = fresh_workspace;
ok(@content == 1, 'one container opened');
is($content[0]->{border}, 'normal', 'border normal by default');
-exit_gracefully($process->pid);
+exit_gracefully($pid);
#####################################################################
# 2: check that new tiling windows start with '1pixel' border when
new_window 1pixel
EOT
-$process = launch_with_config($config);
+$pid = launch_with_config($config);
$tmp = fresh_workspace;
ok(@content == 1, 'one container opened');
is($content[0]->{border}, '1pixel', 'border normal by default');
-exit_gracefully($process->pid);
+exit_gracefully($pid);
#####################################################################
# 3: check that new floating windows start with 'normal' border unless
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
EOT
-$process = launch_with_config($config);
+$pid = launch_with_config($config);
$tmp = fresh_workspace;
my $floatingcon = $floating[0];
is($floatingcon->{nodes}->[0]->{border}, 'normal', 'border normal by default');
-exit_gracefully($process->pid);
+exit_gracefully($pid);
#####################################################################
# 4: check that new floating windows start with '1pixel' border when
new_float 1pixel
EOT
-$process = launch_with_config($config);
+$pid = launch_with_config($config);
$tmp = fresh_workspace;
$floatingcon = $floating[0];
is($floatingcon->{nodes}->[0]->{border}, '1pixel', 'border normal by default');
-exit_gracefully($process->pid);
+exit_gracefully($pid);
done_testing;