]> git.sur5r.net Git - i3/i3/blob - testcases/t/175-startup-notification.t
add testcase for the startup notification protocol
[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
32 // TODO: this should use $x
33 void init_ctx() {
34     int screen;
35     xcb_connection_t *conn;
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 }
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 $ENV{DESKTOP_STARTUP_ID} = $startup_id;
87
88 # Create a new libstartup-notification launchee context
89 init_ctx();
90
91 # Make sure the context was set up successfully
92 is(get_startup_id(), $startup_id, 'libstartup-notification returns the same id');
93
94 my $second_ws = fresh_workspace;
95
96 is(@{get_ws_content($second_ws)}, 0, 'no containers on the second workspace yet');
97
98 my $win = open_window($x);
99 mark_window($win->id);
100
101 is(@{get_ws_content($second_ws)}, 0, 'still no containers on the second workspace');
102 is(@{get_ws_content($first_ws)}, 1, 'one container on the first workspace');
103
104 # TODO: the same thing, but in a CLIENT_LEADER situation
105
106 ######################################################################
107 # 2) open another window after the startup process is completed
108 # (should be placed on the current workspace)
109 ######################################################################
110
111 complete_startup();
112 sync_with_i3($x);
113
114 my $otherwin = open_window($x);
115 is(@{get_ws_content($second_ws)}, 1, 'one container on the second workspace');
116
117 done_testing;