Re: Gtkmm widgets don't always update...



On Wed, 2008-01-16 at 14:47 -0800, rob wrote:

> 
> The function I use to invalidate the widget from the producer thread is:
> 
>         void invalidate()
>         {
>                 gdk_threads_enter();
>                 Gdk::Rectangle rect = get_allocation();
>                 get_window()->invalidate_rect(rect, false);
>                 gdk_flush();
>                 gdk_threads_leave();
>         }

this shows an incorrect understanding of how a toolkit like GTK actually
draws.

when there are events to handle, they are all dispatched. the handler
calltree for each event stands a good chance of invalidating some part
of the window(s) owned by the app.

once the events have all been dispatched, there is a GTK idle handler
which then calls gdk_window_process_all_updates(). this finds all GDK
windows that have had some area invalidated, and invokes
gdk_window_process_updates() on each one, which in turn causes the
delivery of expose events to the window. in the expose event handler,
the window (or the invalidated portion of it) will be redrawn to show
the new content.

the last part of the puzzle is how the redrawn pixels actually get to
the screen. in the case of the X11 backend, this process is
asynchronous, because it involves sending draw requests to the server.
they will show up on screen some time after the request is sent. for
other backends, things are done in a more synchronous fashion - none of
the redraws will appear on screen until the next vertical sync trace
starts, for example.

your call to gdk_flush() does nothing relevant - it simply tells GDK to
make sure that all X11 requests have been sent to the server. but the
invalidate_rect() call didn't cause any X11 requests to be sent. it just
put the window into the update list. the window will not be redrawn
until the global GTK idle update routine kicks in.

there is one way around this cycle of events, and its used by a few
stock GTK widgets. you can call gdk_window_process_updates() yourself
when you want the expose events to be delivered right now (thus ensuring
a reasonable chance the the screen display will change very soon).

note that code that tries to circumvent the usual update cycle is
subject to potentially different behaviour with different GTK/GDK
backends.

--p




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