Using GHC 7.4.2 and GtkHs 0.12.4, on Win32 and Win64, this program takes more and more memory, consuming approximately 2Mb/sec on my machine. I am simply trying to make an animation using Gtk (this is why I invalidate the window so it gets redrawn immediately).
I tried to profile the memory usage with the RTS options, but this memory is not visible.
What is going on ?
import Graphics.UI.Gtk
main :: IO ()
main = do
initGUI
window <- windowNew
onDestroy window mainQuit
onExpose window (\_ -> widgetQueueDraw window >> return True)
widgetShowAll window
mainGUI
-- Edit: I am using the version of Gtk found here which happens to be 2.24.10
-- Edit2: So, using an external timer instead of requesting widgetQueueDraw
from the expose event fixes the problem. It will do for now, but I don't understand why. I have used this approach in several languages with several GUI framework (invalidating a GUI control in the paint event). Usually, calling the invalidate just sets a flag that gets read next time the GUI thread kicks in. It ends-up in the GUI thread redrawing the control each frame, but that is actually what I want here. It looks like a but in Gtk2Hs.
I think your program enters a circular loop. When the window receives the expose event (i.e. it is requested to redraw itself), you don't do any drawing. Instead you force it to redraw itself, which in turn emits an expose event, and so on. You must split the problem into two parts. You should set up a timer that calls a function that prepares the next step of the animation and calls widgetQueueDraw
to render the scene onto the window. The actual rendering should be made as a reaction to the window's expose event.