Bug 18567 - Xaw: relayout of Form widget when a child resizes is broken
Summary: Xaw: relayout of Form widget when a child resizes is broken
Keywords:
Status: CLOSED RAWHIDE
Alias: None
Product: Red Hat Linux
Classification: Retired
Component: XFree86
Version: 7.0
Hardware: i386
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Mike A. Harris
QA Contact: David Lawrence
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2000-10-06 20:18 UTC by Tim Mann
Modified: 2007-04-18 16:29 UTC (History)
0 users

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2002-11-03 07:55:10 UTC
Embargoed:


Attachments (Terms of Use)

Description Tim Mann 2000-10-06 20:18:12 UTC
This bug is submitted for your information only.  I've also sent the bug
report directly to xbugs and xfree86, so
hopefully one of those groups will be fixing it.

To: xbugs
cc: XFree86
Newsgroups: 
Subject: Xaw: relayout of Form widget when a child resizes is broken
-----
     VERSION:

R6.4, public-patch-3
XFree86 4.0.1

     CLIENT MACHINE and OPERATING SYSTEM:

Red Hat Linux 7.0, kernel 2.2.16
(but this doesn't matter to the bug)

     DISPLAY TYPE:

XF86_Mach64
(but this doesn't matter to the bug; also seen on other displays)

     WINDOW MANAGER:

GNOME with Sawfish window manager
(but this doesn't matter to the bug)

     COMPILER:

gcc version 2.96 20000731 (Red Hat Linux 7.0)

     AREA:

Xaw

     SYNOPSIS:

Relayout of Form widget when a child resizes is broken

     DESCRIPTION:

When a child of a Form widget is resized by the user program after the 
Form widget has been realized, relayout of the form is not done properly.
In the case I've seen, the children do not move.  This bug was not present
in earlier versions of Xaw; they repositioned the children correctly.

Looking at the code and comparing it with an older version, the Form widget 
is going through the motions of trying to do the relayout, but an extra 
layer of code has been added that does not work properly and keeps the 
relayout from actually changing the layout as it should.  It seems that 
layout now uses something called the "virtual" width and height of the 
child widgets to compute the layout instead of looking inside the child 
widgets for their actual width and height.  I don't understand what is 
supposed to be accomplished by doing that -- it can't be an optimization 
to avoid communicating with the server, since the actual width and height 
are already in local fields.  What it does do is break the relayout
process, 
because the virtual width and height are not updated to match the real 
width and height.

In particular, if a child resizes, the sequence of events is (1) the child 
resizes itself, (2) the Form's geometry manager is called, (3) the geometry 
manager redoes the form layout using the virtual sizes of the children, 
which DO NOT reflect the new size of the child that just changed, (4) 
the geometry manager MIGHT update the virtual size of the child.  In step 
(3), obviously the layout will be wrong because the outdated size is used. 
In step (4) there is an additional bug, because the virtual size is updated 
only if XawFormDoLayout(w, False) had been called earlier to put the form 
into deferred layout mode.

Perhaps the virtual stuff is some kind of optimization for the case where
the form itself is resized and it must then resize its children.  But it
completely breaks the case where a child is resized by the user program
and the form needs relayout.

     REPEAT BY:

Below is a program that demonstrates the problem.  If you run it with 
the argument "0", it draws a Form widget with three children and does 
not attempt to resize any of them.  If you run it with the argument "1", 
it will widen the child marked "Label 1".  Under older versions of Xaw, 
this causes Label 2 to move to the right to get out of the way.  Under 
the current version, Label 2 does not move, because the Layout procedure 
uses the old size of Label 1 (the incorrect "virtual" size) to compute 
the new layout.  Thus Label 1 ends up overlapping Label 2.  You can also 
run the program with the argument "3", which calls XawFormDoLayout(w, 
FALSE) before the resize and XawFormDoLayout(2, TRUE) after.  This does 
not change the result on the screen, but does cause the code to go down 
a somewhat different path.

Another way to reproduce the problem is to run any version of xboard from
3.0.0 to 4.1.0.  (See http://www.tim-mann.org for source code.)  The button
bar [<< < P > >>] ends up on top of the message widget instead of moving
to the far right of the window as it should.  xboard lays out its window
by first making the message widget small, then realizing all the widgets,
then looking to see how much extra space there is and enlarging the message
widget to fill it.  This has worked fine for years but is now broken with
the current Xaw.

=============cut here=================

#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/Label.h>
#include <stdio.h>

XtAppContext appContext;
Widget shellWidget, formWidget, labelWidget[3];

int
main(int argc, char **argv)
{
  int i;
  Arg args[16];
  Dimension w, h, wr, hr;
  XtGeometryResult gres;
  int arg = 1;
  Position x, y;

  shellWidget = XtAppInitialize(&appContext, "XawBug", NULL, 0,
				&argc, argv, NULL, NULL, 0);

  if (argc > 1) arg = atoi(argv[1]);

  formWidget =
    XtCreateManagedWidget("form", formWidgetClass, shellWidget, NULL, 0);

  labelWidget[0] =
    XtCreateWidget("label0", labelWidgetClass, formWidget, NULL, 0);
  labelWidget[1] =
    XtCreateWidget("label1", labelWidgetClass, formWidget, NULL, 0);
  labelWidget[2] =
    XtCreateWidget("label2", labelWidgetClass, formWidget, NULL, 0);

  XtManageChildren(labelWidget, sizeof(labelWidget)/sizeof(Widget));

  i = 0;
  XtSetArg(args[i], XtNlabel,
	   "This is a long label to make the form wide"); i++;
  XtSetValues(labelWidget[0], args, i);

  i = 0;
  XtSetArg(args[i], XtNresizable, True); i++;
  XtSetArg(args[i], XtNlabel, "Label 1"); i++;
  XtSetArg(args[i], XtNfromVert, labelWidget[0]); i++;
  XtSetValues(labelWidget[1], args, i);

  i = 0;
  XtSetArg(args[i], XtNlabel, "Label 2"); i++;
  XtSetArg(args[i], XtNfromVert, labelWidget[0]); i++;
  XtSetArg(args[i], XtNfromHoriz, labelWidget[1]); i++;
  XtSetValues(labelWidget[2], args, i);

  XtRealizeWidget(shellWidget);
  
  if (arg & 2) {
    XawFormDoLayout(formWidget, False);
  }

  if (arg & 1) {

    i = 0;
    XtSetArg(args[i], XtNwidth, &w);  i++;
    XtSetArg(args[i], XtNheight, &h);  i++;
    XtGetValues(labelWidget[1], args, i);

    w += 40;

    gres = XtMakeResizeRequest(labelWidget[1], w, h, &wr, &hr);
    if (gres != XtGeometryYes) {
      fprintf(stderr, "resize geometry error %d %d %d %d %d\n",
	      gres, w, h, wr, hr);
    }

  }

  if (arg & 2) {
    XawFormDoLayout(formWidget, True);
  }

  XtAppMainLoop(appContext);
  return 0;
}


=============cut here=================

     SAMPLE FIX:

I'm sorry, but I don't understand what the virtual stuff is supposed to 
do, so I don't know the proper fix.  You can definitely fix this bug by 
going back to the old version of Xaw that was used in XFree86 3.3.6.  

The identifying lines from the OLD, WORKING version are:
/* $XConsortium: Form.c,v 1.52 94/04/17 20:12:06 kaleb Exp $ */
/* $XFree86: xc/lib/Xaw/Form.c,v 1.1.1.1.12.2 1998/05/16 09:05:19 dawes Exp
$ */

The identifying lines from the NEW, BROKEN version are:
/* $TOG: Form.c /main/54 1998/05/14 14:55:45 kaleb $ */
/* $XFree86: xc/lib/Xaw/Form.c,v 1.16 1999/11/19 13:53:26 hohndel Exp $ */

     SERVER OUTPUT:

This is totally irrelevant, but the XFree86 FAQ says to include it in but
reports, so here it is.  Apparently I have an XFree86 3.3.6 server, but
nevertheless the bug I'm reporting is in the XFree86 4.0.1 libraries. 
It's independent of the server that's running.

XFree86 Version 3.3.6 / X Window System
(protocol Version 11, revision 0, vendor release 6300)
Release Date: January 8 2000
	If the server is older than 6-12 months, or if your card is newer
	than the above date, look for a newer version before reporting
	problems.  (see http://www.XFree86.Org/FAQ)
Operating System: Linux 2.2.5-22smp i686 [ELF] 
Configured drivers:
  Mach64: accelerated server for ATI Mach64 graphics adaptors (Patchlevel
1)
(using VT number 8)

XF86Config: /usr/X11R6/lib/X11/XF86Config
(**) stands for supplied, (--) stands for probed/default values
(**) XKB: rules: "xfree86"
(**) XKB: model: "pc101"
(**) XKB: layout: "us"
(**) Mouse: type: PS/2, device: /dev/mouse, buttons: 3
(**) Mach64: Graphics device ID: "Primary Card"
(**) Mach64: Monitor ID: "Primary Monitor"
(**) FontPath set to "unix/:7100"
(--) Mach64: PCI: Mach64 RagePro rev 92, Aperture @ 0x41000000, Registers @
0x40000000, Block I/O @ 0x1000
(--) Mach64: PCI (92) and CONFIG_CHIP_ID (124) don't agree on ChipRev,
	using PCI value
(--) Mach64: Card type: AGP
(--) Mach64: Memory type: SGRAM (1:1) (5)
(--) Mach64: Clock type: Internal
(--) Mach64: Maximum allowed dot-clock: 230.000 MHz
(**) Mach64: Mode "1600x1200": mode clock = 162.000
(--) Mach64: Too little memory for mode "1600x1200"
(--) Mach64: Removing mode "1600x1200" from list of valid modes.
(**) Mach64: Mode "1280x1024": mode clock = 135.000
(**) Mach64: Mode "1152x864": mode clock = 135.000
(**) Mach64: Mode "1024x768": mode clock = 115.500
(**) Mach64: Mode "800x600": mode clock =  69.650
(**) Mach64: Mode "640x480": mode clock =  45.800
(--) Mach64: Virtual resolution: 1280x1024
(--) Mach64: Video RAM: 6144k
(--) Mach64: Using hardware cursor
(--) Mach64: Using 16 MB aperture @ 0x41000000
(--) Mach64: Using 4 KB register aperture @ 0x40000000
(--) Mach64: Ramdac is Internal
(--) Mach64: Ramdac speed: 230 MHz
Warning: Ron = 43, Rloop = 10, Roff = 46
(--) Mach64: Pixmap cache: 0 256x256 slots, 0 128x128 slots, 0 64x64 slots
(--) Mach64: Font cache: 0 fonts
SESSION_MANAGER=local/milwaukee:/tmp/.ICE-unix/11319
Xlib:  extension "XINERAMA" missing on display ":1.0".
SetKbdSettings - type: 2 rate: 30 delay: 500 snumlk: 0
SetKbdSettings - Succeeded
subshell.c: couldn't get terminal settings: Inappropriate ioctl for device

Tim Mann  tim.mann  http://www.tim-mann.org
Compaq Computer Corporation, Systems Research Center, Palo Alto, CA

Comment 1 Mike A. Harris 2001-09-18 08:22:25 UTC
If it hasn't been picked up already, we will pick up the upstream
fix when available.  Thanks for the report.

Comment 2 Mike A. Harris 2002-11-03 07:55:53 UTC
This should be fixed in XFree86 CVS which is going into rawhide soon,
if not in an earlier release.

Closing as RAWHIDE

Thanks.


Note You need to log in before you can comment on or make changes to this bug.