From 1cc071e24fb719da78fdc834a5b393d010928189 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Thu, 31 Jul 2008 17:29:05 +0200 Subject: [PATCH] client: add refcount for clients Signed-off-by: Julien Danjou --- client.c | 18 +++++++++++++++++- client.h | 2 +- common/xutil.h | 8 +++++++- structs.h | 15 +++++++++++++++ 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/client.c b/client.c index b313858b0..02d7bd73c 100644 --- a/client.c +++ b/client.c @@ -54,10 +54,12 @@ luaA_client_userdata_new(lua_State *L, client_t *p) { client_t **pp = lua_newuserdata(L, sizeof(client_t *)); *pp = p; + client_ref(pp); return luaA_settype(L, "client"); } DO_LUA_EQ(client_t, client, "client") +DO_LUA_GC(client_t, client, "client", client_unref) /** Load windows properties, restoring client's tag * and floating state before awesome was restarted if any. @@ -424,6 +426,7 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int screen) client_list_push(&globalconf.clients, c); /* Append client in history: it'll be last. */ focus_client_append(c); + client_ref(&c); /* Push client in stack */ client_raise(c); @@ -669,6 +672,9 @@ client_unmanage(client_t *c) { tag_array_t *tags = &globalconf.screens[c->screen].tags; + if(globalconf.screens[c->screen].client_focus == c) + client_unfocus(c); + /* call hook */ luaA_client_userdata_new(globalconf.L, c); luaA_dofunction(globalconf.L, globalconf.hooks.unmanage, 1, 0); @@ -707,7 +713,10 @@ client_unmanage(client_t *c) /* delete properties */ xcb_delete_property(globalconf.connection, c->win, _AWESOME_PROPERTIES); - p_delete(&c); + /* set client as invalid */ + c->invalid = true; + + client_unref(&c); } /** Update the WM hints of a client. @@ -1101,6 +1110,9 @@ luaA_client_newindex(lua_State *L) int i; titlebar_t **t = NULL; + if((*c)->invalid) + luaL_error(L, "client is invalid\n"); + switch(a_tokenize(buf, len)) { case A_TK_NAME: @@ -1230,6 +1242,9 @@ luaA_client_index(lua_State *L) xcb_get_property_cookie_t prop_c; xcb_get_property_reply_t *prop_r = NULL; + if((*c)->invalid) + luaL_error(L, "client is invalid\n"); + if(luaA_usemetatable(L, 1, 2)) return 1; @@ -1334,6 +1349,7 @@ const struct luaL_reg awesome_client_meta[] = { "__index", luaA_client_index }, { "__newindex", luaA_client_newindex }, { "__eq", luaA_client_eq }, + { "__gc", luaA_client_gc }, { "__tostring", luaA_client_tostring }, { NULL, NULL } }; diff --git a/client.h b/client.h index 2c52f7925..7ee34595b 100644 --- a/client.h +++ b/client.h @@ -49,7 +49,7 @@ int luaA_client_newindex(lua_State *); int luaA_client_userdata_new(lua_State *, client_t *); -DO_SLIST(client_t, client, p_delete) +DO_SLIST(client_t, client, client_unref) #endif // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/common/xutil.h b/common/xutil.h index de1f4ef88..43af0f1bf 100644 --- a/common/xutil.h +++ b/common/xutil.h @@ -123,10 +123,16 @@ xcb_cursor_t xutil_cursor_new(xcb_connection_t *, unsigned int); static inline xcb_screen_t * xutil_screen_get(xcb_connection_t *c, int screen) { + xcb_screen_t *s; + if(xcb_connection_has_error(c)) fatal("X connection invalid"); - return xcb_aux_get_screen(c, screen); + s = xcb_aux_get_screen(c, screen); + + assert(s); + + return s; } #endif diff --git a/structs.h b/structs.h index 839d799f5..b028d4bd2 100644 --- a/structs.h +++ b/structs.h @@ -239,6 +239,10 @@ struct statusbar_t /** client_t type */ struct client_t { + /** Ref counter */ + int refcount; + /** Valid, or not ? */ + bool invalid; /** Client name */ char *name; /** Window geometry */ @@ -294,7 +298,18 @@ struct client_t /** Next and previous clients */ client_t *prev, *next; }; + +static void +client_delete(client_t **c) +{ + button_list_wipe(&(*c)->buttons); + p_delete(&(*c)->icon_path); + p_delete(&(*c)->name); + p_delete(c); +} + DO_ARRAY(client_t *, client, DO_NOTHING) +DO_RCNT(client_t, client, client_delete) struct client_node_t {