2.12. Child Geometry Management: the geometry_manager Procedure   

The geometry_manager procedure pointer in a composite widget class is of type XtGeometryHandler.

typedef XtGeometryResult (*XtGeometryHandler)(Widget, XtWidgetGeometry*, XtWidgetGeometry*);
Widget w;
XtWidgetGeometry *request;
XtWidgetGeometry *geometry_return;
w Passes the widget making the request.
request Passes the new geometry the child desires.
geometry_return Passes a geometry structure in which the geometry manager may store a compromise.
A class can inherit its superclass's geometry manager during class initialization.

A bit set to zero in the request's request_mode field means that the child widget does not care about the value of the corresponding field, so the geometry manager can change this field as it wishes. A bit set to 1 means that the child wants that geometry element changed to the value in the corresponding field.

If the geometry manager can satisfy all changes requested and if XtCWQueryOnly is not specified, it updates the widget's x, y, width, height, and border_width fields appropriately. Then, it returns XtGeometryYes, and the values pointed to by the geometry_return argument are undefined. The widget's window is moved and resized automatically by XtMakeGeometryRequest.

Homogeneous composite widgets often find it convenient to treat the widget making the request the same as any other widget, including reconfiguring it using XtConfigureWidget or XtResizeWidget as part of its layout process, unless XtCWQueryOnly is specified. If it does this, it should return XtGeometryDone to inform XtMakeGeometryRequest that it does not need to do the configuration itself.

To remain compatible with layout techniques used in older widgets (before XtGeometryDone was added to the Intrinsics), a geometry manager should avoid using XtResizeWidget or XtConfigureWidget on the child making the request because the layout process of the child may be in an intermediate state in which it is not prepared to handle a call to its resize procedure. A self-contained widget set may choose this alternative geometry management scheme, however, provided that it clearly warns widget developers of the compatibility consequences.

Although XtMakeGeometryRequest resizes the widget's window (if the geometry manager returns XtGeometryYes), it does not call the widget class's resize procedure. The requesting widget must perform whatever resizing calculations are needed explicitly.

If the geometry manager disallows the request, the widget cannot change its geometry. The values pointed to by geometry_return are undefined, and the geometry manager returns XtGeometryNo.

Sometimes the geometry manager cannot satisfy the request exactly but may be able to satisfy a similar request. That is, it could satisfy only a subset of the requests (for example, size but not position) or a lesser request (for example, it cannot make the child as big as the request but it can make the child bigger than its current size). In such cases, the geometry manager fills in the structure pointed to by geometry_return with the actual changes it is willing to make, including an appropriate request_mode mask, and returns XtGeometryAlmost. If a bit in geometry_return->request_mode is zero, the geometry manager agrees not to change the corresponding value if geometry_return is used immediately in a new request. If a bit is 1, the geometry manager does change that element to the corresponding value in geometry_return. More bits may be set in geometry_return->request_mode than in the original request if the geometry manager intends to change other fields should the child accept the compromise.

When XtGeometryAlmost is returned, the widget must decide if the compromise suggested in geometry_return is acceptable. If it is, the widget must not change its geometry directly; rather, it must make another call to XtMakeGeometryRequest.

If the next geometry request from this child uses the geometry_return values filled in by the geometry manager with an XtGeometryAlmost return and if there have been no intervening geometry requests on either its parent or any of its other children, the geometry manager must grant the request, if possible. That is, if the child asks immediately with the returned geometry, it should get an answer of XtGeometryYes. However, dynamic behavior in the user's window manager may affect the final outcome.

To return XtGeometryYes, the geometry manager frequently rearranges the position of other managed children by calling XtMoveWidget. However, a few geometry managers may sometimes change the size of other managed children by calling XtResizeWidget or XtConfigureWidget. If XtCWQueryOnly is specified, the geometry manager must return data describing how it would react to this geometry request without actually moving or resizing any widgets.

Geometry managers must not assume that the request and geometry_return arguments point to independent storage. The caller is permitted to use the same field for both, and the geometry manager must allocate its own temporary storage, if necessary.