i3 - improved tiling WM


Handle _NET_CLOSE_WINDOW client message requests

Patch status: merged

Patch by Tony Crisci

Long description:

> Pagers wanting to close a window MUST send a _NET_CLOSE_WINDOW client
> message request to the root window.

We interpret this message as a request to close the con for the given
window.

See: http://standards.freedesktop.org/wm-spec/wm-spec-latest.html#idm140200472668896

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

b/include/atoms.xmacro

24
@@ -20,6 +20,7 @@ xmacro(_NET_NUMBER_OF_DESKTOPS)
25
 xmacro(_NET_DESKTOP_NAMES)
26
 xmacro(_NET_DESKTOP_VIEWPORT)
27
 xmacro(_NET_ACTIVE_WINDOW)
28
+xmacro(_NET_CLOSE_WINDOW)
29
 xmacro(_NET_STARTUP_ID)
30
 xmacro(_NET_WORKAREA)
31
 xmacro(WM_PROTOCOLS)

b/src/ewmh.c

36
@@ -234,5 +234,5 @@ void ewmh_setup_hints(void) {
37
     /* I’m not entirely sure if we need to keep _NET_WM_NAME on root. */
38
     xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A__NET_WM_NAME, A_UTF8_STRING, 8, strlen("i3"), "i3");
39
 
40
-    xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A__NET_SUPPORTED, XCB_ATOM_ATOM, 32, 22, supported_atoms);
41
+    xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A__NET_SUPPORTED, XCB_ATOM_ATOM, 32, 23, supported_atoms);
42
 }

b/src/handlers.c

47
@@ -838,6 +838,24 @@ static void handle_client_message(xcb_client_message_event_t *event) {
48
                 ++idx;
49
             }
50
         }
51
+    } else if (event->type == A__NET_CLOSE_WINDOW) {
52
+        /*
53
+         * Pagers wanting to close a window MUST send a _NET_CLOSE_WINDOW
54
+         * client message request to the root window.
55
+         * http://standards.freedesktop.org/wm-spec/wm-spec-latest.html#idm140200472668896
56
+         */
57
+        Con *con = con_by_window_id(event->window);
58
+        if (con) {
59
+            DLOG("Handling _NET_CLOSE_WINDOW request (con = %p)\n", con);
60
+
61
+            if (event->data.data32[0])
62
+                last_timestamp = event->data.data32[0];
63
+
64
+            tree_close(con, KILL_WINDOW, false, false);
65
+            tree_render();
66
+        } else {
67
+            DLOG("Couldn't find con for _NET_CLOSE_WINDOW request. (window = %d)\n", event->window);
68
+        }
69
     } else {
70
         DLOG("unhandled clientmessage\n");
71
         return;

b/testcases/t/239-net-close-window-request.t

77
@@ -0,0 +1,49 @@
78
+#!perl
79
+# vim:ts=4:sw=4:expandtab
80
+#
81
+# Please read the following documents before working on tests:
82
+# • http://build.i3wm.org/docs/testsuite.html
83
+#   (or docs/testsuite)
84
+#
85
+# • http://build.i3wm.org/docs/lib-i3test.html
86
+#   (alternatively: perldoc ./testcases/lib/i3test.pm)
87
+#
88
+# • http://build.i3wm.org/docs/ipc.html
89
+#   (or docs/ipc)
90
+#
91
+# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
92
+#   (unless you are already familiar with Perl)
93
+#
94
+# Test _NET_CLOSE_WINDOW requests to close a window.
95
+# See http://standards.freedesktop.org/wm-spec/wm-spec-latest.html#idm140200472668896
96
+# Ticket: #1396
97
+# Bug still in: 4.8-116-gbb1f857
98
+use i3test;
99
+
100
+sub send_close_window_request {
101
+    my ($win) = @_;
102
+
103
+    my $msg = pack "CCSLLLLLL",
104
+        X11::XCB::CLIENT_MESSAGE, # response_type
105
+        32, # format
106
+        0, # sequence
107
+        $win->id, # window
108
+        $x->atom(name => '_NET_CLOSE_WINDOW')->id, # message type
109
+        0, # data32[0]
110
+        0, # data32[1]
111
+        0, # data32[2]
112
+        0, # data32[3]
113
+        0; # data32[4]
114
+
115
+    $x->send_event(0, $x->get_root_window(), X11::XCB::EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);
116
+}
117
+
118
+my $ws = fresh_workspace;
119
+my $win = open_window;
120
+
121
+send_close_window_request($win);
122
+sync_with_i3;
123
+
124
+is(@{get_ws($ws)->{nodes}}, 0, 'When a pager sends a _NET_CLOSE_WINDOW request for a window, the container should be closed');
125
+
126
+done_testing;