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 <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2016-03-27 11:28:02 +02:00
parent 5fe0344232
commit 3117b439a2
4 changed files with 63 additions and 41 deletions

View File

@ -694,6 +694,9 @@ main(int argc, char **argv)
xcb_ungrab_server(globalconf.connection); xcb_ungrab_server(globalconf.connection);
xcb_flush(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 */ /* Parse and run configuration file */
if (!luaA_parserc(&xdg, confpath, true)) if (!luaA_parserc(&xdg, confpath, true))
fatal("couldn't find any rc file"); fatal("couldn't find any rc file");

View File

@ -171,6 +171,8 @@ typedef struct
struct xkb_state *xkb_state; struct xkb_state *xkb_state;
/** The preferred size of client icons for this screen */ /** The preferred size of client icons for this screen */
uint32_t preferred_icon_size; uint32_t preferred_icon_size;
/** Cached wallpaper information */
cairo_surface_t *wallpaper;
} awesome_t; } awesome_t;
extern awesome_t globalconf; 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; return globalconf.L.real_L_dont_use_directly;
} }
/* Defined in root.c */
void root_update_wallpaper(void);
#endif #endif
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80

View File

@ -381,6 +381,7 @@ property_handle_xrootpmap_id(uint8_t state,
xcb_window_t window) xcb_window_t window)
{ {
lua_State *L = globalconf_get_lua_State(); lua_State *L = globalconf_get_lua_State();
root_update_wallpaper();
signal_object_emit(L, &global_signals, "wallpaper_changed", 0); signal_object_emit(L, &global_signals, "wallpaper_changed", 0);
return 0; return 0;
} }

95
root.c
View File

@ -123,6 +123,58 @@ disconnect:
return result; 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 static xcb_keycode_t
_string_to_key_code(const char *s) _string_to_key_code(const char *s)
{ {
@ -344,13 +396,6 @@ luaA_root_drawins(lua_State *L)
static int static int
luaA_root_wallpaper(lua_State *L) 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) if(lua_gettop(L) == 1)
{ {
cairo_pattern_t *pattern = (cairo_pattern_t *)lua_touserdata(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; return 1;
} }
prop_c = xcb_get_property_unchecked(globalconf.connection, false, if(globalconf.wallpaper == NULL)
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 0; 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 has to make sure this surface gets destroyed */
lua_pushlightuserdata(L, surface); lua_pushlightuserdata(L, cairo_surface_reference(globalconf.wallpaper));
p_delete(&prop_r);
p_delete(&geom_r);
return 1; return 1;
} }