Re: to many invalidate_rect calls freezes window



On Wed, 20 May 2009 23:53:34 +0200
buergi <pat_buergi124 gmx de> wrote:
> Hello,
> 
> I'm developing an application with 2 threads: one worker thread and
> one which runs the GTK mainloop. The worker thread uses a sigc signal
> to move a cursor step by step over a DrawingArea in the main thread.
> The whole thing should simulate a XY plotter with stepper motors, thus
> the single step movements are important.
> 
> So i defined
> 	sigc::signal<void,STEP_DIRECTION> step_command;
> in the main thread and pass it to the worker thread and call it e.g.
> in a loop like
> 	for (int i=0;i<100;i++)	step_command(STEP_UP);
> 
> The new cursor position in the main thread gets set in
> 	void MainDrawArea::on_signal_step_command(STEP_DIRECTION dir)
> The cursor's region on the DrawingArea gets invalidated before and
> after the new cursor position gets set:
> 	Gdk::Rectangle rect(cursor.x-10,cursor.y-10,20,20);
> 	window->invalidate_rect(rect,false);
> 
> The cursor is drawn in the on_expose_event() method.
> 
> Everything works that far, but the cursor moves a bit slow.
> Seems this communication by sigc signal is not very efficient. I think
> i'll use asynchronous GTK's or sigcx's Dispatcher instead of sigc's
> signals. (better ideas are welcome, but single step movements are
> important)
> 
> The problem which i have is that although i called invalidate_rect the
> cursor gets redrawn only for a few steps and freezes then.
> But not only the cursor movement freezes, the whole window doesn't get
> redrawn any longer. Moving it out of the screen and back in creates
> ugly artifacts. Resizing the window or clicking a button redraws it
> correctly as expected.
> 
> I could solve the problem by using window->process_update(false);
> after the invalidate_rect call which makes the cursor being redrawn
> as expected.
> 
> Perhaps i filled the update area with to many rectangles, i've no idea
> why it doesn't work.
> Does anyone have an idea how to solve this problem without the
> process_update? Or what i'm actually more interested in is the reason
> why it doesn't work.

This might help:

http://library.gnome.org/devel/gdk/stable/gdk-Threads.html#gdk-Threads.description

Given that I know of no other commonly used graphical toolkit which
allows you to call drawing functions from a thread other than the main
GUI thread (which includes MS Windows and Qt), I never cease to be
surprised by those who assume that GTK+ permits it.  (In fact it does,
but only on Unix platforms and only if you use the GDK global lock.)

Rather than use the global lock it is better to use Glib::Dispatcher or
g_idle_add() to send events to the GUI thread's event loop.

Note that sigc slots/signals are just an encapsulation of a callback
mechanism.  slots execute in the thread which emits the signal. (The
same applies to GObject signals.)

Chris



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]