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