[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[platform-swt-dev] SWT/GTK and Gnome Summit
|
Eclipse 2.0 shipped on June 28, 2002 - with GTK listed as officially fully
supported.
SWT/GTK port has come a long way since it started in 2001. Many issues
were solved and of course there are still issues to be solved. Since next
week is the Gnome Summit conference, here are some thoughts about SWT and
GTK that if addressed would really make this port a first class SWT port.
In this post, we will explain what state the SWT/GTK port is in, what
difficulties we had on our way to R2.0, what needs to be done, and what we
would wish were in GTK that would have made the port easier. Our order of
explanation will be more historical than structural.
When we started working on porting SWT to GTK in 2001, the SWT API was
mostly defined, and there existed good implementations for Windows and
Linux/Motif. Therefore, the design of the toolkit was clear, and the
general idea about how to do another port was there. There was very
little or no room for SWT API adaptation to what GTK provided.
A look at the GTK API (then 1.2) soon revealed several hard problems.
The first question was, how the relationship of SWT Composite with Child
should map to GTK Container / Child. SWT provides direct control over
positioning and sizing of widgets, and it is the widget who manages itself
- in contrast to GTK where the container, not the child, has all the
knowledge about the child's geometry. The composite layouts in SWT are
just regular Java code manipulating this child geometry.
At first sight, this is no problem. We could create a custom GTK
container - a "real fixed" or "null layout", and delegate the child's
geometry operations to the parent widget. This would also solve the
problem with the synchronous nature of setLocation/setSize in SWT. We
could then say that the null layout is equivalent to having direct control
over widgets' geometry.
Unfortunately, this does not work in the general case. There exist cases
where application code needs to know details like the "client area" (for
example, the contents of a scrolled window not including the trim or
scroll bars) of a Composite. Another example is a TabFolder "t", child of
a parent Composite "p". The application code sets the size of
t.setSize(100, 100), and immediately wants to t.getClientArea() in order
to position a child page. The GtkNotebook is not resized at this point;
all t.setSize() did was put the size into the "child sizes" data structure
in "p". Therefore, we can not just get the client area from the notebook;
the only way to calculate it from the total size, would be to follow the
corresponding logic in GtkNotebook, but this code is not exposed through
the GTK API. We realize that a GTK application would allow GTK to
position the child page and while SWT supports automatically positioning
the child page, it is also possible to position the page through
application code or have exactly one page that corrresponds to many tabs.
An SWT TabFolder is a Composite and can have arbitrary children positioned
in arbitrary places.
The only way we saw to overcome this difficulty, was to resize the widgets
directly, and prevent the parent from messing with the size, by
set_usize(). This, however, destroys the widget's native requisition,
which in some cases we use for computeSize(), the SWT API that is used to
determine the preferred size of a widget. To fix this, we sometimes wrap
the widget in a bin, and set_usize() on that outer bin. In other cases
this doesn't matter as the GTK concept of preferred size is different than
the SWT one.
Isn't it too expensive to wrap widgets? It might be but we need to do it
anyways for other reasons. In SWT, in contrast to GTK, *all* widgets
receive input events. The only way we see to achieve this is to put an
event box behind the widget. The alternative way of propagating events to
the children would mean rewriting a large chunk of the toolkit's
functionality - but there are even more important reasons why it would do
no good. The worst problem is clipping. unfortunately, the lightweight
doctrine is not exercised consistently in GTK. Some leaf widgets may be
heavyweight when their parent container is lightweight. This means the
container will not guarantee correct clipping of children unless it has an
X window.
Another problem is overlapping and z-order. Overlapping widgets are very
common in Eclipse. Several Eclipse UI features are implemented by
shuffling the z-order of things (e.g., switching perspectives). Obviously,
this is not the UI style GTK creators had in mind. Widgets in a typical
GTK app never overlap. GTK does not provide facilities to directly
control the z-order. We solve this by having an X window with every
widget's "top handle", and calling X directly to control the z-order.
Another reason to have a GdkWindow is that every widget in SWT is a
drawable.
Of course, this makes for a lot of ugliness. On pixbuf themes, the fake
handles will show through the transparent widgets. This spoils the look
of the theme. Moving around many X windows on every resize also might be
making things "jumpy".
There were many minor problems that we will not discuss all. For example,
the difference between event semantics in GTK and SWT. SWT has a specific
set of rules when application sees events such as selection change, or
text modify. In general, but not always, if an event is programmatically
caused, there is no call back from SWT. We had to carefully block the
signal in these cases. Some of these things are just API incompatibilites
and SWT just addressed them.
There are several areas that just need work. In R2.0, we are still using
the deprecated GtkText, GtkClist, and GtkCTree. There are deprecated
calls that we need to get rid of.
SWT team