i3 - improved tiling WM


i3bar: Handle DestroyNotify events

Patch status: merged

Patch by Tony Crisci

Long description:

Handle DestroyNotify events by removing the tray client from the tray
client list held in memory.

This change is intended to be part of the i3bar's implementation of the
XEmbed protocol. For more information, see:

<http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html>

According to the XEmbed protocol specification, this is one way for a
tray client to finish the protocol. After this event is received, i3bar
should have no more interaction with the tray client.

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

b/i3bar/src/xcb.c

24
@@ -623,6 +623,39 @@ static void handle_client_message(xcb_client_message_event_t* event) {
25
 }
26
 
27
 /*
28
+ * Handles DestroyNotify events by removing the tray client from the data
29
+ * structure. According to the XEmbed protocol, this is one way for a tray
30
+ * client to finish the protocol. After this event is received, there is no
31
+ * further interaction with the tray client.
32
+ *
33
+ * See: http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html
34
+ *
35
+ */
36
+static void handle_destroy_notify(xcb_destroy_notify_event_t* event) {
37
+    DLOG("DestroyNotify for window = %08x, event = %08x\n", event->window, event->event);
38
+
39
+    i3_output *walk;
40
+    SLIST_FOREACH(walk, outputs, slist) {
41
+        if (!walk->active)
42
+            continue;
43
+        DLOG("checking output %s\n", walk->name);
44
+        trayclient *trayclient;
45
+        TAILQ_FOREACH(trayclient, walk->trayclients, tailq) {
46
+            if (trayclient->win != event->window)
47
+                continue;
48
+
49
+            DLOG("Removing tray client with window ID %08x\n", event->window);
50
+            TAILQ_REMOVE(walk->trayclients, trayclient, tailq);
51
+
52
+            /* Trigger an update, we now have more space for the statusline */
53
+            configure_trayclients();
54
+            draw_bars(false);
55
+            return;
56
+        }
57
+    }
58
+}
59
+
60
+/*
61
  * Handles UnmapNotify events. These events happen when a tray window unmaps
62
  * itself. We then update our data structure
63
  *
64
@@ -798,8 +831,11 @@ void xcb_chk_cb(struct ev_loop *loop, ev_check *watcher, int revents) {
65
                  * example system tray widgets talk to us directly via client messages. */
66
                 handle_client_message((xcb_client_message_event_t*) event);
67
                 break;
68
-            case XCB_UNMAP_NOTIFY:
69
             case XCB_DESTROY_NOTIFY:
70
+                /* DestroyNotify signifies the end of the XEmbed protocol */
71
+                handle_destroy_notify((xcb_destroy_notify_event_t*) event);
72
+                break;
73
+            case XCB_UNMAP_NOTIFY:
74
                 /* UnmapNotifies are received when a tray window unmaps itself */
75
                 handle_unmap_notify((xcb_unmap_notify_event_t*) event);
76
                 break;