[gtk-devel] [long] Widgets vs Gadgets: Round 2

Owen Taylor wrote:


> >  - 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" ?

Ok, I read several times your message to understand what was
your problem with this kind of patches, and I hope I'll can
enlighten you on some historical points (although I'm not
very good in english).

X is an event driven system.
The key for event dispatching is the "window" type, which
can tell the programmer what event occured, and where
(and also when as X uses an event queue - list).
Note that the drawings are handled by the expose events
X is written in such a way that when you create an entity,
it needs a window, as a backbone, to exploit the X window
system in an efficient way (with, as usual some exceptions).

So, the "natural" way to create a widget set is to give each
widget its own window. 
As a side effect to the OOP of most of the widget sets, it is
considered a bad thing to do things (handling event, drawing...)
of a widget in another one window:
In a program is it the "good way" to modify an object (or module)
from another one? Of course not. At least you will allways avoid 
this case if you can.
This is the same thing with the widgets.

Try to avoid for a widget to mess witn an other one's internals
(window, events handling...) every time you can.

Of course it works even if you do so. You can do powerful things
with crappy internals. That's not a problem, but usually it
requires more work, and people looking at the internals of
your structures/objects/code will be disgusted/amazed :).

Now we have the problem of efficiency.

Usually it's not very interesting to have a well-written code that 
is inefficient. So we have to find find correct balancing between
well-written code and efficiency.
In our case, the efficiency problem is limited to speeeed.

What could be the problems of X:

 - window creation. When you have a _huge_ amount of wigdets
to create at the same time, it takes some time.
 - window/events overhead. When you have a _huge_ amount of
wigdets, you get big chunks of events.
 - events go through the network. Combine this with point 2.

As the Xlib is much more "low-level" than gtk, all the event
handling is much more efficient than the one of gtk.

As you can see, the problems are appearing when we have a
_lot_ of widgets.
To "solve" them we have to generate 1 event instead of 100
or 200. A list widget with 1000 entries comes to mind.

I'll add that when you look at the lists of window/no_window
widgets in gtk, you have:

 - simple widgets without window
 - simple widgets with window (I guess so, I can't check here).
 - containers with window that wouldn't draw on parent.
 - containers with window that would draw on parent.
 - containers without window that draw on parent.
 - containers without window that don't draw on parent.

And if you don't read closely the sources of all these widgets
you can't tell the reason for this...
And as there is no rules about this you have to behave as if
a widget could be anything in that list.

This is:
 1 - dirty.
 2 - inefficient (as a whole, even if it is in some special 
     cases like clist).

> > 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.

Xaw3d or neXtaw draw almost as much as gtk 1.0 (for the same king of 

>  - Xaw doesn't provide nearly as power much for the application

This not the point. 

>  - 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.

Dunno about this :).

> 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. ;-)

How can can you guess that? :).

> 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.

Even with NO_WINDOW widget you have to do that job, and it's
even more complicated as you need to treat both cases
(no_window AND !no_window).

> Actually, raster has figured out how to deal with NO_WINDOW widgets
> quite well and actually take advantage of it to some extent.

I guess you're talking about pixmap or label widgets, and 
considering raster's background, I was sure he would find 
some interesting optimizations with no_window widgets (this
is _not_ a critic) :).

> 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.

correct me but you're talking about efficiency :).

> > 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.

No, you don't look at it from the correct side.

Historically and as far as I can remember S&P were working on
X terminals (or very low-end stations) and their applications
(like gimp) were running on a distant server.

So when they built gtk, they did everything to reduce network
traffic. And the important thing to do in that case is to
avoid windows, so you avoid events trafic, but you need to
handle them yourself.

This is the reason why when we got 0.99.0 version the default
behaviour was to have NO_WINDOW widget (except when it was
not possible).

Now, tell me:

 - Do you plan to have a container widget which should have
1000+ *frames widgets children?
I remind that gtk*frame draw on their parent window.
 - same question with gtkbox.
There is _no_ event (except maybe un/map) for such a widget,
so the overhead is just the window structure.
 - same question with other big container widgets (I don't know
how to treat gtkalignement widget, as I don't have enough datas).

Also note that sometimes you have to draw on on widget, that wouldn't
need expose events if there was no no_window.
eg: the gtkfixed widget clears the area were it _could_ have  no_window


> First, prove that the current solution is bad. Then when trying
> to find something better, keep in mind:

see beginning.

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

I don't ask anything (yet :)) in the case of simple widget.
Besides, clist and ctree do have a window :).


>   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

so we  have to unmap all the children instead of this one, and worse,
this widget, which recieved the event, has to tell it to its children.

Well, this is a very long message,
cudos for the guys who reached the end :).


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