From b47f480728a6d053c117e4b99ee4c78d99ba6a71 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Mon, 16 Jun 2014 02:50:47 -0400 Subject: [PATCH] Implement EWMH number of desktops property _NET_NUMBER_OF_DESKTOPS: > This property SHOULD be set and updated by the Window Manager to > indicate the number of virtual desktops. We interpret this property as the number of noninternal workspaces. --- include/atoms.xmacro | 1 + include/ewmh.h | 6 ++++++ src/ewmh.c | 23 ++++++++++++++++++++++- src/main.c | 3 ++- src/workspace.c | 2 ++ 5 files changed, 33 insertions(+), 2 deletions(-) diff --git a/include/atoms.xmacro b/include/atoms.xmacro index 90b02616..12e9ee28 100644 --- a/include/atoms.xmacro +++ b/include/atoms.xmacro @@ -16,6 +16,7 @@ xmacro(_NET_WM_STRUT_PARTIAL) xmacro(_NET_CLIENT_LIST) xmacro(_NET_CLIENT_LIST_STACKING) xmacro(_NET_CURRENT_DESKTOP) +xmacro(_NET_NUMBER_OF_DESKTOPS) xmacro(_NET_ACTIVE_WINDOW) xmacro(_NET_STARTUP_ID) xmacro(_NET_WORKAREA) diff --git a/include/ewmh.h b/include/ewmh.h index 46d6c985..38d612da 100644 --- a/include/ewmh.h +++ b/include/ewmh.h @@ -18,6 +18,12 @@ */ void ewmh_update_current_desktop(void); +/** + * Updates _NET_NUMBER_OF_DESKTOPS which we interpret as the number of + * noninternal workspaces. + */ +void ewmh_update_number_of_desktops(void); + /** * Updates _NET_ACTIVE_WINDOW with the currently focused window. * diff --git a/src/ewmh.c b/src/ewmh.c index 0c860ad0..7ab0c22a 100644 --- a/src/ewmh.c +++ b/src/ewmh.c @@ -40,6 +40,27 @@ void ewmh_update_current_desktop(void) { } } +/* + * Updates _NET_NUMBER_OF_DESKTOPS which we interpret as the number of + * noninternal workspaces. + */ +void ewmh_update_number_of_desktops(void) { + Con *output; + uint32_t idx = 0; + + TAILQ_FOREACH (output, &(croot->nodes_head), nodes) { + Con *ws; + TAILQ_FOREACH (ws, &(output_get_content(output)->nodes_head), nodes) { + if (STARTS_WITH(ws->name, "__")) + continue; + ++idx; + } + } + + xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, + A__NET_NUMBER_OF_DESKTOPS, XCB_ATOM_CARDINAL, 32, 1, &idx); +} + /* * Updates _NET_ACTIVE_WINDOW with the currently focused window. * @@ -133,7 +154,7 @@ void ewmh_setup_hints(void) { NULL); xcb_change_property(conn, XCB_PROP_MODE_REPLACE, child_window, A__NET_SUPPORTING_WM_CHECK, XCB_ATOM_WINDOW, 32, 1, &child_window); xcb_change_property(conn, XCB_PROP_MODE_REPLACE, child_window, A__NET_WM_NAME, A_UTF8_STRING, 8, strlen("i3"), "i3"); - xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A__NET_SUPPORTING_WM_CHECK, XCB_ATOM_WINDOW, 32, 1, &child_window); + xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A__NET_SUPPORTING_WM_CHECK, XCB_ATOM_WINDOW, 33, 1, &child_window); /* I’m not entirely sure if we need to keep _NET_WM_NAME on root. */ xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A__NET_WM_NAME, A_UTF8_STRING, 8, strlen("i3"), "i3"); diff --git a/src/main.c b/src/main.c index 632e68c4..917ae1cb 100644 --- a/src/main.c +++ b/src/main.c @@ -765,8 +765,9 @@ int main(int argc, char *argv[]) { x_set_i3_atoms(); ewmh_update_workarea(); - /* Set the _NET_CURRENT_DESKTOP property. */ + /* Set the ewmh desktop properties. */ ewmh_update_current_desktop(); + ewmh_update_number_of_desktops(); struct ev_io *xcb_watcher = scalloc(sizeof(struct ev_io)); struct ev_io *xkb = scalloc(sizeof(struct ev_io)); diff --git a/src/workspace.c b/src/workspace.c index d626d17c..41c02952 100644 --- a/src/workspace.c +++ b/src/workspace.c @@ -92,6 +92,7 @@ Con *workspace_get(const char *num, bool *created) { con_attach(workspace, content, false); ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, "{\"change\":\"init\"}"); + ewmh_update_number_of_desktops(); if (created != NULL) *created = true; } else if (created != NULL) { @@ -424,6 +425,7 @@ static void _workspace_show(Con *workspace) { LOG("Closing old workspace (%p / %s), it is empty\n", old, old->name); tree_close(old, DONT_KILL_WINDOW, false, false); ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, "{\"change\":\"empty\"}"); + ewmh_update_number_of_desktops(); } }