From 3117b439a24d48c908a9ea89fe8b7f5165a61b48 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sun, 27 Mar 2016 11:28:02 +0200 Subject: [PATCH] Cache the wallpaper Instead of querying the wallpaper every time that root.wallpaper() is called, we just remember it in globalconf. Signed-off-by: Uli Schlachter --- awesome.c | 3 ++ globalconf.h | 5 +++ property.c | 1 + root.c | 95 +++++++++++++++++++++++++++++----------------------- 4 files changed, 63 insertions(+), 41 deletions(-) diff --git a/awesome.c b/awesome.c index b16f2395..2c4caa82 100644 --- a/awesome.c +++ b/awesome.c @@ -694,6 +694,9 @@ main(int argc, char **argv) xcb_ungrab_server(globalconf.connection); xcb_flush(globalconf.connection); + /* get the current wallpaper, from now on we are informed when it changes */ + root_update_wallpaper(); + /* Parse and run configuration file */ if (!luaA_parserc(&xdg, confpath, true)) fatal("couldn't find any rc file"); diff --git a/globalconf.h b/globalconf.h index 8d5791cc..be4a6535 100644 --- a/globalconf.h +++ b/globalconf.h @@ -171,6 +171,8 @@ typedef struct struct xkb_state *xkb_state; /** The preferred size of client icons for this screen */ uint32_t preferred_icon_size; + /** Cached wallpaper information */ + cairo_surface_t *wallpaper; } awesome_t; extern awesome_t globalconf; @@ -182,5 +184,8 @@ static inline lua_State *globalconf_get_lua_State(void) { return globalconf.L.real_L_dont_use_directly; } +/* Defined in root.c */ +void root_update_wallpaper(void); + #endif // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/property.c b/property.c index d48747c1..faf13b18 100644 --- a/property.c +++ b/property.c @@ -381,6 +381,7 @@ property_handle_xrootpmap_id(uint8_t state, xcb_window_t window) { lua_State *L = globalconf_get_lua_State(); + root_update_wallpaper(); signal_object_emit(L, &global_signals, "wallpaper_changed", 0); return 0; } diff --git a/root.c b/root.c index 8bbe960f..6b1ab5c5 100644 --- a/root.c +++ b/root.c @@ -123,6 +123,58 @@ disconnect: return result; } +void +root_update_wallpaper(void) +{ + xcb_get_property_cookie_t prop_c; + xcb_get_property_reply_t *prop_r; + xcb_get_geometry_cookie_t geom_c; + xcb_get_geometry_reply_t *geom_r; + xcb_pixmap_t *rootpix; + + cairo_surface_destroy(globalconf.wallpaper); + globalconf.wallpaper = NULL; + + prop_c = xcb_get_property_unchecked(globalconf.connection, false, + globalconf.screen->root, _XROOTPMAP_ID, XCB_ATOM_PIXMAP, 0, 1); + prop_r = xcb_get_property_reply(globalconf.connection, prop_c, NULL); + + if (!prop_r || !prop_r->value_len) + { + p_delete(&prop_r); + return; + } + + rootpix = xcb_get_property_value(prop_r); + if (!rootpix) + { + p_delete(&prop_r); + return; + } + + geom_c = xcb_get_geometry_unchecked(globalconf.connection, *rootpix); + geom_r = xcb_get_geometry_reply(globalconf.connection, geom_c, NULL); + if (!geom_r) + { + p_delete(&prop_r); + return; + } + + /* Only the default visual makes sense, so just the default depth */ + if (geom_r->depth != draw_visual_depth(globalconf.screen, globalconf.default_visual->visual_id)) + warn("Got a pixmap with depth %d, but the default depth is %d, continuing anyway", + geom_r->depth, draw_visual_depth(globalconf.screen, globalconf.default_visual->visual_id)); + + globalconf.wallpaper = cairo_xcb_surface_create(globalconf.connection, + *rootpix, + globalconf.default_visual, + geom_r->width, + geom_r->height); + + p_delete(&prop_r); + p_delete(&geom_r); +} + static xcb_keycode_t _string_to_key_code(const char *s) { @@ -344,13 +396,6 @@ luaA_root_drawins(lua_State *L) static int luaA_root_wallpaper(lua_State *L) { - xcb_get_property_cookie_t prop_c; - xcb_get_property_reply_t *prop_r; - xcb_get_geometry_cookie_t geom_c; - xcb_get_geometry_reply_t *geom_r; - xcb_pixmap_t *rootpix; - cairo_surface_t *surface; - if(lua_gettop(L) == 1) { cairo_pattern_t *pattern = (cairo_pattern_t *)lua_touserdata(L, -1); @@ -359,43 +404,11 @@ luaA_root_wallpaper(lua_State *L) return 1; } - prop_c = xcb_get_property_unchecked(globalconf.connection, false, - globalconf.screen->root, _XROOTPMAP_ID, XCB_ATOM_PIXMAP, 0, 1); - prop_r = xcb_get_property_reply(globalconf.connection, prop_c, NULL); - - if (!prop_r || !prop_r->value_len) - { - p_delete(&prop_r); + if(globalconf.wallpaper == NULL) return 0; - } - - rootpix = xcb_get_property_value(prop_r); - if (!rootpix) - { - p_delete(&prop_r); - return 0; - } - - geom_c = xcb_get_geometry_unchecked(globalconf.connection, *rootpix); - geom_r = xcb_get_geometry_reply(globalconf.connection, geom_c, NULL); - if (!geom_r) - { - p_delete(&prop_r); - return 0; - } - - /* Only the default visual makes sense, so just the default depth */ - if (geom_r->depth != draw_visual_depth(globalconf.screen, globalconf.default_visual->visual_id)) - warn("Got a pixmap with depth %d, but the default depth is %d, continuing anyway", - geom_r->depth, draw_visual_depth(globalconf.screen, globalconf.default_visual->visual_id)); - - surface = cairo_xcb_surface_create(globalconf.connection, *rootpix, globalconf.default_visual, - geom_r->width, geom_r->height); /* lua has to make sure this surface gets destroyed */ - lua_pushlightuserdata(L, surface); - p_delete(&prop_r); - p_delete(&geom_r); + lua_pushlightuserdata(L, cairo_surface_reference(globalconf.wallpaper)); return 1; }