[comp.windows.x] Toolkit geometry management

bilbo.geoff@SEAS.UCLA.EDU (Geoff Kuenning) (11/12/87)

Marcel Meth brings up several important issues related to geometry
management.  I have run into a similar difficulty, which I
would like to see addressed in any suggested solution.

The problem I have run into deals with initial window sizing.  If the
user invokes my application with a geometry string, I'd like to
obey that.  The geometry string controls the sizing of TopLevel,
so I'd like to make everything else fit within those confines.  This
isn't too hard, since the code already exists in my resize routine.
But it does require some method of discovering that said code needs
to be executed.

However, if the user doesn't specify a geometry string, I'd like my
application to autosize, possibly depending on the data (for example,
an image-processing utility would want to make an image window of
appropriate size, then make TopLevel slightly larger to allow room for
the other widgets that control the application.  In this case, each
widget (starting at TopLevel) needs to ask each of its subwidgets for
a preferred size and then calculate a preferred size of its own.

An easy way to do this would be to add a new routine to the widget
class structure, the PreferredSize routine.

	typedef XtGeometryResult (*XtPreferredSize)();
	    Widget w;
	    XtWidgetGeometry *constraint;
	    XtWidgetGeometry *reply;
	    Boolean do_resize;

The constraint argument would give any limitations the parent widget chooses
to place on the child's geometry (for example, TopLevel might choose to
limit children to the size of the screen).  If a given constraint is
unspecified (or for width, height, or border_width, zero), then the child
is unconstrained.  (Note that these constraints have nothing to do with
constrained widgets).

The PreferredSize routine would never return XtGeometryAlmost, and it
would return XtGeometryNo only if it could not live within the constraints.
If the PreferredSize routine returns XtGeometryNo, it must nevertheless
store a valid geometry that satisfies the constraints into "reply", so
that the caller can choose to ignore the XtGeometryNo result.

If the do_resize argument is nonzero, the PreferredSize routine should
finish by making an XtGeometryRequest to achieve the desired size.

When TopLevel is realized, it can then check to see whether a geometry
string was specified.  If so, it can call the Resize routines for its
children to force them into that size.  If not, it can call the
PreferredSize routines and then size itself to match.

A small related issue here is the problem of doing operations on unrealized
widgets.  For example, I use popup scroll bars.  Before I pop them up, I
want to set the thumb using XtScrollbarSetThumb.  However, this routine
only works after the widget is realized, which also requires it to be
managed.  So I'd have to clear mapped_when_managed, manage it (to realize
it), set the thumb, and then set mapped_when_managed to map it (actually,
that part's not implemented yet...).  Instead, I modified PaintThumb so
that it works on an unrealized scrollbar.

I think widget writers need to be very careful to make it possible for
various operations to be carried out on unrealized widgets.  Special care
should be given to the SetValues and GetValues procedures, as well as
any "extra" procedures exported to the user.  It is frequently necessary
to fiddle around with widgets before realizing them, so that you can
get the geometry and parameters exactly correct.  If you make appropriate
XtIsRealized() calls in the right places, you will make your widget much
easier to use.

	Geoff Kuenning	geoff@lcc.ucla.edu	geoff@ITcorp.com