Double Buffering

I have started looking at the code and did not quite understand what I
found:

backends/backend_gtk.py has a class FigureCanvasGTK. Its method
'expose_event' is responsible for redrawing.
In the situation I described, when I leave an opened menu that overlaps
the graph, the expose_event is properly called, but the widget is not
redrawn. If DBL_BUFFER is set (which it is), the widget is only redrawn,
if self._draw_pixmap is set to True.

Thats not true, see below.

Of course, this variable is not set
to True when GTK closes a menu but only when matplotlib requests a
redraw. So, in conclusion, no redraw happens.

After consulting the PyGTK reference I tried to reactivate double
buffering, which is turned of in the backend_gtk.py by the command

self.set_double_buffered(False)

I wonder why you set this? Do you want to provide your own double
buffering? Why? If you set this value to True, everything will be fine.

Best regards,

Niklas Volbers.

Why do we have self.set_double_buffered(False)?
Its been that way for as long as I can remember, I think John wrote the
original code, he may remember the actual reasons.

My guess is because of printing. backend_gtk has two basic functions -
to plot to the display and to plot to a file. If you
set_double_buffered(False) you can draw to a Pixmap and use the pixmap
to draw to both the screen and to a jpg or png file.
If you draw direct to a gdk.Window you can only save to a file if the
gdk.Window is mapped; if the window is minimised or not yet realized the
print will fail. The 'savefig()' command would not work if called before
'show()'.

expose-events:
If the window is resized or draw() is called self._draw_pixmap is set to
True and the whole figure is redrawn to the Pixmap.
self.window.set_back_pixmap() is then called to set the window
background to the Pixmap. Then if an expose event occurs, without the
window being resized or draw() being called, matplotlib does not need to
do anything. GTK+ handles it for us by automatically filling an exposed
window with its background, which is our plot.

This is how it works for GTK+/PyGTK 2.4. However, something changed in
2.6 and it no longer always draws the widgets background. I think this
is a bug, however after rereading the gdk_window_set_back_pixmap()
manual page I notice it says:
"The windowing system will normally fill a window with its background
when the window is obscured then exposed, and when you call
gdk_window_clear()"

What is "normally" supposed to mean? It not something you can rely on,
so it may just as well be "never". I think that the documentation is
unclear and opened a documentation bug report
http://bugzilla.gnome.org/show_bug.cgi?id=306214

I also found a bug report very similar to the problem experienced in
matplotlib
http://bugzilla.gnome.org/show_bug.cgi?id=161561
its been resolved as 'fixed', so GTK+ 2.6.1 (with the fix applied) may
work OK, and it may just have been a 2.6.0 problem.

Regards,
Steve

Send instant messages to your online friends http://au.messenger.yahoo.com

···

On Wed, 2005-06-01 at 05:12 -0700, matplotlib-users- request@lists.sourceforge.net wrote:

Steve, thanks for your long reply. I think I know understand the way it works.

Steve Chaplin schrieb:

[...] expose-events:
If the window is resized or draw() is called self._draw_pixmap is set to
True and the whole figure is redrawn to the Pixmap.
self.window.set_back_pixmap() is then called to set the window
background to the Pixmap. Then if an expose event occurs, without the
window being resized or draw() being called, matplotlib does not need to
do anything. GTK+ handles it for us by automatically filling an exposed
window with its background, which is our plot.

This is how it works for GTK+/PyGTK 2.4. However, something changed in
2.6 and it no longer always draws the widgets background. I think this
is a bug, however after rereading the gdk_window_set_back_pixmap()
manual page I notice it says:
"The windowing system will normally fill a window with its background
when the window is obscured then exposed, and when you call
gdk_window_clear()"

I read that part too, but didn not quite understand it before you explained the part about set_back_pixmap().

What is "normally" supposed to mean? It not something you can rely on,
so it may just as well be "never". I think that the documentation is
unclear and opened a documentation bug report
Bug 306214 – gdk_window_set_back_pixmap() has confusing documentation

I also found a bug report very similar to the problem experienced in
matplotlib
Bug 161561 – GtkWindow subclass not automatically repainting style->bg_pixmap
its been resolved as 'fixed', so GTK+ 2.6.1 (with the fix applied) may
work OK, and it may just have been a 2.6.0 problem.

Hmmm. The buggy behaviour I noticed was on a machine running pygtk 2.6.1 and gtk+-2.6.4, so I am not so sure if it was a 2.6.0 problem.

Niklas Volbers.