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 |
} |