[comp.windows.x] `Working dialogs' in Motif

pvianna@Citicorp.COM (Paul Vianna) (03/01/90)

The C code below uses the Motif X Toolkit to pop up a button that can be
used to trigger the execution of some application code (simply reads
a string entered by the user in this example). Assuming that the
application code will take some time, a status window is popped up to
tell the user that we are "Working...". Unfortunately, due to the order
that things are done by the X toolkit, a blank status window is displayed
while the application code runs. If the XtUnmanageChild() call is commented
out, then the "Working..." text is displayed, but only *after* the
application code is finished.

Does anyone know how such a status window can be completely displayed
*before* the application code begins? Thanks!

--
Paul Vianna
pvianna@Citicorp.COM
uunet!ccorp!pvianna

/* dialog.c - Test of a simple button-activated dialog. */

#include <stdio.h>
#include <X11/StringDefs.h>
#include <X11/Intrinsic.h>
#include <X11/Shell.h>
#include <Xm/Xm.h>
#include <Xm/PushB.h>
#include <Xm/Text.h>
#include <Xm/MessageB.h>

static void buttonPressCallback(button, clientData, callData)
     Widget button;
     caddr_t clientData, callData;
{
    char line[80];
    static Widget box = NULL;
    
    if (!box) {
	XmString title = XmStringCreateLtoR(" Waiting... ", 
					    XmSTRING_DEFAULT_CHARSET);
	XmString msg = XmStringCreateLtoR("Waiting for a string...", 
					  XmSTRING_DEFAULT_CHARSET);
	Arg args[10];
	int n = 0;
	
	XtSetArg(args[n], XmNmessageString,  msg);                         n++;
	XtSetArg(args[n], XmNdialogTitle,    title);                       n++;
	XtSetArg(args[n], XmNdialogStyle,    XmDIALOG_APPLICATION_MODAL);  n++;
	box = XmCreateWorkingDialog(button, "WorkingBox", args, n);
	}

    XtManageChild(box);
    XSync(XtDisplay(box), False);

    fprintf(stderr, "Enter a string: ");
    gets(line);
    fprintf(stderr, "You typed: `%s'\n", line);
    XtUnmanageChild(box);
    }

main(ac, av)
     int ac;
     char **av;
{
    Widget topLevel, button, dialog;
    Arg args[10];
    int n = 0;

    topLevel = XtInitialize(av[0], "Dialog", NULL, 0, &ac, av);

    XtSetArg(args[n], XmNwidth,  150); n++;
    XtSetArg(args[n], XmNheight, 150); n++;
    button = XtCreateManagedWidget("button", xmPushButtonWidgetClass, topLevel,
				   args, n);
    XtAddCallback(button, XmNactivateCallback, buttonPressCallback, NULL);

    XtRealizeWidget(topLevel);
    XtMainLoop();
    }
-- 
Dominick Samperi
Citicorp, NAIB
uunet!naib!samperi

greg@tweedledum.imsd.contel.com (Greg Christy) (03/01/90)

I brought this problem up on motif-talk in October and the message
that follows contains the hack that I have been using since then to
circumvent this annoyance.  The code was written with the goal of
waiting the minimum amount of time for the widget to "appear" and
therefore only processing the event that is necessary for this to
happen.


--------------------

From: greg%tweedledum@WLV.imsd.contel.com (Greg Christy)
To: motif-talk@osf.org
Subject: Waiting for a Dialog to Appear...
Date: Mon, 30 Oct 89 16:44:31 PST


I think I've found the answer to my own question after mucking around
with event dumps from xscope.  I tried some variations on the events to
process while waiting for the Expose event, but only the Expose event
seems to be important.   The code shown below seems to do the trick.  Does
anyone know of any side-effects that may be introduced by this method?  


/*
 *   WaitForExpose()
 *   October 30, 1989
 *
 *   Greg Christy  (greg@mickey.imsd.contel.com)
 *
 *   This routine will wait (i.e., block) until an Expose event occurs
 *   in the widget specified in the argument, process the event with
 *   XtNextEvent() and then synchronize the server to flush out any
 *   requests made during the execution of XtNextEvent().  This has the
 *   effect of waiting for a widget to "appear".
 *
 *   Copyright 1989 by Contel Federal Systems
 *
 *   Permission to use, copy, modify, and distribute this software 
 *   without fee is hereby granted, provided that the above copyright
 *   notice appears in all copies.  It is provided "as is" without any
 *   express or implied warranty. 
 */

#include <X11/Intrinsic.h>

void
  WaitForExpose(w)
Widget w;

{
  XEvent event;
  Display * display = XtDisplay(w);
  Window window = XtWindow(w);


  XWindowEvent(display, window, ExposureMask, &event); /* wait for expose... */

  XtDispatchEvent(&event);	/* process it */

  XSync(display,0);		/* flush out any requests made during */
				/* XtDispatchEvent() */
}

-------------------------------------------------------------------------------
Greg Christy                    dumb email: greg%mickey@wlv.imsd.contel.com
Contel Federal Systems          smart email: greg@mickey.imsd.contel.com
31717 La Tienda Drive           phone: (818) 706-4307
Westlake Village, CA    91359
-------------------------------------------------------------------------------

karlton@sgi.com (Phil Karlton) (03/02/90)

In article <47834@wlbr.IMSD.CONTEL.COM>, greg@tweedledum.imsd.contel.com
(Greg Christy) writes:
>  *   This routine will wait (i.e., block) until an Expose event occurs
>  *   in the widget specified in the argument, process the event with
>  *   XtNextEvent() and then synchronize the server to flush out any
>  *   requests made during the execution of XtNextEvent().  This has the
>  *   effect of waiting for a widget to "appear".

There is a danger in this scheme. If the window for the widget is
completely obscurred, then this will end up wedging the application
until the window is uncovered. Unless you have some guarantee that the
window will be on top, waiting for a Map event would be a better idea.

PK
--

hvr@kimba.Sun.COM (Heather Rose) (03/08/90)

In article <1990Feb28.164742.1177@Citicorp.COM> pvianna@Citicorp.COM (Paul Vianna) writes:
>
>Does anyone know how such a status window can be completely displayed
>*before* the application code begins? Thanks!

You might want to point the MOTIF folks at the XView implementation of
FRAME_BUSY.  In OpenLook, you can signal to your user that the application
is "working" by a frame in "busy state".  This means that the cursor for
the application becomes a stop watch, and the frame reflects the "busy state"
as defined by OpenLook.

Anyway, XView accomplishes the "working" state changes before starting the
task at hand, so the MOTIF developers may want to see how we handled this
to affect a similar result.

Regards,

Heather