diff --git a/client.c b/client.c index 8b41c859..0d21f4f1 100644 --- a/client.c +++ b/client.c @@ -24,6 +24,7 @@ #include #include +#include "image.h" #include "client.h" #include "tag.h" #include "window.h" @@ -389,6 +390,7 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int phys_screen, { xcb_get_property_cookie_t ewmh_icon_cookie; client_t *c; + draw_image_t *icon; const uint32_t select_input_val[] = { XCB_EVENT_MASK_STRUCTURE_NOTIFY @@ -419,7 +421,11 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int phys_screen, c->geometry.width = c->f_geometry.width = c->m_geometry.width = wgeom->width; c->geometry.height = c->f_geometry.height = c->m_geometry.height = wgeom->height; client_setborder(c, wgeom->border_width); - c->icon = ewmh_window_icon_get_reply(ewmh_icon_cookie); + if((icon = ewmh_window_icon_get_reply(ewmh_icon_cookie))) + { + c->icon = image_new(icon); + image_ref(&c->icon); + } /* we honor size hints by default */ c->honorsizehints = true; @@ -1017,7 +1023,7 @@ luaA_client_visible_get(lua_State *L) for(c = globalconf.clients; c; c = c->next) if(client_isvisible(c, screen)) { - luaA_client_userdata_new(globalconf.L, c); + luaA_client_userdata_new(L, c); lua_rawseti(L, -2, i++); } @@ -1274,6 +1280,7 @@ luaA_client_newindex(lua_State *L) double d; int i; titlebar_t **t = NULL; + image_t **image; if((*c)->invalid) luaL_error(L, "client is invalid\n"); @@ -1316,10 +1323,11 @@ luaA_client_newindex(lua_State *L) case A_TK_FULLSCREEN: client_setfullscreen(*c, luaA_checkboolean(L, 3)); break; - case A_TK_ICON_PATH: - buf = luaL_checkstring(L, 3); - p_delete(&(*c)->icon_path); - (*c)->icon_path = a_strdup(buf); + case A_TK_ICON: + image = luaA_checkudata(L, 3, "image"); + image_unref(&(*c)->icon); + image_ref(image); + (*c)->icon = *image; widget_invalidate_cache((*c)->screen, WIDGET_CACHE_CLIENTS); break; case A_TK_OPACITY: @@ -1525,8 +1533,11 @@ luaA_client_index(lua_State *L) case A_TK_FULLSCREEN: lua_pushboolean(L, (*c)->isfullscreen); break; - case A_TK_ICON_PATH: - lua_pushstring(L, (*c)->icon_path); + case A_TK_ICON: + if((*c)->icon) + luaA_image_userdata_new(L, (*c)->icon); + else + return 0; break; case A_TK_OPACITY: if((d = window_opacity_get((*c)->win)) >= 0) @@ -1554,7 +1565,7 @@ luaA_client_index(lua_State *L) break; case A_TK_TITLEBAR: if((*c)->titlebar) - return luaA_titlebar_userdata_new(globalconf.L, (*c)->titlebar); + return luaA_titlebar_userdata_new(L, (*c)->titlebar); return 0; case A_TK_URGENT: lua_pushboolean(L, (*c)->isurgent); diff --git a/common/tokenize.gperf b/common/tokenize.gperf index b3d73d45..1d00e207 100644 --- a/common/tokenize.gperf +++ b/common/tokenize.gperf @@ -24,8 +24,8 @@ grow height hide honorsizehints +icon icon_name -icon_path image instance invert diff --git a/event.c b/event.c index e948e49d..5a79e883 100644 --- a/event.c +++ b/event.c @@ -668,9 +668,16 @@ event_handle_propertynotify(void *data __attribute__ ((unused)), else if(ev->atom == _NET_WM_ICON) { xcb_get_property_cookie_t icon_q = ewmh_window_icon_get_unchecked(c->win); - draw_image_delete(&c->icon); + draw_image_t *icon; + image_unref(&c->icon); widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS); - c->icon = ewmh_window_icon_get_reply(icon_q); + if((icon = ewmh_window_icon_get_reply(icon_q))) + { + c->icon = image_new(icon); + image_ref(&c->icon); + } + else + c->icon = NULL; } } diff --git a/image.c b/image.c index fe364b74..9539f095 100644 --- a/image.c +++ b/image.c @@ -24,7 +24,7 @@ extern awesome_t globalconf; -DO_LUA_NEW(static, image_t, image, "image", image_ref) +DO_LUA_NEW(extern, image_t, image, "image", image_ref) DO_LUA_GC(image_t, image, "image", image_unref) DO_LUA_EQ(image_t, image, "image") diff --git a/image.h b/image.h index c52ca38b..2d90bade 100644 --- a/image.h +++ b/image.h @@ -22,7 +22,10 @@ #ifndef AWESOME_IMAGE_H #define AWESOME_IMAGE_H +#include + #include "draw.h" +#include "common/refcount.h" typedef struct { @@ -43,5 +46,19 @@ image_delete(image_t **i) DO_RCNT(image_t, image, image_delete) +int luaA_image_userdata_new(lua_State *, image_t *); + +/** Create a new image from a draw_image_t object. + * \param i The image data. + * \return A image_t object. + */ +static inline image_t * +image_new(draw_image_t *i) +{ + image_t *image = p_new(image_t, 1); + image->image = i; + return image; +} + #endif // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/structs.h b/structs.h index a0743e07..38dd4e01 100644 --- a/structs.h +++ b/structs.h @@ -30,10 +30,10 @@ #include "layout.h" #include "swindow.h" #include "xscreen.h" +#include "image.h" #include "common/xutil.h" #include "common/xembed.h" #include "common/refcount.h" -#include "draw.h" /** Stacking layout layers */ typedef enum @@ -329,7 +329,7 @@ struct client_t /** Button bindings */ button_array_t buttons; /** Icon */ - draw_image_t *icon; + image_t *icon; /** Size hints */ xcb_size_hints_t size_hints; /** Next and previous clients */ diff --git a/widgets/appicon.c b/widgets/appicon.c index 8b31e869..392a1627 100644 --- a/widgets/appicon.c +++ b/widgets/appicon.c @@ -56,11 +56,9 @@ appicon_draw(draw_context_t *ctx, int screen __attribute__ ((unused)), if(c) { - if(!(image = draw_image_new(c->icon_path))) - image = c->icon; - - if(image) + if(c->icon) { + image = c->icon->image; w->area.width = ((double) ctx->height / (double) image->height) * image->width; w->area.x = widget_calculate_offset(ctx->width, w->area.width, @@ -68,8 +66,6 @@ appicon_draw(draw_context_t *ctx, int screen __attribute__ ((unused)), w->widget->align); draw_image(ctx, w->area.x, w->area.y, ctx->height, image); - if(image != c->icon) - draw_image_delete(&image); } } else diff --git a/widgets/tasklist.c b/widgets/tasklist.c index 93a42fb6..de949210 100644 --- a/widgets/tasklist.c +++ b/widgets/tasklist.c @@ -142,20 +142,12 @@ tasklist_draw_item(draw_context_t *ctx, else parser_data = NULL; - /* use image from icon_path, otherwise netwm icon */ - if(!(image = draw_image_new(odata->client_labels.tab[i].client->icon_path))) - image = odata->client_labels.tab[i].client->icon; - - if(image) + if(odata->client_labels.tab[i].client->icon) { - + image = odata->client_labels.tab[i].client->icon->image; icon_width = ((double) ctx->height / (double) image->height) * image->width; draw_image(ctx, w->area.x + odata->box_width * i, w->area.y, ctx->height, image); - - /* a bit hackish */ - if(image != odata->client_labels.tab[i].client->icon) - draw_image_delete(&image); } } else