diff --git a/client.c b/client.c index f1a41926b..bb204e20b 100644 --- a/client.c +++ b/client.c @@ -54,6 +54,7 @@ luaA_client_gc(lua_State *L) button_array_wipe(&c->buttons); key_array_wipe(&c->keys); image_unref(L, c->icon); + xcb_get_wm_protocols_reply_wipe(&c->protocols); p_delete(&c->class); p_delete(&c->startup_id); p_delete(&c->instance); @@ -510,6 +511,7 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int phys_screen, property_update_wm_name(c); property_update_wm_icon_name(c); property_update_wm_class(c, NULL); + property_update_wm_protocols(c); xutil_text_prop_get(globalconf.connection, c->win, _NET_STARTUP_ID, &c->startup_id, NULL); diff --git a/client.h b/client.h index e7ac0e386..8c41b91ba 100644 --- a/client.h +++ b/client.h @@ -130,6 +130,8 @@ struct client_t xcb_window_t group_win; /** Window holding command needed to start it (session management related) */ xcb_window_t leader_win; + /** Client's WM_PROTOCOLS property */ + xcb_get_wm_protocols_reply_t protocols; /** Client logical screen */ screen_t *screen; /** Client physical screen */ diff --git a/property.c b/property.c index b9322e1c1..e2cfa41cd 100644 --- a/property.c +++ b/property.c @@ -365,6 +365,41 @@ property_handle_net_wm_icon(void *data, return 0; } +/** Update the list of supported protocols for a client. + * \param c The client. + */ +void +property_update_wm_protocols(client_t *c) +{ + xcb_get_wm_protocols_reply_t protocols; + + /* If this fails for any reason, we still got the old value */ + if(xcb_get_wm_protocols_reply(globalconf.connection, + xcb_get_wm_protocols_unchecked(globalconf.connection, + c->win, WM_PROTOCOLS), + &protocols, NULL)) + { + xcb_get_wm_protocols_reply_wipe(&c->protocols); + memcpy(&c->protocols, &protocols, sizeof(protocols)); + } +} + +static int +property_handle_wm_protocols(void *data, + xcb_connection_t *connection, + uint8_t state, + xcb_window_t window, + xcb_atom_t name, + xcb_get_property_reply_t *reply) +{ + client_t *c = client_getbywin(window); + + if(c) + property_update_wm_protocols(c); + + return 0; +} + /** The property notify event handler. * \param data currently unused. * \param connection The connection to the X server. @@ -447,6 +482,8 @@ void a_xcb_set_property_handlers(void) property_handle_wm_icon_name, NULL); xcb_property_set_handler(&globalconf.prophs, WM_CLASS, UINT_MAX, property_handle_wm_class, NULL); + xcb_property_set_handler(&globalconf.prophs, WM_PROTOCOLS, UINT_MAX, + property_handle_wm_protocols, NULL); /* EWMH stuff */ xcb_property_set_handler(&globalconf.prophs, _NET_WM_NAME, UINT_MAX, diff --git a/property.h b/property.h index 259821f25..f492d10ac 100644 --- a/property.h +++ b/property.h @@ -31,6 +31,7 @@ void property_update_wm_hints(client_t *, xcb_get_property_reply_t *); void property_update_wm_class(client_t *, xcb_get_property_reply_t *); void property_update_wm_name(client_t *); void property_update_wm_icon_name(client_t *); +void property_update_wm_protocols(client_t *); void a_xcb_set_property_handlers(void); #endif