diff --git a/client.c b/client.c index 3993ed815..bec530aa6 100644 --- a/client.c +++ b/client.c @@ -549,6 +549,7 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int phys_screen, property_update_wm_transient_for(c, NULL); property_update_wm_client_leader(c, NULL); property_update_wm_client_machine(c); + property_update_net_wm_pid(c, NULL); /* Then check clients hints */ ewmh_client_check_hints(c); @@ -1633,9 +1634,6 @@ luaA_client_index(lua_State *L) client_t *c = luaA_client_checkudata(L, 1); const char *buf = luaL_checklstring(L, 2, &len); char *value; - void *data; - xcb_get_property_cookie_t prop_c; - xcb_get_property_reply_t *prop_r = NULL; double d; if(luaA_usemetatable(L, 1, 2)) @@ -1714,16 +1712,7 @@ luaA_client_index(lua_State *L) p_delete(&value); break; case A_TK_PID: - prop_c = xcb_get_property_unchecked(globalconf.connection, false, c->win, _NET_WM_PID, CARDINAL, 0L, 1L); - prop_r = xcb_get_property_reply(globalconf.connection, prop_c, NULL); - - if(prop_r && prop_r->value_len && (data = xcb_get_property_value(prop_r))) - lua_pushnumber(L, *(uint32_t *)data); - else - { - p_delete(&prop_r); - return 0; - } + lua_pushnumber(L, c->pid); break; case A_TK_ID: lua_pushnumber(L, c->win); diff --git a/client.h b/client.h index d0d98736b..ae165d76e 100644 --- a/client.h +++ b/client.h @@ -150,6 +150,8 @@ struct client_t bool size_hints_honor; /** Machine the client is running on. */ char *machine; + /** Client pid */ + uint32_t pid; /** Window it is transient for */ client_t *transient_for; }; diff --git a/property.c b/property.c index 1df965f41..1c37705a3 100644 --- a/property.c +++ b/property.c @@ -397,6 +397,46 @@ property_handle_net_wm_icon(void *data, return 0; } +void +property_update_net_wm_pid(client_t *c, + xcb_get_property_reply_t *reply) +{ + bool no_reply = !reply; + + if(no_reply) + { + xcb_get_property_cookie_t prop_c = + xcb_get_property_unchecked(globalconf.connection, false, c->win, _NET_WM_PID, CARDINAL, 0L, 1L); + reply = xcb_get_property_reply(globalconf.connection, prop_c, NULL); + } + + if(reply && reply->value_len) + { + uint32_t *rdata = xcb_get_property_value(reply); + if(rdata) + c->pid = *rdata; + } + + if(no_reply) + p_delete(&reply); +} + +static int +property_handle_net_wm_pid(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_net_wm_pid(c, reply); + + return 0; +} + /** Update the list of supported protocols for a client. * \param c The client. */ @@ -539,6 +579,8 @@ void a_xcb_set_property_handlers(void) property_handle_net_wm_strut_partial, NULL); xcb_property_set_handler(&globalconf.prophs, _NET_WM_ICON, UINT_MAX, property_handle_net_wm_icon, NULL); + xcb_property_set_handler(&globalconf.prophs, _NET_WM_PID, UINT_MAX, + property_handle_net_wm_pid, NULL); /* background change */ xcb_property_set_handler(&globalconf.prophs, _XROOTPMAP_ID, 1, diff --git a/property.h b/property.h index 9c8e09416..5f761ab6c 100644 --- a/property.h +++ b/property.h @@ -33,6 +33,7 @@ void property_update_wm_name(client_t *); void property_update_wm_icon_name(client_t *); void property_update_wm_protocols(client_t *); void property_update_wm_client_machine(client_t *); +void property_update_net_wm_pid(client_t *, xcb_get_property_reply_t *); void a_xcb_set_property_handlers(void); #endif