i3 - improved tiling WM


event for window focus changes

Patch status: rejected

Patch by andaagar

To apply this patch, use:
curl http://cr.i3wm.org/patch/559/raw.patch | git am

b/include/i3/ipc.h

16
@@ -100,3 +100,6 @@ typedef struct i3_ipc_header {
17
 
18
 /** Bar config update will be triggered to update the bar config */
19
 #define I3_IPC_EVENT_BARCONFIG_UPDATE           (I3_IPC_EVENT_MASK | 4)
20
+
21
+/** Window focus events will be triggered upon window focus requests */
22
+#define I3_IPC_EVENT_FOCUS           			(I3_IPC_EVENT_MASK | 5)

b/src/handlers.c

27
@@ -20,6 +20,10 @@
28
 #define SN_API_NOT_YET_FROZEN 1
29
 #include <libsn/sn-monitor.h>
30
 
31
+ #include "yajl_utils.h"
32
+
33
+#include <yajl/yajl_gen.h>
34
+
35
 int randr_base = -1;
36
 
37
 /* After mapping/unmapping windows, a notify event is generated. However, we don’t want it,
38
@@ -647,6 +651,32 @@ static void handle_expose_event(xcb_expose_event_t *event) {
39
 }
40
 
41
 /*
42
+ * Send focus events
43
+ */
44
+ static void ipc_send_window_focus_event(Con *con, char *change) {
45
+    setlocale(LC_NUMERIC, "C");
46
+    yajl_gen gen = ygenalloc();
47
+
48
+    y(map_open);
49
+
50
+    ystr("change");
51
+    ystr(change);
52
+
53
+    ystr("container");
54
+    dump_node(gen, con, false);
55
+
56
+    y(map_close);
57
+
58
+    const unsigned char *payload;
59
+    ylength length;
60
+    y(get_buf, &payload, &length);
61
+
62
+    ipc_send_event("focus", I3_IPC_EVENT_FOCUS, (const char *)payload);
63
+    y(free);
64
+    setlocale(LC_NUMERIC, "");
65
+}
66
+
67
+/*
68
  * Handle client messages (EWMH)
69
  *
70
  */
71
@@ -731,9 +761,11 @@ static void handle_client_message(xcb_client_message_event_t *event) {
72
                 DLOG("Request to focus con on a visible workspace. Focusing con = %p\n", con);
73
                 workspace_show(ws);
74
                 con_focus(con);
75
+                ipc_send_window_focus_event(con, "focused");
76
             } else {
77
                 DLOG("Request to focus con on a hidden workspace. Setting urgent con = %p\n", con);
78
                 con_set_urgency(con, true);
79
+                ipc_send_window_focus_event(con, "blocked");
80
             }
81
         }
82
 

b/testcases/t/519-ipc-focus.t

88
@@ -0,0 +1,49 @@
89
+#!perl
90
+# vim:ts=4:sw=4:expandtab
91
+#
92
+# Please read the following documents before working on tests:
93
+# • http://build.i3wm.org/docs/testsuite.html
94
+#   (or docs/testsuite)
95
+#
96
+# • http://build.i3wm.org/docs/lib-i3test.html
97
+#   (alternatively: perldoc ./testcases/lib/i3test.pm)
98
+#
99
+# • http://build.i3wm.org/docs/ipc.html
100
+#   (or docs/ipc)
101
+#
102
+# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
103
+#   (unless you are already familiar with Perl)
104
+
105
+use i3test;
106
+
107
+SKIP: {
108
+
109
+    skip "AnyEvent::I3 too old (need >= 0.15)", 1 if $AnyEvent::I3::VERSION < 0.15;
110
+
111
+my $i3 = i3(get_socket_path());
112
+$i3->connect()->recv;
113
+
114
+################################
115
+# Window event
116
+################################
117
+
118
+# Events
119
+
120
+my $new = AnyEvent->condvar;
121
+$i3->subscribe({
122
+    focus => sub {
123
+        my ($event) = @_;
124
+        $new->send($event->{change} eq 'focused');
125
+    }
126
+})->recv;
127
+
128
+open_window;
129
+
130
+my $t;
131
+$t = AnyEvent->timer(after => 0.5, cb => sub { $new->send(0); });
132
+
133
+ok($new->recv, 'Window "focused" event received');
134
+
135
+}
136
+
137
+done_testing;