]> git.sur5r.net Git - i3/i3/blob - testcases/t/175-startup-notification.t
Merge branch 'release-4.1.2'
[i3/i3] / testcases / t / 175-startup-notification.t
1 #!perl
2 # vim:ts=4:sw=4:expandtab
3 #
4 # Test for the startup notification protocol.
5 #
6
7 use i3test;
8 use POSIX qw(mkfifo);
9 use File::Temp qw(:POSIX);
10
11 my $x = X11::XCB::Connection->new;
12 use ExtUtils::PkgConfig;
13
14 # setup dependency on libstartup-notification using pkg-config
15 my %sn_config;
16 BEGIN {
17     %sn_config = ExtUtils::PkgConfig->find('libstartup-notification-1.0');
18 }
19
20 use Inline C => Config => LIBS => $sn_config{libs}, CCFLAGS => $sn_config{cflags};
21 use Inline C => <<'END_OF_C_CODE';
22
23 #include <xcb/xcb.h>
24
25 #define SN_API_NOT_YET_FROZEN 1
26 #include <libsn/sn-common.h>
27 #include <libsn/sn-launchee.h>
28
29 static SnDisplay *sndisplay;
30 static SnLauncheeContext *ctx;
31 static xcb_connection_t *conn;
32
33 // TODO: this should use $x
34 void init_ctx() {
35     int screen;
36     if ((conn = xcb_connect(NULL, &screen)) == NULL ||
37         xcb_connection_has_error(conn))
38         errx(1, "x11 conn failed");
39
40     printf("screen = %d\n", screen);
41     sndisplay = sn_xcb_display_new(conn, NULL, NULL);
42     ctx = sn_launchee_context_new_from_environment(sndisplay, screen);
43 }
44
45 const char *get_startup_id() {
46     return sn_launchee_context_get_startup_id(ctx);
47 }
48
49 void mark_window(int window) {
50     sn_launchee_context_setup_window(ctx, (Window)window);
51     xcb_flush(conn);
52 }
53
54 void complete_startup() {
55     /* mark the startup process complete */
56     sn_launchee_context_complete(ctx);
57 }
58 END_OF_C_CODE
59
60 my $first_ws = fresh_workspace;
61
62 is(@{get_ws_content($first_ws)}, 0, 'no containers on this workspace yet');
63
64 ######################################################################
65 # 1) initiate startup, switch workspace, create window
66 # (should be placed on the original workspace)
67 ######################################################################
68
69 # Start a new process via i3 (to initialize a new startup notification
70 # context), then steal its DESKTOP_STARTUP_ID variable. We handle the startup
71 # notification in the testcase from there on.
72 #
73 # This works by setting up a FIFO in which the process (started by i3) will
74 # echo its $DESKTOP_STARTUP_ID. We (blockingly) read the variable into
75 # $startup_id in the testcase.
76 my $tmp = tmpnam();
77 mkfifo($tmp, 0600) or die "Could not create FIFO in $tmp";
78
79 cmd qq|exec echo \$DESKTOP_STARTUP_ID >$tmp|;
80
81 open(my $fh, '<', $tmp);
82 chomp(my $startup_id = <$fh>);
83 close($fh);
84
85 unlink($tmp);
86
87 isnt($startup_id, '', 'startup_id not empty');
88
89 $ENV{DESKTOP_STARTUP_ID} = $startup_id;
90
91 # Create a new libstartup-notification launchee context
92 init_ctx();
93
94 # Make sure the context was set up successfully
95 is(get_startup_id(), $startup_id, 'libstartup-notification returns the same id');
96
97 my $second_ws = fresh_workspace;
98
99 is(@{get_ws_content($second_ws)}, 0, 'no containers on the second workspace yet');
100
101 my $win = open_window($x, { dont_map => 1 });
102 mark_window($win->id);
103 $win->map;
104 # We don’t use wait_for_map because the window will not get mapped -- it is on
105 # a different workspace.
106 # We sync with i3 here to make sure $x->input_focus is updated.
107 sync_with_i3($x);
108
109 is(@{get_ws_content($second_ws)}, 0, 'still no containers on the second workspace');
110 is(@{get_ws_content($first_ws)}, 1, 'one container on the first workspace');
111
112 ######################################################################
113 # same thing, but with _NET_STARTUP_ID set on the leader
114 ######################################################################
115
116 my $leader = open_window($x, { dont_map => 1 });
117 mark_window($leader->id);
118
119 $win = open_window($x, { dont_map => 1, client_leader => $leader });
120 $win->map;
121 sync_with_i3($x);
122
123 is(@{get_ws_content($second_ws)}, 0, 'still no containers on the second workspace');
124 is(@{get_ws_content($first_ws)}, 2, 'two containers on the first workspace');
125
126 ######################################################################
127 # 2) open another window after the startup process is completed
128 # (should be placed on the current workspace)
129 ######################################################################
130
131 complete_startup();
132 sync_with_i3($x);
133
134 my $otherwin = open_window($x);
135 is(@{get_ws_content($second_ws)}, 1, 'one container on the second workspace');
136
137 ######################################################################
138 # 3) test that the --no-startup-id flag for exec leads to no DESKTOP_STARTUP_ID
139 # environment variable.
140 ######################################################################
141
142 mkfifo($tmp, 0600) or die "Could not create FIFO in $tmp";
143
144 cmd qq|exec --no-startup-id echo \$DESKTOP_STARTUP_ID >$tmp|;
145
146 open($fh, '<', $tmp);
147 chomp($startup_id = <$fh>);
148 close($fh);
149
150 unlink($tmp);
151
152 is($startup_id, '', 'startup_id empty');
153
154 ######################################################################
155 # 4) same thing, but with double quotes in exec
156 ######################################################################
157
158 mkfifo($tmp, 0600) or die "Could not create FIFO in $tmp";
159
160 cmd qq|exec --no-startup-id "echo \$DESKTOP_STARTUP_ID >$tmp"|;
161
162 open($fh, '<', $tmp);
163 chomp($startup_id = <$fh>);
164 close($fh);
165
166 unlink($tmp);
167
168 is($startup_id, '', 'startup_id empty');
169
170
171 done_testing;