diff --git a/src/atoms-list.txt b/src/atoms-list.txt index 3b14c5c..1d039be 100644 --- a/src/atoms-list.txt +++ b/src/atoms-list.txt @@ -10,6 +10,7 @@ UTF8_STRING COMPOUND_TEXT _NET_ACTIVE_WINDOW +_NET_CLIENT_LIST _NET_WM_NAME _NET_WM_ICON_NAME _NET_SUPPORTING_WM_CHECK diff --git a/src/client.c b/src/client.c index 4dd91cd..aebc218 100644 --- a/src/client.c +++ b/src/client.c @@ -204,6 +204,9 @@ void client_manage(xcb_window_t window, client_attach_list(c); client_attach_stack(c); + xcb_change_property(wm.xcb_conn, XCB_PROP_MODE_APPEND, wm.screen->root, + _NET_CLIENT_LIST, XCB_ATOM_WINDOW, 32, 1, &window); + monitor_arrange(c->monitor); monitor_draw_bar(c->monitor); @@ -284,6 +287,19 @@ void client_update_wm_hints(client_t *client) { } } +static void update_client_list(void) { + xcb_connection_t *conn = wm.xcb_conn; + xcb_window_t root = wm.screen->root; + xcb_atom_t atom = _NET_CLIENT_LIST; + uint8_t mode = XCB_PROP_MODE_PREPEND; + xcb_atom_t type = XCB_ATOM_WINDOW; + + xcb_delete_property(conn, root, atom); + for (client_t *c = wm.client_list; c; c = c->next) { + xcb_change_property(conn, mode, root, atom, type, 32, 1, &c->window); + } +} + void client_unmanage(client_t *client) { monitor_t *m = client->monitor; @@ -296,6 +312,8 @@ void client_unmanage(client_t *client) { client_wipe(client); + update_client_list(); + wm_restack_clients(); monitor_deal_focus(m); monitor_arrange(m); diff --git a/src/event.c b/src/event.c index f05edbe..17733e3 100644 --- a/src/event.c +++ b/src/event.c @@ -135,6 +135,22 @@ static void map_request(xcb_map_request_event_t *ev) { p_delete(&wa_reply); } +static void client_message(xcb_client_message_event_t *ev) { + client_t *c = client_get_by_window(ev->window); + if (c == nullptr) return; + + if (ev->type == _NET_ACTIVE_WINDOW) { + for (tag_t *t = c->monitor->tag_list; t; t = t->next) { + if ((t->mask & c->tags) == 0) continue; + + wm.current_monitor = c->monitor; + monitor_select_tag(c->monitor, t->mask); + client_focus(c); + return; + } + } +} + static void property_notify(xcb_property_notify_event_t *ev) { client_t *client = client_get_by_window(ev->window); if (client == nullptr) return; @@ -185,6 +201,7 @@ static void handle_xcb_event(xcb_generic_event_t *event) { EVENT(XCB_KEY_RELEASE, key_press); EVENT(XCB_CONFIGURE_REQUEST, configure_request); EVENT(XCB_MAP_REQUEST, map_request); + EVENT(XCB_CLIENT_MESSAGE, client_message); EVENT(XCB_PROPERTY_NOTIFY, property_notify); EVENT(XCB_UNMAP_NOTIFY, unmap_notify); EVENT(XCB_DESTROY_NOTIFY, destroy_notify);