[comp.windows.x.motif] weird behavior with ScrolledList

jordan@tcs.com (Jordan Hayes) (05/14/91)

1.1.1, SunOs 4.1.1, MIT/18, etc.

In the example below, I create an applicationShell, and put an XmButton
in it.  When the button is pushed, XtAppWarning is called.  Also, I
create a topLevelShell with an XmScrolledList in it.  Then I install a
warning handler, which takes the string and makes an entry in the
list.

Here's what happens when I run it:  the first time I push the button,
the message appears.  Subsequent times I push the button, nothing shows
up (the list area doesn't get redrawn).  When there are enough lines
such that it would scroll, the list gets redrawn (when the scrollbars
show up).

Before the scrollbars show up, if I resize the window, the messages
appear, and it begins to work correctly.

Any guesses?

Code follows ...

=====

#include <stdio.h>
#include <Xm/Xm.h>
#include <Xm/List.h>
#include <Xm/PushB.h>

static Widget		_ErrList;
static XtAppContext	app;

static void
ErrBoxWarnFunc(s)
	char	*s;
{
	char		*cp, *cp1;
	XmString	str;

	if (s == NULL || *s == NULL)
		return;
	for (cp = s; *cp != NULL; cp = cp1) {
		for (cp1 = cp; *cp1 != NULL && *cp1 != '\n'; cp1++)
			;
		if (*cp1 == '\n')
			*cp1++ = NULL;
		str = XmStringCreateLtoR(s, XmSTRING_DEFAULT_CHARSET);
		XmListAddItem(_ErrList, str, 0);
		XmStringFree(str);
	}
}

static void
_AddMore(w, client, call)
	Widget		w;
	XtPointer	client;
	XtPointer	call;
{
	char		buf[BUFSIZ];
	static int	i;

	(void)sprintf(buf, "Push number %d\n", i++);
	XtAppWarning(app, buf);
}

main(argc, argv)
	int	argc;
	char	**argv;
{
	Display	*display;
	Widget	shell, button, errBox;

	/* setup */
	XtToolkitInitialize();
	app = XtCreateApplicationContext();
	if ((display = XtOpenDisplay(app, NULL, NULL, "Testing", NULL,
	    0, (Cardinal *)&argc, argv)) == (Display *)NULL) {
		fprintf(stderr, "Cannot open display \"%s\"\n",
		    XDisplayName(NULL));
		exit(-1);
	}

	/* make a shell with a button */
	shell = XtAppCreateShell(NULL, NULL, applicationShellWidgetClass,
	    display, NULL, 0);
	button = XmCreatePushButton(shell, "PushMe", NULL, 0);
	XtAddCallback(button, XmNactivateCallback, _AddMore, NULL);
	XtManageChild(button);
	XtRealizeWidget(shell);

	/* make the error window */
	errBox = XtAppCreateShell("ErrBox", NULL, topLevelShellWidgetClass,
	    display, NULL, 0);
	_ErrList = XmCreateScrolledList(errBox, "errList", NULL, 0);
	XtManageChild(_ErrList);
	XtRealizeWidget(errBox);

	/* set the warning handler */
	XtAppSetWarningHandler(app, ErrBoxWarnFunc);

	XtAppMainLoop(app);
}

=====

/jordan

meeks@osf.org (W. Scott Meeks) (05/14/91)

>Date: Mon, 13 May 91 10:38:30 PDT
>From: jordan@tcs.com (Jordan Hayes)
>1.1.1, SunOs 4.1.1, MIT/18, etc.
>
>In the example below, I create an applicationShell, and put an XmButton
>in it.  When the button is pushed, XtAppWarning is called.  Also, I
>create a topLevelShell with an XmScrolledList in it.  Then I install a
>warning handler, which takes the string and makes an entry in the
>list.
>
>Here's what happens when I run it:  the first time I push the button,
>the message appears.  Subsequent times I push the button, nothing shows
>up (the list area doesn't get redrawn).  When there are enough lines
>such that it would scroll, the list gets redrawn (when the scrollbars
>show up).
>
>Before the scrollbars show up, if I resize the window, the messages
>appear, and it begins to work correctly.
>
>Any guesses?

No need to guess on this one.  I believe this is caused by pir 2730: "List
widget fails to display all items when size is enforced larger than
visibleItemCount."  It's not so much a bug in the implementation as a minor
design flaw.  The default value for visibleItemCount is 1.  So you have a
list that's bigger than one item, but it's only showing the first item
until you resize at which time it resets visibleItemCount to display all
the items.  The problem is that the resize function doesn't reset the
visibleItemCount if there are no items in the list.  

The workaround is to set a reasonable value for visibleItemCount when you
create it.  This value doesn't have to be exact, it just has to be bigger
than the actual size of the list.

A patch has been made for this problem which should appear in 1.1.3 if it
doesn't create a regression problem.  It will make the default for
visibleItemCount be dynamic based on the size of the list and will cause
the resize function to guess at a reasonable value for visibleItemCount if
the list is empty.

Hope this helps.

W. Scott Meeks           | We must live with the fact, true throughout recorded
Open Software Foundation | history, that our artifacts are sometimes flawed and
meeks@osf.org            | cause us to die in novel and unexpected ways, and we
(617) 621-7229           | can only do our human best to minimize the problems.