i3 - improved tiling WM


Implement EWMH desktop names

Patch status: merged

Patch by Tony Crisci

Long description:

Maintain the _NET_DESKTOP_NAMES property on the root window.

http://standards.freedesktop.org/wm-spec/latest/ar01s03.html#idm140251368131760

> _NET_DESKTOP_NAMES
>
> _NET_DESKTOP_NAMES, UTF8_STRING[]
>
> The names of all virtual desktops. This is a list of NULL-terminated
> strings in UTF-8 encoding [UTF8]. This property MAY be changed by a
> Pager or the Window Manager at any time.

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

b/include/atoms.xmacro

29
@@ -17,6 +17,7 @@ xmacro(_NET_CLIENT_LIST)
30
 xmacro(_NET_CLIENT_LIST_STACKING)
31
 xmacro(_NET_CURRENT_DESKTOP)
32
 xmacro(_NET_NUMBER_OF_DESKTOPS)
33
+xmacro(_NET_DESKTOP_NAMES)
34
 xmacro(_NET_DESKTOP_VIEWPORT)
35
 xmacro(_NET_ACTIVE_WINDOW)
36
 xmacro(_NET_STARTUP_ID)

b/include/ewmh.h

41
@@ -24,6 +24,12 @@ void ewmh_update_current_desktop(void);
42
  */
43
 void ewmh_update_number_of_desktops(void);
44
 
45
+ /**
46
+ * Updates _NET_DESKTOP_NAMES: "The names of all virtual desktops. This is a
47
+ * list of NULL-terminated strings in UTF-8 encoding"
48
+ */
49
+void ewmh_update_desktop_names(void);
50
+
51
 /**
52
  * Updates _NET_DESKTOP_VIEWPORT, which is an array of pairs of cardinals that
53
  * define the top left corner of each desktop's viewport.

b/src/commands.c

58
@@ -1987,6 +1987,9 @@ void cmd_rename_workspace(I3_CMD, char *old_name, char *new_name) {
59
     ysuccess(true);
60
 
61
     ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, "{\"change\":\"rename\"}");
62
+    ewmh_update_desktop_names();
63
+    ewmh_update_desktop_viewport();
64
+    ewmh_update_current_desktop();
65
 }
66
 
67
 /*

b/src/ewmh.c

72
@@ -61,6 +61,45 @@ void ewmh_update_number_of_desktops(void) {
73
                         A__NET_NUMBER_OF_DESKTOPS, XCB_ATOM_CARDINAL, 32, 1, &idx);
74
 }
75
 
76
+ /*
77
+ * Updates _NET_DESKTOP_NAMES: "The names of all virtual desktops. This is a
78
+ * list of NULL-terminated strings in UTF-8 encoding"
79
+ */
80
+void ewmh_update_desktop_names(void) {
81
+    Con *output;
82
+    int msg_length = 0;
83
+
84
+    /* count the size of the property message to set */
85
+    TAILQ_FOREACH(output, &(croot->nodes_head), nodes) {
86
+        Con *ws;
87
+        TAILQ_FOREACH(ws, &(output_get_content(output)->nodes_head), nodes) {
88
+            if (STARTS_WITH(ws->name, "__"))
89
+                continue;
90
+            msg_length += strlen(ws->name) + 1;
91
+        }
92
+    }
93
+
94
+    char desktop_names[msg_length];
95
+    int current_position = 0;
96
+
97
+    /* fill the buffer with the names of the i3 workspaces */
98
+    TAILQ_FOREACH(output, &(croot->nodes_head), nodes) {
99
+        Con *ws;
100
+        TAILQ_FOREACH(ws, &(output_get_content(output)->nodes_head), nodes) {
101
+            if (STARTS_WITH(ws->name, "__"))
102
+                continue;
103
+
104
+            for (size_t i = 0; i < strlen(ws->name) + 1; i++) {
105
+                desktop_names[current_position] = ws->name[i];
106
+                current_position++;
107
+            }
108
+        }
109
+    }
110
+
111
+    xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root,
112
+            A__NET_DESKTOP_NAMES, A_UTF8_STRING, 8, msg_length, desktop_names);
113
+}
114
+
115
 /*
116
  * Updates _NET_DESKTOP_VIEWPORT, which is an array of pairs of cardinals that
117
  * define the top left corner of each desktop's viewport.
118
@@ -196,5 +235,5 @@ void ewmh_setup_hints(void) {
119
     /* I’m not entirely sure if we need to keep _NET_WM_NAME on root. */
120
     xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A__NET_WM_NAME, A_UTF8_STRING, 8, strlen("i3"), "i3");
121
 
122
-    xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A__NET_SUPPORTED, XCB_ATOM_ATOM, 32, 20, supported_atoms);
123
+    xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A__NET_SUPPORTED, XCB_ATOM_ATOM, 32, 21, supported_atoms);
124
 }

b/src/main.c

129
@@ -674,6 +674,7 @@ int main(int argc, char *argv[]) {
130
     /* Set the ewmh desktop properties. */
131
     ewmh_update_current_desktop();
132
     ewmh_update_number_of_desktops();
133
+    ewmh_update_desktop_names();
134
     ewmh_update_desktop_viewport();
135
 
136
     struct ev_io *xcb_watcher = scalloc(sizeof(struct ev_io));

b/src/workspace.c

141
@@ -93,6 +93,7 @@ Con *workspace_get(const char *num, bool *created) {
142
 
143
         ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, "{\"change\":\"init\"}");
144
         ewmh_update_number_of_desktops();
145
+        ewmh_update_desktop_names();
146
         ewmh_update_desktop_viewport();
147
         if (created != NULL)
148
             *created = true;
149
@@ -419,6 +420,7 @@ static void _workspace_show(Con *workspace) {
150
             tree_close(old, DONT_KILL_WINDOW, false, false);
151
             ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, "{\"change\":\"empty\"}");
152
             ewmh_update_number_of_desktops();
153
+            ewmh_update_desktop_names();
154
             ewmh_update_desktop_viewport();
155
         }
156
     }