diff --git a/src/atoms-list.txt b/src/atoms-list.txt index 1d039be..9c9feac 100644 --- a/src/atoms-list.txt +++ b/src/atoms-list.txt @@ -11,6 +11,7 @@ COMPOUND_TEXT _NET_ACTIVE_WINDOW _NET_CLIENT_LIST +_NET_WM_DESKTOP _NET_WM_NAME _NET_WM_ICON_NAME _NET_SUPPORTING_WM_CHECK diff --git a/src/client.c b/src/client.c index b1ad0f3..6325587 100644 --- a/src/client.c +++ b/src/client.c @@ -77,6 +77,8 @@ task_in_tag_t *client_get_previous_task_in_tag(client_t *client, tag_t *tag) { static void client_add_to_tag(client_t *client, tag_t *tag) { if (client_get_task_in_tag(client, tag)) return; + xwindow_set_wm_desktop(client->window, tag->index); + task_in_tag_t *task = p_new(task_in_tag_t, 1); task->client = client; task->next = tag->task_list; @@ -145,6 +147,20 @@ static inline void client_init_geometry(client_t *c) { client_change_border_width(c, wm.border_width); } +static void client_init_tag_by_wm_desktop(client_t *client) { + uint32_t tag_index = 0; + if (!xwindow_get_wm_desktop(client->window, &tag_index)) return; + for (monitor_t *m = wm.monitor_list; m; m = m->next) { + for (tag_t *tag = m->tag_list; tag; tag = tag->next) { + if (tag->index == tag_index) { + client->monitor = m; + client->tags = tag->mask; + return; + } + } + } +} + void client_manage(xcb_window_t window, xcb_get_geometry_reply_t *geometry_reply) { client_t *c = p_new(client_t, 1); @@ -198,6 +214,7 @@ void client_manage(xcb_window_t window, } client_init_geometry(c); + client_init_tag_by_wm_desktop(c); client_tags_apply(c); } diff --git a/src/xwindow.c b/src/xwindow.c index 66f547f..b10df16 100644 --- a/src/xwindow.c +++ b/src/xwindow.c @@ -206,6 +206,25 @@ void xwindow_get_text_property(xcb_window_t window, xcb_atom_t property, p_delete(&reply); } +void xwindow_set_wm_desktop(xcb_window_t window, uint32_t desktop) { + xcb_change_property(wm.xcb_conn, XCB_PROP_MODE_REPLACE, window, + _NET_WM_DESKTOP, XCB_ATOM_CARDINAL, 32, 1, &desktop); +} + +bool xwindow_get_wm_desktop(xcb_window_t window, uint32_t *desktop) { + xcb_get_property_cookie_t cookie = xcb_get_property_unchecked( + wm.xcb_conn, false, window, _NET_WM_DESKTOP, XCB_ATOM_CARDINAL, 0, 1); + xcb_get_property_reply_t *reply = + xcb_get_property_reply(wm.xcb_conn, cookie, nullptr); + if (!reply) return false; + + bool success = reply->type == XCB_ATOM_CARDINAL && reply->format == 32; + if (success) *desktop = *(uint32_t *)xcb_get_property_value(reply); + + p_delete(&reply); + return success; +} + xcb_window_t xwindow_get_transient_for(xcb_window_t window) { xcb_connection_t *conn = wm.xcb_conn; xcb_window_t t_window = XCB_WINDOW_NONE; diff --git a/src/xwindow.h b/src/xwindow.h index cdf51a3..9f70e41 100644 --- a/src/xwindow.h +++ b/src/xwindow.h @@ -20,6 +20,9 @@ bool xwindow_send_event(xcb_window_t window, xcb_atom_t atom); void xwindow_focus(xcb_window_t window); void xwindow_get_text_property(xcb_window_t window, xcb_atom_t property, char **out); +void xwindow_set_wm_desktop(xcb_window_t window, uint32_t desktop); +bool xwindow_get_wm_desktop(xcb_window_t window, uint32_t *desktop); + xcb_window_t xwindow_get_transient_for(xcb_window_t window); int32_t xwindow_get_state(xcb_window_t window); xcb_get_geometry_reply_t *xwindow_get_geometry_reply(xcb_window_t window);