From 0d6d6c4fa711ed735f8d7359f9473e218baedcb5 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Sat, 4 Apr 2009 13:41:17 +0200 Subject: [PATCH] client: store class and instance Signed-off-by: Julien Danjou --- client.c | 16 +++------------- client.h | 2 ++ property.c | 36 ++++++++++++++++++++++++++++++++++++ property.h | 1 + structs.h | 2 ++ 5 files changed, 44 insertions(+), 13 deletions(-) diff --git a/client.c b/client.c index ccaa49ac1..a195d9fe6 100644 --- a/client.c +++ b/client.c @@ -558,6 +558,7 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int phys_screen, /* update window title */ property_update_wm_name(c); property_update_wm_icon_name(c); + property_update_wm_class(c); /* update strut */ ewmh_process_client_strut(c, NULL); @@ -1833,7 +1834,6 @@ luaA_client_index(lua_State *L) const char *buf = luaL_checklstring(L, 2, &len); char *value; void *data; - xcb_get_wm_class_reply_t hint; xcb_get_property_cookie_t prop_c; xcb_get_property_reply_t *prop_r = NULL; double d; @@ -1910,20 +1910,10 @@ luaA_client_index(lua_State *L) } break; case A_TK_CLASS: - if(!xcb_get_wm_class_reply(globalconf.connection, - xcb_get_wm_class_unchecked(globalconf.connection, (*c)->win), - &hint, NULL)) - return 0; - lua_pushstring(L, hint.class_name); - xcb_get_wm_class_reply_wipe(&hint); + lua_pushstring(L, (*c)->class); break; case A_TK_INSTANCE: - if(!xcb_get_wm_class_reply(globalconf.connection, - xcb_get_wm_class_unchecked(globalconf.connection, (*c)->win), - &hint, NULL)) - return 0; - lua_pushstring(L, hint.instance_name); - xcb_get_wm_class_reply_wipe(&hint); + lua_pushstring(L, (*c)->instance); break; case A_TK_ROLE: if(!xutil_text_prop_get(globalconf.connection, (*c)->win, diff --git a/client.h b/client.h index 1cdb817fd..b1d107786 100644 --- a/client.h +++ b/client.h @@ -36,6 +36,8 @@ static void client_delete(client_t **c) { button_array_wipe(&(*c)->buttons); + p_delete(&(*c)->class); + p_delete(&(*c)->instance); p_delete(&(*c)->icon_name); p_delete(&(*c)->name); p_delete(c); diff --git a/property.c b/property.c index 1fd85e4c7..ab30e2273 100644 --- a/property.c +++ b/property.c @@ -223,6 +223,24 @@ property_update_wm_name(client_t *c) hooks_property(c, "name"); } +void +property_update_wm_class(client_t *c) +{ + xcb_get_wm_class_reply_t hint; + + p_delete(&c->instance); + p_delete(&c->class); + + if(xcb_get_wm_class_reply(globalconf.connection, + xcb_get_wm_class_unchecked(globalconf.connection, c->win), + &hint, NULL)) + { + c->instance = a_strdup(hint.instance_name); + c->class = a_strdup(hint.class_name); + xcb_get_wm_class_reply_wipe(&hint); + } +} + /** Update client icon name attribute with its new title. * \param c The client. * \param Return true if it has been updated. @@ -277,6 +295,22 @@ property_handle_wm_icon_name(void *data, return 0; } +static int +property_handle_wm_class(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_class(c); + + return 0; +} + static int property_handle_net_wm_strut_partial(void *data, xcb_connection_t *connection, @@ -386,6 +420,8 @@ void a_xcb_set_property_handlers(void) property_handle_wm_name, NULL); xcb_property_set_handler(&globalconf.prophs, WM_ICON_NAME, UINT_MAX, property_handle_wm_icon_name, NULL); + xcb_property_set_handler(&globalconf.prophs, WM_CLASS, UINT_MAX, + property_handle_wm_class, NULL); /* EWMH stuff */ xcb_property_set_handler(&globalconf.prophs, _NET_WM_NAME, UINT_MAX, diff --git a/property.h b/property.h index e00851df4..1c98fe0ca 100644 --- a/property.h +++ b/property.h @@ -28,6 +28,7 @@ void property_update_wm_transient_for(client_t *, xcb_get_property_reply_t *); void property_update_wm_client_leader(client_t *c, xcb_get_property_reply_t *reply); void property_update_wm_normal_hints(client_t *, xcb_get_property_reply_t *); void property_update_wm_hints(client_t *, xcb_get_property_reply_t *); +void property_update_wm_class(client_t *); void property_update_wm_name(client_t *); void property_update_wm_icon_name(client_t *); void a_xcb_set_property_handlers(void); diff --git a/structs.h b/structs.h index 368a1121a..f3a255b6a 100644 --- a/structs.h +++ b/structs.h @@ -167,6 +167,8 @@ struct client_t bool invalid; /** Client name */ char *name, *icon_name; + /** WM_CLASS stuff */ + char *class, *instance; /** Window geometry */ area_t geometry; struct