[Gtk-sharp-list] DrawingArea flickering - how to stop erasing background

eskimobob martin at berriman.co.uk
Wed Jun 13 12:20:24 UTC 2012


I've searched and searched on DoubleBuffering with Gdk# but am still stuck...
I'm writing a test linux app in Monodevelop using Gdk# and Cairo.
I have on my form a DrawingArea widget onto which I draw.

In order to avoid flickering, I am creating a Cairo.ImageSurface where I do
the actual drawing.  This is then painted onto the DrawingArea during the
Expose event handler.

I am finding that it is flickering badly but fail to understand why.  In a
previous app on Windows, I had a similar problem because Windows tries to
erase the background before each paint.  Since I am painting the entire
image from memory, there is no need to erase first.  This was solved by
handling the WM_ERASEBKGND message - i.e. intercept the message and ignore
it so that the attempted erase does not occur.

It seems likely that the same thing is happening here (automatic erase
before my paint) however I don't know how to stop it.

I've included example code below (although can't see any way to use code
tags) and would appreciate any suggestions.

	private Cairo.ImageSurface viewSurface; //surface used to double buffer
drawing to prevent flicker
	private System.Timers.Timer timer;		//used to cause a redraw

	public MainWindow (): base (Gtk.WindowType.Toplevel)
	{
		Build ();
		timer = new System.Timers.Timer(10);
		timer.Enabled = false;
		timer.Elapsed += HandleTimerElapsed;
	}

	void HandleTimerElapsed (object sender, System.Timers.ElapsedEventArgs e)
	{
		UpdateViewSurface();
		mainDrawingArea.QueueDraw();
	}

	protected void eDrawingAreaConfigure (object o, Gtk.ConfigureEventArgs
args)
	{
		//we get here we we have a resize event
		//create our sufrace in memory for later use
		viewSurface = new ImageSurface(Format.ARGB32,
mainDrawingArea.Allocation.Width, mainDrawingArea.Allocation.Height);
	}

	protected void eDrawingAreaExpose (object sender, Gtk.ExposeEventArgs args)
	{
		//we get here when we need to redraw the screen
		DrawingArea viewArea = (DrawingArea)sender;
		using (Context cr = Gdk.CairoHelper.Create(viewArea.GdkWindow))
		{
			cr.SetSourceSurface(viewSurface, 0, 0);
			cr.Paint();
		}
	}

	private void UpdateViewSurface()
	{		
		//whenever we want
		//draw onto our surface in memory
		//white background with a blue circle which has a red border
		using (Context cr = new Context(viewSurface))
		{
			int width, height;
			width = Allocation.Width;
			height = Allocation.Height;

			cr.Rectangle(0, 0, width, height);
			cr.SetSourceRGB(1, 1, 1);
			cr.Fill();
			
			cr.LineWidth = 9;
			cr.SetSourceRGB(1, 0, 0);
					
			cr.Translate(width/2, height/2);
			cr.Arc(0, 0, (width < height ? width : height) / 2 - 10, 0, 2*Math.PI);
			cr.StrokePreserve();
			
			cr.SetSourceRGB(0, 0, 1);
			cr.Fill();
		}
	}

--
View this message in context: http://mono.1490590.n4.nabble.com/DrawingArea-flickering-how-to-stop-erasing-background-tp4649911.html
Sent from the Mono - Gtk# mailing list archive at Nabble.com.


More information about the Gtk-sharp-list mailing list