query_geometry()query_geometry()Namequery_geometry - RectObj method called to request a widget's preferred
size and position.
Synopsis
typedef XtGeometryResult (*XtGeometryHandler)(Widget, XtWidgetGeometry
*,
XtWidgetGeometry *);
Widget w;
XtWidgetGeometry *request;
XtWidgetGeometry *preferred_return
Inputs
w Specifies the widget or object that is being queried.
request Specifies the geometry changes that the parent plans to make.
Outputs
preferred_return
Returns the widget or object's preferred geometry.
Returns
The widget's reply: XtGeometryYes, XtGeometryNo, or XtGeometryAlmost.
Description
The query_geometry() method is registered on the query_geometry field
of the RectObj or Core class part structure. It is invoked by XtQuery‐
Geometry() when the widget's parent wants to determine the widget's
preferred geometry. The parent may call this function when it want to
know the widget's ideal size in the absence of any constraints, or it
may call it before changing some of the widget's geometry fields in
order to find out the widget's preference for the other fields.
The request argument indicates the geometry changes the parent plans to
make. request->request_mode contains flags that indicate which of the
remaining fields are significant. (See the "Structures" section below
for a description of the structure and a list of the flags.) The
query_geometry() method should examine this proposed change, set its
preferred geometry in preferred_return, setting preferred_return->
request_mode to indicate which geometry field it cares about, and
return one of the following values:
XtGeometryYes
The widget agrees to the change; the parent should make exactly
the change it proposed. When query_geometry() returns this value,
the contents of preferred_return should be identical to the con‐
tents of request, for each flag bit set in preferred_return. This
means that the parent's proposed geometry is exactly the widget's
preferred geometry (or that the widget has a flexible notion of
"preferred" and feels that the proposal is good enough).
XtGeometryNo
This return value means that the widget's current geometry is its
preferred geometry, and it would rather not be changed. When this
value is returned, query_geometry() doesn't have to fill in pre‐
ferred_return, because XtQueryGeometry() will fill in any unspeci‐
fied fields with their current values, which in this case are the
preferred values. It is of course up to the parent widget whether
or not to honor this request not to change.
XtGeometryAlmost
This return value means that the widget would like a geometry
change, but that its preferred geometry differs from the proposed
geometry. query_geometry() should return this value if at least
one bit is set in the return flags that was not set in the pro‐
posed flags, or if any of the returned values (that have their
flag bit set) differ from the corresponding proposed values.
Note that query_geometry() need only return its preferences for the
fields it cares about (generally width and height). XtQueryGeometry()
will fill in any unspecified fields with the widget's current value.
Also, query_geometry() can ignore flag bits set in request for fields
that it does not care about. If a widget doesn't care about its loca‐
tion, for example, and its parent proposes to change its location with‐
out changing its size, it should still place its preferred size in pre‐
ferred_return, and follow the rules above to determine which value to
return.
It is up to the parent widget to decide what to do with the return
value from this function (which it gets from XtQueryGeometry()). Some
parents will respect the widget's requests, but many will ignore them.
Generally, if a parent sets a flag in request, it will change that
field, regardless of the widget's return value. The power of the
query_geometry() method lies in the fact that the widget can propose
additional geometry changes with the XtGeometryAlmost return value. A
parent that constrains the width of a widget may call XtQueryGeometry()
to determine how high the widget would like to be, given its new width.
A label widget that supported word wrapping, for example, might request
a larger height if its width were made smaller. A cooperating parent
would make its change to the width, but also change the height as the
child requested.
The query_geometry() method is not chained. Widget classes that do not
define a query_geometry() method can inherit the method from their
superclass by specifying XtInheritQueryGeometry on the query_geometry
field of the RectObj or Core class part structure. Widgets that have
no preference about their geometry can set this field to NULL.
See the "Background" section below for more details on the query_geome‐
try() method. See XtQueryGeometry(1) for the parent widget's perspec‐
tive on this geometry negotiation process.
Usage
Like the geometry_manager() method, the query_geometry() method can be
confusing, and can become almost arbitrarily complex. The query_geome‐
try() mechanism allows much more flexibility than most widgets need and
more than most parents support. The fact that there are three possible
return values which do not have very clearly defined meanings (at least
not well defined in practice) to the child or to the parent makes the
situation all the more confusing. There are some factors that can sim‐
plify the query_geometry() method, however.
Most widgets do not care about anything other than their width and
height, and their query_geometry() methods never need to return pre‐
ferred information about position, border width, or stacking order.
Most parents won't bother to query these fields anyway.
Most widgets treat their width and height independently, and do not try
to increase their height if their width shrinks, for example. These
widgets can use a simple method like the example shown below.
Some widgets do not even have a preference about their size. A label
widget's preferred size is whatever it takes to display the string or
pixmap, and a composite widget's preferred size may be whatever it
takes to lay out its children. A scrollbar, however, can make do with
whatever size it is given, and can simply inherit the query_geometry()
method of its parent.
Example
The following procedure is the query_geometry() method from the Xaw
Label widget. Most of the Xaw widgets that have a query_geometry()
method use almost identical procedures. The first thing it does is set
its preferred width and height, which are the width and height of the
label plus internal margins. Then it checks to see if the parent's
requested geometry had both width and height flags set (note that it
masks out any other bits for fields that it does not care about), and
if so, and if the parent's request matches the preferred size, it
returns XtGeometryYes. Otherwise, if the preferred size matches the
widget's current size, it returns XtGeometryNo, and otherwise it
returns XtGeometryAlmost.
Note that this procedure does not attempt to do anything special if
only its width or only its height are constrained. The query_geome‐
try() method of the Xaw Box widget does handle this case, and may be
worth study if you will be writing a similar widget.
static XtGeometryResult QueryGeometry(w, intended, preferred)
Widget w;
XtWidgetGeometry *intended, *preferred;
{
register LabelWidget lw = (LabelWidget)w;
preferred->request_mode = CWWidth CWHeight;
preferred->width = (lw->label.label_width + 2 * lw->label.internal_width +
LEFT_OFFSET(lw));
preferred->height = lw->label.label_height + 2*lw->label.internal_height;
if ( ((intended->request_mode & (CWWidth CWHeight))
== (CWWidth CWHeight)) &&
intended->width == preferred->width &&
intended->height == preferred->height)
return XtGeometryYes;
else if (preferred->width == w->core.width &&
preferred->height == w->core.height)
return XtGeometryNo;
else
return XtGeometryAlmost;
}
Background
The query_geometry() method is expected to examine the bits set in
request->request_mode, evaluate the proposed geometry for the widget,
and store the result in preferred_return (setting the bits in pre‐
ferred_return-> request_mode corresponding to those geometry fields
that it cares about). If the proposed geometry change is acceptable
without modification, the query_geometry() method should return XtGeom‐
etryYes. If at least one field in preferred_return is different from
the corresponding field in request or if a bit was set in pre‐
ferred_return that was not set in request, the query_geometry() method
should return XtGeometryAlmost. If the preferred geometry is identical
to the current geometry, the query_geometry() method should return
XtGeometryNo.
Note that the query_geometry() method may assume that no XtMakeResiz‐
eRequest() or XtMakeGeometryRequest() is in progress for the specified
widget; that is, it is not required to construct a reply consistent
with the requested geometry if such a request were actually outstand‐
ing.
After calling the query_geometry() method or if the query_geometry()
field is NULL, XtQueryGeometry() examines all the unset bits in pre‐
ferred_return-> request_mode and sets the corresponding fields in pre‐
ferred_return to the current values from the widget instance. If
CWStackMode is not set, the stack_mode field is set to XtSMDontChange.
XtQueryGeometry() returns either the value returned by the query_geome‐
try() method or XtGeometryYes if the query_geometry() field is NULL.
Therefore, the caller can interpret a return of XtGeometryYes as not
needing to evaluate the contents of the reply and, more importantly,
not needing to modify its layout plans. A return of XtGeometryAlmost
means either that both the parent and the child expressed interest in
at least one common field and the child's preference does not match the
parent's intentions or that the child expressed interest in a field
that the parent might need to consider. A return value of XtGeometryNo
means that both the parent and the child expressed interest in a field
and that the child suggests that the field's current value is its pre‐
ferred value. In addition, whether or not the caller ignores the
return value or the reply mask, it is guaranteed that the pre‐
ferred_return structure contains complete geometry information for the
child.
Parents are expected to call XtQueryGeometry() in their layout routine
and wherever other information is significant after change_managed()
has been called. The change_managed() method may assume that the
child's current geometry is its preferred geometry. Thus, the child is
still responsible for storing values into its own geometry during its
initialize() method.
Structures
The possible return values of a query_geometry() method are defined as
follows:
typedef enum {
XtGeometryYes, /* Request accepted */
XtGeometryNo, /* Request rejected */
XtGeometryAlmost,/* Compromise proposed */
XtGeometryDone /* never returned by query_geometry */
} XtGeometryResult;
The XtWidgetGeometry structure is similar to but not identical to the
corresponding Xlib structure:
typedef unsigned long XtGeometryMask;
typedef struct {
XtGeometryMask request_mode;
Position x, y;
Dimension width, height;
Dimension border_width;
Widget sibling;
int stack_mode;
} XtWidgetGeometry;
XtQueryGeometry(), like the Xlib XConfigureWindow() function, uses
request_mode to determine which fields in the XtWidgetGeometry struc‐
ture the parent and the child have set. The request_mode definitions
are from <X11/X.h>:
#define CWX(1<<0)
#define CWY(1<<1)
#define CWWidth(1<<2)
#define CWHeight(1<<3)
#define CWBorderWidth(1<<4)
#define CWSibling(1<<5)
#define CWStackMode(1<<6)
The stack_mode definitions are from <X11/X.h>:
#define Above0
#define Below1
#define TopIf2
#define BottomIf3
#define Opposite4
The Intrinsics also support the following value:
#define XtSMDontChange5
For precise definitions of Above, Below, TopIf, BottomIf, and Opposite,
see the reference page for XConfigureWindow() in Volume Two, Xlib Ref‐
erence Manual. XtSMDontChange indicates that the widget wants its cur‐
rent stacking order preserved.
See AlsoXtQueryGeometry(1),
Core(3).
Xt - Intrinsics Methods query_geometry()