use double buffering

render to cairo_image_surface and drop that onto the xlib_surface
to get rid of flickering on redraws.
This commit is contained in:
Sascha Kruse 2013-03-08 02:30:23 +01:00
parent aa91688795
commit 5099b57ee5

33
x.c
View File

@ -30,6 +30,7 @@ bool dunst_grab_errored = false;
typedef struct _cairo_ctx { typedef struct _cairo_ctx {
cairo_status_t status; cairo_status_t status;
cairo_surface_t *surface; cairo_surface_t *surface;
cairo_t *context;
PangoFontDescription *desc; PangoFontDescription *desc;
} cairo_ctx_t; } cairo_ctx_t;
@ -134,6 +135,8 @@ void x_cairo_setup(void)
cairo_ctx.surface = cairo_xlib_surface_create(xctx.dpy, cairo_ctx.surface = cairo_xlib_surface_create(xctx.dpy,
xctx.win, DefaultVisual(xctx.dpy, 0), WIDTH, HEIGHT); xctx.win, DefaultVisual(xctx.dpy, 0), WIDTH, HEIGHT);
cairo_ctx.context = cairo_create(cairo_ctx.surface);
cairo_ctx.desc = pango_font_description_from_string(settings.font); cairo_ctx.desc = pango_font_description_from_string(settings.font);
frame_color = x_string_to_color_t(settings.frame_color); frame_color = x_string_to_color_t(settings.frame_color);
@ -294,12 +297,10 @@ void r_free_layouts(GSList *layouts)
void x_win_draw(void) void x_win_draw(void)
{ {
cairo_t *c;
c = cairo_create(cairo_ctx.surface);
GSList *layouts = r_create_layouts(c);
int height = 0; int height = 0;
int text_width = 0; int text_width = 0;
GSList *layouts = r_create_layouts(cairo_ctx.context);
for (GSList *iter = layouts; iter; iter = iter->next) { for (GSList *iter = layouts; iter; iter = iter->next) {
colored_layout *cl = iter->data; colored_layout *cl = iter->data;
@ -318,7 +319,12 @@ void x_win_draw(void)
height += (g_slist_length(layouts) - 1) * settings.separator_height; height += (g_slist_length(layouts) - 1) * settings.separator_height;
height += g_slist_length(layouts) * settings.padding * 2; height += g_slist_length(layouts) * settings.padding * 2;
XResizeWindow(xctx.dpy, xctx.win, width, height);
cairo_t *c;
cairo_surface_t *image_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
c = cairo_create(image_surface);
x_win_move(width, height);
cairo_xlib_surface_set_size(cairo_ctx.surface, width, height); cairo_xlib_surface_set_size(cairo_ctx.surface, width, height);
cairo_set_source_rgb(c, frame_color.r, frame_color.g, frame_color.b); cairo_set_source_rgb(c, frame_color.r, frame_color.g, frame_color.b);
@ -376,11 +382,12 @@ void x_win_draw(void)
first = false; first = false;
} }
cairo_show_page(c); cairo_set_source_surface(cairo_ctx.context, image_surface, 0, 0);
cairo_paint(cairo_ctx.context);
x_win_move(width, height); cairo_show_page(cairo_ctx.context);
cairo_destroy(c); cairo_destroy(c);
cairo_surface_destroy(image_surface);
r_free_layouts(layouts); r_free_layouts(layouts);
} }
@ -404,18 +411,20 @@ static void x_win_move(int width, int height)
y = scr.dim.y + xctx.geometry.y; y = scr.dim.y + xctx.geometry.y;
} }
/* move and map window */ /* move and resize */
if (x != xctx.window_dim.x || y != xctx.window_dim.y if (x != xctx.window_dim.x || y != xctx.window_dim.y) {
|| width != xctx.window_dim.w || height != xctx.window_dim.h) {
XMoveWindow(xctx.dpy, xctx.win, x, y); XMoveWindow(xctx.dpy, xctx.win, x, y);
}
if (width != xctx.window_dim.w || height != xctx.window_dim.h) {
XResizeWindow(xctx.dpy, xctx.win, width, height);
}
xctx.window_dim.x = x; xctx.window_dim.x = x;
xctx.window_dim.y = y; xctx.window_dim.y = y;
xctx.window_dim.h = height; xctx.window_dim.h = height;
xctx.window_dim.w = width; xctx.window_dim.w = width;
} }
}
void setopacity(Window win, unsigned long opacity) void setopacity(Window win, unsigned long opacity)