GNOME Bugzilla – Bug 607544
Print preview broken
Last modified: 2018-02-10 03:41:34 UTC
Print preview is broken in GTK (>= 2.18). Note that this has been known problem with Windows platform for a while but I've noticed that the print preview is now generally broken (the same code that used to work before on older distros, does not work on Fedora 12 (GTK v2.18.3) for example). In the attached sample, preview should draw one page painted in red color. With the newer GTK used, preview draws nothing. Callbacks for drawing are being correctly called.
Created attachment 151830 [details] Sample code
Confirmed here that the test case doesn't show anything in GTK+ 2.19.3
I confirm that this bug is present since the commit 3b6cf72f395b40c61a8eaddb6e56ff6869ef14cf (Move destroyed check to common code for gdk_window_get_origin & gdk_window_get_root_coords) in GTK+ 2.17.3. This may have nothing to do with the printing subsystem.
The comment above is wrong, please ignore it, sorry, I was lost in the forest of the commit trees. In fact, the bug has appeared long time before and probably in the client-side-windows branch. The earilest buggy commit I have identified is eabac453e652d5aa2e535d957057f9c84803eea9 (Initial client-side-windows work), too large to analyze it. What I have found previously was soon after the merge of the client-side-windows and the master branch.
The problem is that we're passing a cairo_t from the preview widget window to gtk_print_context_set_cairo_context(). This is problematic with csw for the usual reasons (doesn't keep the clip region uptodate wrt window show/move/resize). So it doesn't work. In you example, if you move calling gtk_print_context_set_cairo_context() to after having showed the window things will sort of work, until the window size changes. We can probably fix this by hooking into e.g. gtkprintoperation.c:preview_iface_render_page() and calling gdk_cairo_reset there, but i'm not sure how we can get the target gdk drawable that we're drawing too. We probably can do it with some hack. However, and worse, this API means you can't ever do double buffered drawing on preview, because the cairo_t for the window is gotten before the expose event is called.
OK, I confirm that inside draw_page function in Miroslav's example: - with the old GTK the clipping region of the cairo_t contains one rectangle and its size matches the current size of the drawing area and updates correctly as the window is resized; - with the new GTK (with offscreen windows) the clipping region has no rectangles and reports its extents size 0x0; - if I call gdk_cairo_reset inside the draw_page then the clipping area matches the visible part of the drawing area (while previously it matched the whole widget) and the red rectangle draws almost correctly: unfortunately it also draws on the top and left edge of its surrounding frame. So what is the current solution? Should the clipping region be updated whenever the widget is shown/moved/resized/exposed and match its visible area or should the clipping region be unlimited (reset) and let the application draw on whole area of its offscreen pixmap and only the embedder will cut the required part of the image? What if the widget is partially obscured with other widgets? What if the application calls gdk_cairo_reset while drawing and gets the ability to draw outside the widget?
Still valid in current master
I made this work in the print-editor test in the gtk sources like this: http://git.gnome.org/browse/gtk+/commit/?id=c88ccc632a40142b0967fa051d893f575bdd7070
Thanks, I can confirm that your sample shows the preview.
We're moving to gitlab! As part of this move, we are closing bugs that haven't seen activity in more than 5 years. If this issue is still imporant to you and still relevant with GTK+ 3.22 or master, please consider creating a gitlab issue for it.