2 # vim:ts=4:sw=4:expandtab
4 # Please read the following documents before working on tests:
5 # • http://build.i3wm.org/docs/testsuite.html
8 # • http://build.i3wm.org/docs/lib-i3test.html
9 # (alternatively: perldoc ./testcases/lib/i3test.pm)
11 # • http://build.i3wm.org/docs/ipc.html
14 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
15 # (unless you are already familiar with Perl)
17 # Test for the startup notification protocol.
22 use File::Temp qw(:POSIX);
26 skip "X11::XCB too old (need >= 0.07)", 24 if $X11::XCB::VERSION < 0.07;
28 use ExtUtils::PkgConfig;
30 # setup dependency on libstartup-notification using pkg-config
33 %sn_config = ExtUtils::PkgConfig->find('libstartup-notification-1.0');
36 use Inline C => Config => LIBS => $sn_config{libs}, CCFLAGS => $sn_config{cflags};
37 use Inline C => <<'END_OF_C_CODE';
41 #define SN_API_NOT_YET_FROZEN 1
42 #include <libsn/sn-common.h>
43 #include <libsn/sn-launchee.h>
45 static SnDisplay *sndisplay;
46 static SnLauncheeContext *ctx;
47 static xcb_connection_t *conn;
49 void init_ctx(void *connptr) {
50 conn = (xcb_connection_t*)connptr;
51 sndisplay = sn_xcb_display_new(conn, NULL, NULL);
52 ctx = sn_launchee_context_new_from_environment(sndisplay, 0);
55 const char *get_startup_id() {
56 return sn_launchee_context_get_startup_id(ctx);
59 void mark_window(int window) {
60 sn_launchee_context_setup_window(ctx, (Window)window);
64 void complete_startup() {
65 /* mark the startup process complete */
66 sn_launchee_context_complete(ctx);
70 my $first_ws = fresh_workspace;
72 is_num_children($first_ws, 0, 'no containers on this workspace yet');
74 ######################################################################
75 # 1) initiate startup, switch workspace, create window
76 # (should be placed on the original workspace)
77 ######################################################################
79 # Start a new process via i3 (to initialize a new startup notification
80 # context), then steal its DESKTOP_STARTUP_ID variable. We handle the startup
81 # notification in the testcase from there on.
83 # This works by setting up a FIFO in which the process (started by i3) will
84 # echo its $DESKTOP_STARTUP_ID. We (blockingly) read the variable into
85 # $startup_id in the testcase.
87 mkfifo($tmp, 0600) or die "Could not create FIFO in $tmp";
89 cmd qq|exec echo \$DESKTOP_STARTUP_ID >$tmp|;
91 open(my $fh, '<', $tmp);
92 chomp(my $startup_id = <$fh>);
97 isnt($startup_id, '', 'startup_id not empty');
99 $ENV{DESKTOP_STARTUP_ID} = $startup_id;
101 # Create a new libstartup-notification launchee context
102 init_ctx($x->get_xcb_conn());
104 # Make sure the context was set up successfully
105 is(get_startup_id(), $startup_id, 'libstartup-notification returns the same id');
107 my $second_ws = fresh_workspace;
109 is_num_children($second_ws, 0, 'no containers on the second workspace yet');
111 my $win = open_window({ dont_map => 1 });
112 mark_window($win->id);
114 # We don’t use wait_for_map because the window will not get mapped -- it is on
115 # a different workspace.
116 # We sync with i3 here to make sure $x->input_focus is updated.
119 is_num_children($second_ws, 0, 'still no containers on the second workspace');
120 is_num_children($first_ws, 1, 'one container on the first workspace');
122 ######################################################################
123 # same thing, but with _NET_STARTUP_ID set on the leader
124 ######################################################################
126 my $leader = open_window({ dont_map => 1 });
127 mark_window($leader->id);
129 $win = open_window({ dont_map => 1, client_leader => $leader });
133 is_num_children($second_ws, 0, 'still no containers on the second workspace');
134 is_num_children($first_ws, 2, 'two containers on the first workspace');
136 ######################################################################
137 # verifies that finishing startup doesn't immediately stop windows
138 # from being placed on the sequence's workspace, but that moving
139 # the leader actually deletes the startup sequence mapping
140 ######################################################################
145 # Startup has completed but the 30-second deletion time hasn't elapsed,
146 # so this window should still go on the leader's initial workspace.
147 $win = open_window({ dont_map => 1, client_leader => $leader });
151 is_num_children($first_ws, 3, 'three containers on the first workspace');
153 # Switch to the first workspace and move the focused window to the
155 cmd "workspace $first_ws";
156 cmd "move workspace $second_ws";
158 is_num_children($second_ws, 1, 'one container on the second workspace');
160 # Create and switch to a new workspace, just to be safe.
161 my $third_ws = fresh_workspace;
163 # Moving the window between workspaces should have immediately
164 # removed the startup workspace mapping. New windows with that
165 # leader should be created on the current workspace.
166 $win = open_window({ dont_map => 1, client_leader => $leader });
170 is_num_children($third_ws, 1, 'one container on the third workspace');
172 ######################################################################
173 # 2) open another window after the startup process is completed
174 # (should be placed on the current workspace)
175 ######################################################################
177 my $otherwin = open_window;
178 is_num_children($third_ws, 2, 'two containers on the third workspace');
180 ######################################################################
181 # 3) test that the --no-startup-id flag for exec leads to no DESKTOP_STARTUP_ID
182 # environment variable.
183 ######################################################################
185 mkfifo($tmp, 0600) or die "Could not create FIFO in $tmp";
187 cmd qq|exec --no-startup-id echo \$DESKTOP_STARTUP_ID >$tmp|;
189 open($fh, '<', $tmp);
190 chomp($startup_id = <$fh>);
195 is($startup_id, '', 'startup_id empty');
197 ######################################################################
198 # 4) same thing, but with double quotes in exec
199 ######################################################################
201 mkfifo($tmp, 0600) or die "Could not create FIFO in $tmp";
203 cmd qq|exec --no-startup-id "echo \$DESKTOP_STARTUP_ID >$tmp"|;
205 open($fh, '<', $tmp);
206 chomp($startup_id = <$fh>);
211 is($startup_id, '', 'startup_id empty');