From: aw@jello.bae.bellcore.com (Andrew Wason)
Subject: R5 geometry management and XtSetValues
Reply-To: aw@bae.bellcore.com
Organization: Bell Communications Research
Date: Sat, 23 Jan 93 02:06:53 GMT

Consider this scenario:

 A child widget requests a new size via it's set_values method.
 XtSetValues calls XtMakeGeometryRequest with the new size.  The
 widgets parent can't grant the new size, and returns
 XtGeometryAlmost via it's geometry_manager method and a
 compromise geometry which is the *current size* of the child
 widget.  The child widgets set_values_almost method accepts this
 supposedly "new" size. XtSetValues then calls
 XtMakeGeometryRequest again to accept this "compromise" size,
 this time the parent returns XtGeometryYes.

Is it correct for a manager widget to return XtGeometryAlmost and
a compromize geometry of the current size of the child?

This wasn't a problem in R4, but the R5 XtSetValues behaves
differently (compare line 275 in R5 SetValues.c RCSID 1.15 with
line 250 in R4 SetValues.c RCSID 1.10).  In R5, the child widgets
resize method is only called on an XtGeometryYes if the size of
the child has also changed.  In the case above, the childs
set_values_almost accepted the "compromize" size expecting it's
resize method to be called as a result.  In R4 it was, in R5 it
won't be because the new size is the same as the current size.

In my widgets set_values method, if it determines it needs to do
an internal relayout, it only does the layout if it's size is
unchanged as a result of the set_values.  It assumes if it's size
has changed, then XtSetValues will call it's resize method which
will do the layout.  If the new size is refused, then it's
set_values_almost method will do the layout.  But in R5, in the
case where the size changed in set_values and we need to layout,
and the parent returns Almost with the current size as a
compromise, then the widget will not get to layout.

Assuming the parent in the scenario above is behaving correctly,
then how can my child work around this case in R5?

Here is the basic structure of my set_values, set_values_almost
and resize methods:


static Boolean SetValues(Widget current, Widget request, Widget new,
                         ArgList args, Cardinal *num_args)
{
    [...]
    /*
     * If our size didn't change, but we need to layout, call Layout.
     * If our size did change, then Xt will call our Resize method for us.
     * If our size did change, but the new size is later refused,
     *   then SetValuesAlmost will call Layout.
     */
    if (current->core.width == new->core.width &&
        current->core.height == new->core.height &&
        need_relayout)
        Layout(new);
    [...]
}

static void SetValuesAlmost(Widget old, Widget new,
                            XtWidgetGeometry *request, XtWidgetGeometry *reply)
{
    /*
     * If XtGeometryAlmost, accept compromize - Resize will take care of it
     */
    if (reply->request_mode)
        *request = *reply;

    /*
     * If XtGeometryNo, call Layout to relayout if it was a size change
     * that was denied.
     * Accept the original geometry.
     * (we need to call Layout even though the size
     * didn't change to force a relayout - set_values relies on this)
     */
    else {
        if ((request->request_mode & CWWidth ||
             request->request_mode & CWHeight))
            Layout(new);

        request->request_mode = 0;
    }
}

static void Resize(Widget w)
{
    Layout(w);
}



Andrew

_______________________________________________________________________________

Andrew Wason                                       Bell Communications Research
aw@bae.bellcore.com                                Piscataway, NJ
bellcore!bae!aw
Newsgroups: comp.windows.x.intrinsics