2011-10-09 19:24:29 -04:00
|
|
|
|
#!perl
|
|
|
|
|
# vim:ts=4:sw=4:expandtab
|
|
|
|
|
#
|
2012-09-10 08:09:01 -04:00
|
|
|
|
# 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)
|
|
|
|
|
#
|
2011-10-09 19:24:29 -04:00
|
|
|
|
# Test for the startup notification protocol.
|
|
|
|
|
#
|
|
|
|
|
|
|
|
|
|
use i3test;
|
|
|
|
|
use POSIX qw(mkfifo);
|
|
|
|
|
use File::Temp qw(:POSIX);
|
|
|
|
|
|
2012-12-27 12:02:23 -05:00
|
|
|
|
SKIP: {
|
|
|
|
|
|
|
|
|
|
skip "X11::XCB too old (need >= 0.07)", 24 if $X11::XCB::VERSION < 0.07;
|
|
|
|
|
|
2011-10-09 19:24:29 -04:00
|
|
|
|
use ExtUtils::PkgConfig;
|
|
|
|
|
|
|
|
|
|
# setup dependency on libstartup-notification using pkg-config
|
|
|
|
|
my %sn_config;
|
|
|
|
|
BEGIN {
|
|
|
|
|
%sn_config = ExtUtils::PkgConfig->find('libstartup-notification-1.0');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
use Inline C => Config => LIBS => $sn_config{libs}, CCFLAGS => $sn_config{cflags};
|
|
|
|
|
use Inline C => <<'END_OF_C_CODE';
|
|
|
|
|
|
|
|
|
|
#include <xcb/xcb.h>
|
|
|
|
|
|
|
|
|
|
#define SN_API_NOT_YET_FROZEN 1
|
|
|
|
|
#include <libsn/sn-common.h>
|
|
|
|
|
#include <libsn/sn-launchee.h>
|
|
|
|
|
|
|
|
|
|
static SnDisplay *sndisplay;
|
|
|
|
|
static SnLauncheeContext *ctx;
|
2011-10-10 07:48:19 -04:00
|
|
|
|
static xcb_connection_t *conn;
|
2011-10-09 19:24:29 -04:00
|
|
|
|
|
2012-12-27 12:02:23 -05:00
|
|
|
|
void init_ctx(void *connptr) {
|
|
|
|
|
conn = (xcb_connection_t*)connptr;
|
2011-10-09 19:24:29 -04:00
|
|
|
|
sndisplay = sn_xcb_display_new(conn, NULL, NULL);
|
2012-12-27 12:02:23 -05:00
|
|
|
|
ctx = sn_launchee_context_new_from_environment(sndisplay, 0);
|
2011-10-09 19:24:29 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *get_startup_id() {
|
|
|
|
|
return sn_launchee_context_get_startup_id(ctx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mark_window(int window) {
|
|
|
|
|
sn_launchee_context_setup_window(ctx, (Window)window);
|
2011-10-10 07:48:19 -04:00
|
|
|
|
xcb_flush(conn);
|
2011-10-09 19:24:29 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void complete_startup() {
|
|
|
|
|
/* mark the startup process complete */
|
|
|
|
|
sn_launchee_context_complete(ctx);
|
|
|
|
|
}
|
|
|
|
|
END_OF_C_CODE
|
|
|
|
|
|
|
|
|
|
my $first_ws = fresh_workspace;
|
|
|
|
|
|
2012-09-04 16:24:13 -04:00
|
|
|
|
is_num_children($first_ws, 0, 'no containers on this workspace yet');
|
2011-10-09 19:24:29 -04:00
|
|
|
|
|
|
|
|
|
######################################################################
|
|
|
|
|
# 1) initiate startup, switch workspace, create window
|
|
|
|
|
# (should be placed on the original workspace)
|
|
|
|
|
######################################################################
|
|
|
|
|
|
|
|
|
|
# Start a new process via i3 (to initialize a new startup notification
|
|
|
|
|
# context), then steal its DESKTOP_STARTUP_ID variable. We handle the startup
|
|
|
|
|
# notification in the testcase from there on.
|
|
|
|
|
#
|
|
|
|
|
# This works by setting up a FIFO in which the process (started by i3) will
|
|
|
|
|
# echo its $DESKTOP_STARTUP_ID. We (blockingly) read the variable into
|
|
|
|
|
# $startup_id in the testcase.
|
|
|
|
|
my $tmp = tmpnam();
|
2014-07-10 16:30:45 -04:00
|
|
|
|
mkfifo($tmp, 0600) or BAIL_OUT "Could not create FIFO in $tmp: $!";
|
2011-10-09 19:24:29 -04:00
|
|
|
|
|
|
|
|
|
cmd qq|exec echo \$DESKTOP_STARTUP_ID >$tmp|;
|
|
|
|
|
|
|
|
|
|
open(my $fh, '<', $tmp);
|
|
|
|
|
chomp(my $startup_id = <$fh>);
|
|
|
|
|
close($fh);
|
|
|
|
|
|
|
|
|
|
unlink($tmp);
|
|
|
|
|
|
2011-10-25 17:21:37 -04:00
|
|
|
|
isnt($startup_id, '', 'startup_id not empty');
|
|
|
|
|
|
2011-10-09 19:24:29 -04:00
|
|
|
|
$ENV{DESKTOP_STARTUP_ID} = $startup_id;
|
|
|
|
|
|
|
|
|
|
# Create a new libstartup-notification launchee context
|
2012-12-27 12:02:23 -05:00
|
|
|
|
init_ctx($x->get_xcb_conn());
|
2011-10-09 19:24:29 -04:00
|
|
|
|
|
|
|
|
|
# Make sure the context was set up successfully
|
|
|
|
|
is(get_startup_id(), $startup_id, 'libstartup-notification returns the same id');
|
|
|
|
|
|
|
|
|
|
my $second_ws = fresh_workspace;
|
|
|
|
|
|
2012-09-04 16:24:13 -04:00
|
|
|
|
is_num_children($second_ws, 0, 'no containers on the second workspace yet');
|
2011-10-09 19:24:29 -04:00
|
|
|
|
|
2011-11-21 18:47:32 -05:00
|
|
|
|
my $win = open_window({ dont_map => 1 });
|
2011-10-09 19:24:29 -04:00
|
|
|
|
mark_window($win->id);
|
2011-10-10 07:48:19 -04:00
|
|
|
|
$win->map;
|
2011-10-10 11:00:34 -04:00
|
|
|
|
# We don’t use wait_for_map because the window will not get mapped -- it is on
|
|
|
|
|
# a different workspace.
|
2011-10-10 07:48:19 -04:00
|
|
|
|
# We sync with i3 here to make sure $x->input_focus is updated.
|
2011-11-21 19:13:37 -05:00
|
|
|
|
sync_with_i3;
|
2011-10-09 19:24:29 -04:00
|
|
|
|
|
2012-09-04 16:24:13 -04:00
|
|
|
|
is_num_children($second_ws, 0, 'still no containers on the second workspace');
|
|
|
|
|
is_num_children($first_ws, 1, 'one container on the first workspace');
|
2011-10-09 19:24:29 -04:00
|
|
|
|
|
2011-10-10 08:30:52 -04:00
|
|
|
|
######################################################################
|
|
|
|
|
# same thing, but with _NET_STARTUP_ID set on the leader
|
|
|
|
|
######################################################################
|
|
|
|
|
|
2011-11-21 18:47:32 -05:00
|
|
|
|
my $leader = open_window({ dont_map => 1 });
|
2011-10-10 08:30:52 -04:00
|
|
|
|
mark_window($leader->id);
|
|
|
|
|
|
2011-11-21 18:47:32 -05:00
|
|
|
|
$win = open_window({ dont_map => 1, client_leader => $leader });
|
2011-10-10 11:00:34 -04:00
|
|
|
|
$win->map;
|
2011-11-21 19:13:37 -05:00
|
|
|
|
sync_with_i3;
|
2011-10-10 08:30:52 -04:00
|
|
|
|
|
2012-09-04 16:24:13 -04:00
|
|
|
|
is_num_children($second_ws, 0, 'still no containers on the second workspace');
|
|
|
|
|
is_num_children($first_ws, 2, 'two containers on the first workspace');
|
2011-10-09 19:24:29 -04:00
|
|
|
|
|
|
|
|
|
######################################################################
|
2012-10-03 21:06:04 -04:00
|
|
|
|
# verifies that finishing startup doesn't immediately stop windows
|
|
|
|
|
# from being placed on the sequence's workspace, but that moving
|
|
|
|
|
# the leader actually deletes the startup sequence mapping
|
2011-10-09 19:24:29 -04:00
|
|
|
|
######################################################################
|
|
|
|
|
|
|
|
|
|
complete_startup();
|
2011-11-21 19:13:37 -05:00
|
|
|
|
sync_with_i3;
|
2011-10-09 19:24:29 -04:00
|
|
|
|
|
2012-10-03 21:06:04 -04:00
|
|
|
|
# Startup has completed but the 30-second deletion time hasn't elapsed,
|
|
|
|
|
# so this window should still go on the leader's initial workspace.
|
|
|
|
|
$win = open_window({ dont_map => 1, client_leader => $leader });
|
|
|
|
|
$win->map;
|
|
|
|
|
sync_with_i3;
|
|
|
|
|
|
|
|
|
|
is_num_children($first_ws, 3, 'three containers on the first workspace');
|
|
|
|
|
|
|
|
|
|
# Switch to the first workspace and move the focused window to the
|
|
|
|
|
# second workspace.
|
|
|
|
|
cmd "workspace $first_ws";
|
|
|
|
|
cmd "move workspace $second_ws";
|
|
|
|
|
|
2012-09-04 16:24:13 -04:00
|
|
|
|
is_num_children($second_ws, 1, 'one container on the second workspace');
|
2011-10-09 19:24:29 -04:00
|
|
|
|
|
2012-10-03 21:06:04 -04:00
|
|
|
|
# Create and switch to a new workspace, just to be safe.
|
|
|
|
|
my $third_ws = fresh_workspace;
|
|
|
|
|
|
|
|
|
|
# Moving the window between workspaces should have immediately
|
|
|
|
|
# removed the startup workspace mapping. New windows with that
|
|
|
|
|
# leader should be created on the current workspace.
|
|
|
|
|
$win = open_window({ dont_map => 1, client_leader => $leader });
|
|
|
|
|
$win->map;
|
|
|
|
|
sync_with_i3;
|
|
|
|
|
|
|
|
|
|
is_num_children($third_ws, 1, 'one container on the third workspace');
|
|
|
|
|
|
|
|
|
|
######################################################################
|
|
|
|
|
# 2) open another window after the startup process is completed
|
|
|
|
|
# (should be placed on the current workspace)
|
|
|
|
|
######################################################################
|
|
|
|
|
|
|
|
|
|
my $otherwin = open_window;
|
|
|
|
|
is_num_children($third_ws, 2, 'two containers on the third workspace');
|
|
|
|
|
|
2011-10-25 17:21:37 -04:00
|
|
|
|
######################################################################
|
|
|
|
|
# 3) test that the --no-startup-id flag for exec leads to no DESKTOP_STARTUP_ID
|
|
|
|
|
# environment variable.
|
|
|
|
|
######################################################################
|
|
|
|
|
|
2014-03-18 23:07:01 -04:00
|
|
|
|
mkfifo($tmp, 0600) or BAIL_OUT "Could not create FIFO in $tmp";
|
2011-10-25 17:21:37 -04:00
|
|
|
|
|
|
|
|
|
cmd qq|exec --no-startup-id echo \$DESKTOP_STARTUP_ID >$tmp|;
|
|
|
|
|
|
|
|
|
|
open($fh, '<', $tmp);
|
|
|
|
|
chomp($startup_id = <$fh>);
|
|
|
|
|
close($fh);
|
|
|
|
|
|
|
|
|
|
unlink($tmp);
|
|
|
|
|
|
|
|
|
|
is($startup_id, '', 'startup_id empty');
|
|
|
|
|
|
2011-11-10 19:28:04 -05:00
|
|
|
|
######################################################################
|
|
|
|
|
# 4) same thing, but with double quotes in exec
|
|
|
|
|
######################################################################
|
|
|
|
|
|
2014-03-18 23:07:01 -04:00
|
|
|
|
mkfifo($tmp, 0600) or BAIL_OUT "Could not create FIFO in $tmp";
|
2011-11-10 19:28:04 -05:00
|
|
|
|
|
|
|
|
|
cmd qq|exec --no-startup-id "echo \$DESKTOP_STARTUP_ID >$tmp"|;
|
|
|
|
|
|
|
|
|
|
open($fh, '<', $tmp);
|
|
|
|
|
chomp($startup_id = <$fh>);
|
|
|
|
|
close($fh);
|
|
|
|
|
|
|
|
|
|
unlink($tmp);
|
|
|
|
|
|
|
|
|
|
is($startup_id, '', 'startup_id empty');
|
2012-12-27 12:02:23 -05:00
|
|
|
|
}
|
2011-11-10 19:28:04 -05:00
|
|
|
|
|
2011-10-09 19:24:29 -04:00
|
|
|
|
done_testing;
|