Keep the cairo surface we use for setting the wallpaper

This fixes a race where we would keep giving the old wallpaper surface to Lua
when a new one was set, because we didn't get the "wallpaper changed"-event yet.
Fix this by just keeping the surface we use for setting the wallpaper around.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2016-03-27 11:36:23 +02:00
parent d9c918c14a
commit 222f0a133c
1 changed files with 18 additions and 2 deletions

20
root.c
View File

@ -74,6 +74,7 @@ root_set_wallpaper_pixmap(xcb_connection_t *c, xcb_pixmap_t p)
static bool static bool
root_set_wallpaper(cairo_pattern_t *pattern) root_set_wallpaper(cairo_pattern_t *pattern)
{ {
lua_State *L = globalconf_get_lua_State();
xcb_connection_t *c = xcb_connect(NULL, NULL); xcb_connection_t *c = xcb_connect(NULL, NULL);
xcb_pixmap_t p = xcb_generate_id(c); xcb_pixmap_t p = xcb_generate_id(c);
/* globalconf.connection should be connected to the same X11 server, so we /* globalconf.connection should be connected to the same X11 server, so we
@ -107,15 +108,30 @@ root_set_wallpaper(cairo_pattern_t *pattern)
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
cairo_paint(cr); cairo_paint(cr);
cairo_destroy(cr); cairo_destroy(cr);
cairo_surface_finish(surface); cairo_surface_flush(surface);
cairo_surface_destroy(surface);
xcb_aux_sync(globalconf.connection); xcb_aux_sync(globalconf.connection);
/* Change the wallpaper, without sending us a PropertyNotify event */
xcb_grab_server(globalconf.connection);
xcb_change_window_attributes(globalconf.connection,
globalconf.screen->root,
XCB_CW_EVENT_MASK,
(uint32_t[]) { 0 });
root_set_wallpaper_pixmap(c, p); root_set_wallpaper_pixmap(c, p);
xcb_change_window_attributes(globalconf.connection,
globalconf.screen->root,
XCB_CW_EVENT_MASK,
ROOT_WINDOW_EVENT_MASK);
xcb_ungrab_server(globalconf.connection);
/* Make sure our pixmap is not destroyed when we disconnect. */ /* Make sure our pixmap is not destroyed when we disconnect. */
xcb_set_close_down_mode(c, XCB_CLOSE_DOWN_RETAIN_PERMANENT); xcb_set_close_down_mode(c, XCB_CLOSE_DOWN_RETAIN_PERMANENT);
/* Tell Lua that the wallpaper changed */
cairo_surface_destroy(globalconf.wallpaper);
globalconf.wallpaper = surface;
signal_object_emit(L, &global_signals, "wallpaper_changed", 0);
result = true; result = true;
disconnect: disconnect:
xcb_flush(c); xcb_flush(c);