Implement EWMH desktop names
Patch status: needinfo
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/595/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_ACTIVE_WINDOW) |
| 35 |
xmacro(_NET_STARTUP_ID) |
| 36 |
xmacro(_NET_WORKAREA) |
b/include/ewmh.h
| 41 |
@@ -25,6 +25,12 @@ void ewmh_update_current_desktop(void); |
| 42 |
void ewmh_update_number_of_desktops(void); |
| 43 |
|
| 44 |
/** |
| 45 |
+ * Updates _NET_DESKTOP_NAMES: "The names of all virtual desktops. This is a |
| 46 |
+ * list of NULL-terminated strings in UTF-8 encoding" |
| 47 |
+ */ |
| 48 |
+void ewmh_update_desktop_names(void); |
| 49 |
+ |
| 50 |
+/** |
| 51 |
* Updates _NET_ACTIVE_WINDOW with the currently focused window. |
| 52 |
* |
| 53 |
* EWMH: The window ID of the currently active window or None if no window has |
b/src/commands.c
| 58 |
@@ -1948,6 +1948,8 @@ 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_current_desktop(); |
| 64 |
} |
| 65 |
|
| 66 |
/* |
b/src/ewmh.c
| 71 |
@@ -62,6 +62,45 @@ void ewmh_update_number_of_desktops(void) {
|
| 72 |
} |
| 73 |
|
| 74 |
/* |
| 75 |
+ * Updates _NET_DESKTOP_NAMES: "The names of all virtual desktops. This is a |
| 76 |
+ * list of NULL-terminated strings in UTF-8 encoding" |
| 77 |
+ */ |
| 78 |
+void ewmh_update_desktop_names(void) {
|
| 79 |
+ Con *output; |
| 80 |
+ int msg_length = 0; |
| 81 |
+ |
| 82 |
+ /* count the size of the property message to set */ |
| 83 |
+ TAILQ_FOREACH(output, &(croot->nodes_head), nodes) {
|
| 84 |
+ Con *ws; |
| 85 |
+ TAILQ_FOREACH(ws, &(output_get_content(output)->nodes_head), nodes) {
|
| 86 |
+ if (STARTS_WITH(ws->name, "__")) |
| 87 |
+ continue; |
| 88 |
+ msg_length += strlen(ws->name) + 1; |
| 89 |
+ } |
| 90 |
+ } |
| 91 |
+ |
| 92 |
+ char desktop_names[msg_length]; |
| 93 |
+ int current_position = 0; |
| 94 |
+ |
| 95 |
+ /* fill the buffer with the names of the i3 workspaces */ |
| 96 |
+ TAILQ_FOREACH(output, &(croot->nodes_head), nodes) {
|
| 97 |
+ Con *ws; |
| 98 |
+ TAILQ_FOREACH(ws, &(output_get_content(output)->nodes_head), nodes) {
|
| 99 |
+ if (STARTS_WITH(ws->name, "__")) |
| 100 |
+ continue; |
| 101 |
+ |
| 102 |
+ for (int i = 0; i < strlen(ws->name) + 1; i++) {
|
| 103 |
+ desktop_names[current_position] = ws->name[i]; |
| 104 |
+ current_position += 1; |
| 105 |
+ } |
| 106 |
+ } |
| 107 |
+ } |
| 108 |
+ |
| 109 |
+ xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, |
| 110 |
+ A__NET_DESKTOP_NAMES, A_UTF8_STRING, 8, msg_length, desktop_names); |
| 111 |
+} |
| 112 |
+ |
| 113 |
+/* |
| 114 |
* Updates _NET_ACTIVE_WINDOW with the currently focused window. |
| 115 |
* |
| 116 |
* EWMH: The window ID of the currently active window or None if no window has |
| 117 |
@@ -159,5 +198,5 @@ void ewmh_setup_hints(void) {
|
| 118 |
/* I’m not entirely sure if we need to keep _NET_WM_NAME on root. */ |
| 119 |
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A__NET_WM_NAME, A_UTF8_STRING, 8, strlen("i3"), "i3");
|
| 120 |
|
| 121 |
- xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A__NET_SUPPORTED, XCB_ATOM_ATOM, 32, 19, supported_atoms); |
| 122 |
+ xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A__NET_SUPPORTED, XCB_ATOM_ATOM, 32, 20, supported_atoms); |
| 123 |
} |
b/src/main.c
| 128 |
@@ -768,6 +768,7 @@ int main(int argc, char *argv[]) {
|
| 129 |
/* Set the ewmh desktop properties. */ |
| 130 |
ewmh_update_current_desktop(); |
| 131 |
ewmh_update_number_of_desktops(); |
| 132 |
+ ewmh_update_desktop_names(); |
| 133 |
|
| 134 |
struct ev_io *xcb_watcher = scalloc(sizeof(struct ev_io)); |
| 135 |
struct ev_io *xkb = scalloc(sizeof(struct ev_io)); |
b/src/workspace.c
| 140 |
@@ -93,6 +93,7 @@ Con *workspace_get(const char *num, bool *created) {
|
| 141 |
|
| 142 |
ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, "{\"change\":\"init\"}");
|
| 143 |
ewmh_update_number_of_desktops(); |
| 144 |
+ ewmh_update_desktop_names(); |
| 145 |
if (created != NULL) |
| 146 |
*created = true; |
| 147 |
} else if (created != NULL) {
|
| 148 |
@@ -426,6 +427,7 @@ static void _workspace_show(Con *workspace) {
|
| 149 |
tree_close(old, DONT_KILL_WINDOW, false, false); |
| 150 |
ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, "{\"change\":\"empty\"}");
|
| 151 |
ewmh_update_number_of_desktops(); |
| 152 |
+ ewmh_update_desktop_names(); |
| 153 |
} |
| 154 |
} |
| 155 |
|