Skip to main content

[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


Back to the top