From 8178910f168c927f1f3b4c94531fd32f38743fb0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ingo=20B=C3=BCrk?= Date: Wed, 14 Oct 2015 18:57:16 +0200 Subject: [PATCH] Introduce a macro to flush a cairo surface twice. Flushing the surface twice is necessary due to a cairo bug. For context, refer to #1989 and https://bugs.freedesktop.org/show_bug.cgi?id=92455. --- i3bar/include/cairo_util.h | 8 ++++++++ i3bar/src/cairo_util.c | 8 ++++---- i3bar/src/xcb.c | 4 ++-- libi3/font.c | 3 +++ 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/i3bar/include/cairo_util.h b/i3bar/include/cairo_util.h index 37eaa6e2..3e4ebec4 100644 --- a/i3bar/include/cairo_util.h +++ b/i3bar/include/cairo_util.h @@ -10,6 +10,14 @@ #include +/* We need to flush cairo surfaces twice to avoid an assertion bug. See #1989 + * and https://bugs.freedesktop.org/show_bug.cgi?id=92455. */ +#define CAIRO_SURFACE_FLUSH(surface) \ + do { \ + cairo_surface_flush(surface); \ + cairo_surface_flush(surface); \ + } while (0) + /* Represents a color split by color channel. */ typedef struct color_t { double red; diff --git a/i3bar/src/cairo_util.c b/i3bar/src/cairo_util.c index 6a2ed0ac..98c129b9 100644 --- a/i3bar/src/cairo_util.c +++ b/i3bar/src/cairo_util.c @@ -79,7 +79,7 @@ void cairo_set_source_color(surface_t *surface, color_t color) { */ void cairo_draw_text(i3String *text, surface_t *surface, color_t fg_color, color_t bg_color, int x, int y, int max_width) { /* Flush any changes before we draw the text as this might use XCB directly. */ - cairo_surface_flush(surface->surface); + CAIRO_SURFACE_FLUSH(surface->surface); set_font_colors(surface->gc, fg_color.colorpixel, bg_color.colorpixel); draw_text(text, surface->id, surface->gc, visual_type, x, y, max_width); @@ -109,7 +109,7 @@ void cairo_draw_rectangle(surface_t *surface, color_t color, double x, double y, /* Make sure we flush the surface for any text drawing operations that could follow. * Since we support drawing text via XCB, we need this. */ - cairo_surface_flush(surface->surface); + CAIRO_SURFACE_FLUSH(surface->surface); cairo_restore(surface->cr); } @@ -134,7 +134,7 @@ void cairo_copy_surface(surface_t *src, surface_t *dest, double src_x, double sr /* Make sure we flush the surface for any text drawing operations that could follow. * Since we support drawing text via XCB, we need this. */ - cairo_surface_flush(src->surface); - cairo_surface_flush(dest->surface); + CAIRO_SURFACE_FLUSH(src->surface); + CAIRO_SURFACE_FLUSH(dest->surface); cairo_restore(dest->cr); } diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c index ac9b50f9..aa7b816c 100644 --- a/i3bar/src/xcb.c +++ b/i3bar/src/xcb.c @@ -248,7 +248,7 @@ void refresh_statusline(bool use_short_text) { cairo_set_source_color(&statusline_surface, colors.bar_bg); cairo_set_operator(statusline_surface.cr, CAIRO_OPERATOR_SOURCE); cairo_paint(statusline_surface.cr); - cairo_surface_flush(statusline_surface.surface); + CAIRO_SURFACE_FLUSH(statusline_surface.surface); cairo_restore(statusline_surface.cr); /* Draw the text of each block. */ @@ -1801,7 +1801,7 @@ void draw_bars(bool unhide) { cairo_set_source_color(&(outputs_walk->buffer), colors.bar_bg); cairo_set_operator(outputs_walk->buffer.cr, CAIRO_OPERATOR_SOURCE); cairo_paint(outputs_walk->buffer.cr); - cairo_surface_flush(outputs_walk->buffer.surface); + CAIRO_SURFACE_FLUSH(outputs_walk->buffer.surface); cairo_restore(outputs_walk->buffer.cr); if (!config.disable_ws) { diff --git a/libi3/font.c b/libi3/font.c index b578bf8b..c1e95a9e 100644 --- a/libi3/font.c +++ b/libi3/font.c @@ -133,6 +133,9 @@ static void draw_text_pango(const char *text, size_t text_len, cairo_move_to(cr, x, y - yoffset); pango_cairo_show_layout(cr, layout); + /* We need to flush cairo surfaces twice to avoid an assertion bug. See #1989 + * and https://bugs.freedesktop.org/show_bug.cgi?id=92455. */ + cairo_surface_flush(surface); cairo_surface_flush(surface); /* Free resources */ -- 2.39.2