Re: map/unmap optimization




Patrice Fortier <Patrice.Fortier@aquarel.fr> writes:

> > GtkFrame is a NU_WINDOW widget, and thus it is supposed to draw
> > into its parent's window.
> 
> Yes, and my question is why?
> Why does a large, _container_ widget such as the *frame widgets
> draw on their parent widgets? (except "it is a NO_WINDOW widget" :))
> 
> The main reason for this behaviour is the overhead created by the
> (main) window of the widget. This may be critical when you need 
> to create/handle a _lot_ of small widgets (say 10000) like 
> the entries of a list widget.
> For this reason, some wigets sets use gadgets, which are just the
> same a the widgets, but without the (X) window. Some other widget
> sets create special widgets which handle their own children (entries
> in our case), gtkclist comes to mind.
> 
> In the current version (1.0), we have both cases. So we need to 
> handle them both, and so we get the drawbacks of both solutions.
> 
>  - We need to handle each widget/child as if it _could_ be a
>    NO_WINDOW widget.

>  - Jay had to create the clist widget to get an efficient list 
>    widget (id for ctree). Now we have 2 list widgets:
>    gtklist and gtkclist.

It's hard to get around this. We could (will) reduce the need for
GtkList even further by adding a "widget" cell type to GtkCList,
but GtkCList restricts flexibility in order to get performance,
GtkList permits ultimate flexibility, as long as you accept
size and performance limitations.

>  - We have a bad designed widget set for X wondow handling (even
>    the Athena widgets have a main window - critical widgets like
>    entries have _also_ a gadget version).

How is GTK+ "badly designed for X window handling" ?
 
> Gtk is the only toolkit I know that considers that it is normal 
> for its widgets to write on other widgets (even for containers
> like frame widgets).
> Do I need to say that the Athena work on a 386 or a sparc 1?

 - Xaw doesn't draw much.
 - Xaw doesn't provide nearly as power much for the application
 - As I understood it, Xaw manages geometry in a way that is fairly
   close to the way X handles windows - so it can take advantage
   of the "window gravity" to make things draw better. But it's
   geometry management is pretty poor from the point of view
   of the programmer.

Just saying that Athena works on crufty old machines doesn't
convince me much. There are clearly reasons why you are
using GTK+, not Athena. ;-)

Now if we could somehow use more windows, and use that to save
drawing, that would be good. But I don't think merely using
more windows helps any. You have to keep track of everything
that changes with geometry to know whether you need to redraw
a particular window or not. That can get very complicated.

> Another point is that for the theming stuff, Raster will need
> a window for the *frame widgets. At least he'll find it _very_
> useful :).
 
Actually, raster has figured out how to deal with NO_WINDOW widgets
quite well and actually take advantage of it to some extent.

Note that there is a an important thing _other than efficiency_
that NO_WINDOW widgets allow - they allow layered drawing.
So a widget can draw something complicated, put various GtkLabel
widgets on top, and have it all be drawn correctly.
 
> Here are some ideas, some should be done, and some other are
> just food for thoughts (as they won't please everybody) :)
> 
>  - Big container widget that draw on other widgets (ie: parents)
>    should draw in their own window.
>    The overhead induced by this new window is peanuts, and this
>    is _much_ cleaner.
>    I think *frames are the only ones, but I'm not sure...

Why is this cleaner? If you know how to draw little widgets 
in their parent's windows, you know how to draw big widgets
in their parent's windows.
 
>  - next step: all the container should have their own window
>    (*box...). this is food for thoughts, don't flame :).
>    The overhead created by the window structure, should not
>    be important, no expose event is generated by these
>    widgets, and this should allow us to get rid of the 3/4 of
>    if (NO_WINDOW(xxx)) thing (like expose events, un/map events...).
>    The code should be much clean and maybe faster.

But aren't the cases for NO_WINDOW() widget's in expose() handlers
covering the case where the children are no-window.
 
>  - think about the simple widgets (widget/gadget thing) to 
>    find a clean and effcient solution.
 
First, prove that the current solution is bad. Then when trying
to find something better, keep in mind:

 - Any solution that requires a GtkObject for each "simple widget"
   in a spreadsheet or GtkCTree/GtkCList widget is going to 
   be inefficient.

> BTW, what is the advantage of using gtkpixmap instead of gdkpixmap?
 
It handles exposes itself. 
 
> Back on the map/unmap stuff
> > also it needs to unmap its child if
> > itself gets unmapped, because its child might be a !NO_WINDOW
> > widget.
> 
> Why?
> I mean, why do you need to unmap the child if it's a !NO_WINDOW
> widget? This case is handled by X, and the (X) map/unmap functions
> are here to handle this case. So why do we duplicate the work?

Well, in many places we don't duplicate the work - for instance:

 - The default GtkWidget handler
 - gtk_window_unmap
 - gtk_list_unmap

And, also, this is how it is described in docs/widget_system.txt

  The Unmap signal
  ----------------

  When a widget receives the unmap signal, it must:

   1) If the widget has a window, gdk_window_hide that window, 
   2) If the widget does not have a window, unmap all child widgets
   3) Do any other functions related to taking the widget offscreen
     (for instance, removing popup windows...)
   4) Unset GTK_MAPPED

> Maybe there is a reason for this duplication, but I just can't
> see what it is.

Neither do I. Feel free to track down places where we unmap
children unnecessarily and submit patches.

Regards,
                                        Owen



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