root.wallpaper: Use main connection for pixmap filling (FS#1087)

Previously, cairo would often have to download the old wallpaper from the X11
server and then upload it again. It did this because it couldn't see that the
two X11 connections involved are actually connected to the same X11 server.

This commit fixes this by setting up the pixmap from our main X11 connection.
This is the same connection that we use for accessing the "old" wallpaper and
thus cairo doesn't have to do stupid things.

The big improvement with this is that this speeds up wallpaper setup a lot.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2013-01-24 18:54:35 +01:00
parent cd5180f60f
commit 5024843e95
1 changed files with 12 additions and 7 deletions

19
root.c
View File

@ -79,15 +79,23 @@ root_set_wallpaper(cairo_pattern_t *pattern)
uint16_t height = screen->height_in_pixels; uint16_t height = screen->height_in_pixels;
bool result = false; bool result = false;
cairo_surface_t *surface; cairo_surface_t *surface;
cairo_device_t *device;
cairo_t *cr; cairo_t *cr;
if (xcb_connection_has_error(c)) if (xcb_connection_has_error(c))
goto disconnect; goto disconnect;
/* Create a pixmap and make sure it is already created, because we are going
* to use it from the other X11 connection (Juggling with X11 connections
* is a really, really bad idea).
*/
xcb_create_pixmap(c, screen->root_depth, p, screen->root, width, height); xcb_create_pixmap(c, screen->root_depth, p, screen->root, width, height);
surface = cairo_xcb_surface_create(c, p, draw_default_visual(screen), width, height); xcb_aux_sync(c);
device = cairo_device_reference(cairo_surface_get_device(surface));
/* Now paint to the picture from the main connection so that cairo sees that
* it can tell the X server to copy between the (possible) old pixmap and
* the new one directly and doesn't need GetImage and PutImage.
*/
surface = cairo_xcb_surface_create(globalconf.connection, p, draw_default_visual(screen), width, height);
cr = cairo_create(surface); cr = cairo_create(surface);
/* Paint the pattern to the surface */ /* Paint the pattern to the surface */
cairo_set_source(cr, pattern); cairo_set_source(cr, pattern);
@ -96,10 +104,7 @@ root_set_wallpaper(cairo_pattern_t *pattern)
cairo_destroy(cr); cairo_destroy(cr);
cairo_surface_finish(surface); cairo_surface_finish(surface);
cairo_surface_destroy(surface); cairo_surface_destroy(surface);
/* Make sure that cairo doesn't try to use the connection later again */ xcb_aux_sync(globalconf.connection);
assert(device != NULL);
cairo_device_finish(device);
cairo_device_destroy(device);
root_set_wallpaper_pixmap(c, p); root_set_wallpaper_pixmap(c, p);