[cairo] Strange values of cairo_xlib_surface_get_width
otte at redhat.com
Wed Jul 7 06:31:45 PDT 2010
What you're seeing here is a GTK feature. GTK does not hand you a Cairo
surface made for the current widget, but applies some sophistication.
Some I do remember (there's probably more):
1) There is double buffering going on. To avoid flicker, GTK creates a
Pixmap and causes all rendering to happen on that Pixmap. Then it does a
single blit of the pixmap to the X window. The Pixmap will only be as
big as the area that needs to be redrawn. This explains why the surface
may be smaller than your allocation.
2) Some GTK widgets are NOWINDOW widgets and reuse the parent's
GdkWindow. This explains why the surface may be bigger than your
3) Since GTK 2.20, so called "client side windows" exist in GTK. These
are GdkWindows that aren't backed by an Xlib window. They instead reuse
the parent's Xlib window when drawing. This also explains why the
surface may be bigger than your allocation.
In short: Do not rely on the target surface's size for anything.
On Wed, 2010-07-07 at 11:32 +0200, Stefan Salewski wrote:
> I have just started working on my first non trivial GTK+/Cairo program.
> (picture of early draft of GUI: http://www.ssalewski.de/tmp/GUI.png )
> My code is mainly based on the examples from A.Krauses GTK book, the
> http://zetcode.com/tutorials/cairographicstutorial/ and other web
> One of my task was to find the size of the GTK drawing area, which is
> used for cairo drawing.
> My first attempt was using
> cairo_xlib_surface_get_width (surface)
> which I found in an example in the web.
> But that gave me sometimes strange results, while
> widget->allocation.width seems to work fine.
> I was going to just ignore this problem, but now I decided to search for
> an explanation -- to understand the problem and to avoid similar
> problems in future. So I stripped down my code to this example:
> cairosurfacewidth = widget->allocation.width;
> cairosurfaceheight = widget->allocation.height;
> cr = gdk_cairo_create (widget->window);
> surface = cairo_get_target (cr);
> if (cairo_surface_get_type (surface) != CAIRO_SURFACE_TYPE_XLIB)
> g_print("we have problems\n");
> cairowidthfromsurface = cairo_xlib_surface_get_width (surface);
> cairoheightfromsurface = cairo_xlib_surface_get_height (surface);
> g_print("widget->allocation: %d %d ",cairosurfacewidth, cairosurfaceheight);
> g_print("cairo_xlib_surface_get: %d %d\n",cairowidthfromsurface, cairoheightfromsurface);
> Output looks like
> stefan at AMD64X2 ~/cairobug $ gcc -o test `pkg-config --cflags --libs gtk+-2.0` main.c
> stefan at AMD64X2 ~/cairobug $ ./test
> widget->allocation: 100 100 cairo_xlib_surface_get: 182 110
> widget->allocation: 101 101 cairo_xlib_surface_get: 183 111
> widget->allocation: 101 102 cairo_xlib_surface_get: 183 107
> widget->allocation: 108 248 cairo_xlib_surface_get: 197 253
> widget->allocation: 109 248 cairo_xlib_surface_get: 114 258
> widget->allocation: 109 249 cairo_xlib_surface_get: 200 259
> widget->allocation: 110 249 cairo_xlib_surface_get: 115 259
> widget->allocation: 111 249 cairo_xlib_surface_get: 116 259
> widget->allocation: 111 250 cairo_xlib_surface_get: 204 260
> widget->allocation: 112 250 cairo_xlib_surface_get: 117 260
> widget->allocation: 111 250 cairo_xlib_surface_get: 112 250
> While the height (second value each) seems to be not too wrong, the
> width result of cairo_xlib_surface_get_width makes very strange output,
> with jumping values.
> This is on a 64 bit AMD dual core box with Gentoo-Linux,
> stefan at AMD64X2 ~ $ emerge -pv gtk+ cairo
> x11-libs/gtk+-2.18.9 USE="cups jpeg jpeg2k tiff (-aqua) -debug -doc -test -vim-syntax -xinerama" 17,769 kB
> x11-libs/cairo-1.8.8 USE="X opengl svg (-aqua) -cleartype -debug -directfb -doc -glitz -xcb" 6,491 kB
> gcc version 4.4.4
> Best regards
> Stefan Salewski
> cairo mailing list
> cairo at cairographics.org
More information about the cairo