I have a helper function
to take screenshots of GtkWindows during unit-tests (that run on xvfb). I used those to e.g update the docs for a release. This has been working fine for years, but is failing since a while with:
./../../../src/cairo-surface.c:1734: cairo_surface_mark_dirty_rectangle: Assertion
! _cairo_surface_has_mime
_data (surface)’ failed`.
Here is a backtrace:
2 0x00007ffff041177f in __assert_fail_base (fmt=0x7ffff0573bc0 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=0x7ffff196f2c0 "! _cairo_surface_has_mime_data (surface)", file=0x7ffff196f130 "../../../../src/cairo-surface.c", line=1734, function=0x7ffff196f620 "cairo_surface_mark_dirty_rectangle") at assert.c:92
#3 0x00007ffff041f542 in __GI___assert_fail (assertion=0x7ffff196f2c0 "! _cairo_surface_has_mime_data (surface)", file=0x7ffff196f130 "../../../../src/cairo-surface.c", line=1734, function=0x7ffff196f620 "cairo_surface_mark_dirty_rectangle") at assert.c:101
#4 0x00007ffff190061f in cairo_surface_mark_dirty_rectangle () at /usr/lib/x86_64-linux-gnu/libcairo.so.2
#5 0x00007ffff1901645 in cairo_surface_mark_dirty () at /usr/lib/x86_64-linux-gnu/libcairo.so.2
#6 0x00007ffff1e7459c in gdk_pixbuf_get_from_window () at /usr/lib/x86_64-linux-gnu/libgdk-3.so.0
#7 0x00005555555ef547 in make_screenshot (widget=widget@entry=0x555555e93100) at tests/bt-check-ui.c:358
#8 0x00005555555ef5ba in check_make_widget_screenshot (widget=0x555555e93100, name=0x5555555f7425 "mono-source")
at tests/bt-check-ui.c:458
#9 0x000055555557ea52 in test_bt_machine_properties_dialog_create (_i=<optimized out>)
which is suggesting that a call to cairo_surface_flush
would help. This makes my make_screenshot
helper work again, but it looks overly complicated, right?:
const cairo_rectangle_int_t c_rect = {0, 0, ww, wh };
cairo_region_t *c_region = cairo_region_create_rectangle (&c_rect);
if (c_region) {
GdkDrawingContext *dc = gdk_window_begin_draw_frame (window, c_region);
if (dc) {
cairo_t *cr = gdk_drawing_context_get_cairo_context (dc);
cairo_surface_t *surface = cairo_get_target (cr);
cairo_surface_flush (surface);
gdk_window_end_draw_frame (window, dc);
} else {
LOG_WARNING ("failed to begin_draw_frame");
}
cairo_region_destroy (c_region);
} else {
LOG_WARNING ("failed to create cairo region");
}
Any better idea?