montnaro@spyder.crd.ge.com (Skip Montanaro) (06/18/91)
In my application I popup an XmMessageDialog widget before launching into a long operation. I've experimented with calling XmUpdateDisplay one or more times before the operation, in an attempt to force the message to display properly. My experiments have been unsuccessful thusfar. The mental picture I have of the situation is that there is an expose event for the outer DialogShell widget in the input queue when XmUpdateDisplay is called initially. The call processes that expose event, which generates one or more other expose events for the XmMessageBox child of the DialogShell. These aren't seen by the first call to XmUpdateDisplay, so you have to call it again. Unfortunately, there is a race between the client and server to see whether the server can send the expose event(s) before the next call to XmUpdateDisplay. If it can, the second call will cause the message to be displayed. If not, the second call will see no expose events in the queue and return without doing any useful work. Can someone comment on my perception of the situation? Whether my ideas are right or wrong, are there any techniques I can use to remedy my problem? Currently I just execute several XFlush's in the client after the first XmUpdateDisplay call to slow the client down. Naturally, this doesn't always work either. (I could have the client sleep for awhile, but for how long?) Thx, -- Skip (montanaro@crdgw1.ge.com)
tsang@ISI.COM (Kam C. Tsang) (06/18/91)
> In my application I popup an XmMessageDialog widget before launching into a > long operation. I've experimented with calling XmUpdateDisplay one or more > times before the operation, in an attempt to force the message to display > properly. My experiments have been unsuccessful thusfar. Try this: void ProcessAllExposeEvents() { // somehow you have to get to your own appContext // see pp 312, 6.10, "X Window System Toolkit" // by Paul Asente and Ralph Swick while (XtAppPending(appContext) & XtIMXEvent) { XEvent event; XtAppPeekEvent(appContext, &event); if ((event.type == Expose) || (event.type == MapNotify)) XtAppProcessEvent(appContext, XtIMXEvent); else break; } } -kam ----------------------------+----------------------------- Kam Tsang | User Interface Group (408) 980-1590 x 275 | Integrated Systems, Inc. (408) 980-0400 [Fax] | 3620 Jay Street tsang@isi.com | Santa Clara, CA 94054 ----------------------------+-----------------------------
masa@hpsciz.sc.hp.com (Masayoshi Habu) (06/18/91)
In comp.windows.x.motif, montnaro@spyder.crd.ge.com (Skip Montanaro) writes:
Can someone comment on my perception of the situation? Whether my ideas are
right or wrong, are there any techniques I can use to remedy my problem?
Currently I just execute several XFlush's in the client after the first
XmUpdateDisplay call to slow the client down. Naturally, this doesn't always
work either. (I could have the client sleep for awhile, but for how long?)
I have experienced similar problems. Instead of XFlush, I called XSync.
Calling a pair of XSync and XmUpdateDisplay once ot twice took care of
my problems. As you see, this depends on the relative speed of our server
and client. Asynchronous parallel processes give me interesting problems.
Masa
bazavan@hpdtczb.HP.COM (Valentin Bazavan) (06/19/91)
The sequence below always works for me: XmUpdateDisplay sleep XmUpdateDisplay The problem with this approach is that the shortest suspension time you can set using sleep(3) is one second; that's too long. You will have to write your own sleep() to allow shorter suspension times. Valentin Bazavan vbazavan@dtc.hp.com
gabe@hpcvlx.cv.hp.com. (Gabe Begeddov) (06/23/91)
> / hpcvlx.cv.hp.com:comp.windows.x.motif / bazavan@hpdtczb.HP.COM (Valentin Bazavan) / 7:37 am Jun 19, 1991 / > > The sequence below always works for me: > > XmUpdateDisplay > sleep > XmUpdateDisplay > > The problem with this approach is that the shortest suspension time you > can set using sleep(3) is one second; that's too long. You will have > to write your own sleep() to allow shorter suspension times. > Another problem is that it isn't guaranteed to work. Since the dialog is a non-override redirect window it is mapped by the wm rather than by the client. Since the wm could be swapped out or on a slow link you are not quaranteed that it will respond in 1 second. A local event loop waiting for a MapNotify on the dialog is probably your best bet. Something like: while (1) { XtAppNextEvent(app, &event); if (event.xany.type == MapNotify && event.xany.window == XtWindow(dialogShell)) { XmUpdateDisplay(dialogShell); return; } else XtDispatchEvent(&event); } > Valentin Bazavan > vbazavan@dtc.hp.com > ---------- > > Gabe Beged-Dov gabe@cv.hp.com
dbrooks@osf.org (06/27/91)
I just got back from vacation (11 days with a youth orchestra in 11 cities in Europe; clearly some strange new meaning of the word "vacation") so apologies for joining in too late. As Gabe suggested, the problem of a dialog not displaying before the client goes "busy" is a kind of race. The server tells the client that its request to map a window has been honored; unfortunately, in this case, this means only that the request has been sent on to the (reparenting) window manager. The wm is now at liberty to yawn, scratch, thrash the paging disk a little, decorate the window, walk the dog, pay its bills, and finally map the entire decorated concoction (whereupon the server will yawn, scratch -- etc). There is one problem with solutions like the two posted. We know from a separate, recent thread, that it's possible to "pop-up" a dialog from an iconified main window, and it will then not be actually mapped. I think the following works a little better. It may be over-general for your requirement; note in particular it climbs a tree to find shell widgets, and the chances are you already know these. It doesn't work with olwm, as noted. This isn't deliberate OSF policy ;-) It's just because olwm has a different approach to transient children of iconified parents. It could be made to work. David Brooks Systems Engineering Open Software Foundation /* * This procedure will ensure that, if a dialog window is being mapped, * its contents become visible before returning. It is intended to be * used just before a bout of computing that doesn't service the display. * You should still call XmUpdateDisplay() at intervals during this * computing if possible. * * The monitoring of window states is necessary because attempts to map * the dialog are redirected to the window manager (if there is one) and * this introduces a significant delay before the window is actually mapped * and exposed. This code works under mwm, twm, uwm, and no-wm. It * doesn't work with olwm if the mainwindow is iconified. * * The argument to ForceDialog is any widget in the dialog (often it * will be the BulletinBoard child of a DialogShell). */ ForceDialog(w) Widget w; { Widget diashell, topshell; Window diawindow, topwindow; Display *dpy; XWindowAttributes xwa; XEvent event; XtAppContext cxt; /* Locate the shell we are interested in */ for (diashell = w; !XtIsShell(diashell); diashell = XtParent(diashell)) ; /* Locate its primary window's shell (which may be the same) */ for (topshell = diashell; !XtIsTopLevelShell(topshell); topshell = XtParent(topshell)) ; if (XtIsRealized(diashell) && XtIsRealized(topshell)) { dpy = XtDisplay(topshell); diawindow = XtWindow(diashell); topwindow = XtWindow(topshell); cxt = XtWidgetToApplicationContext(diashell); /* Wait for the dialog to be mapped. It's guaranteed to become so unless... */ while (XGetWindowAttributes(dpy, diawindow, &xwa), xwa.map_state != IsViewable) { /* ...if the primary is (or becomes) unviewable or unmapped, it's probably iconified, and nothing will happen. */ if (XGetWindowAttributes(dpy, topwindow, &xwa), xwa.map_state != IsViewable) break; /* At this stage, we are guaranteed there will be an event of some kind. BEWARE; we are presumably in a callback, so this can recurse. */ XtAppNextEvent(cxt, &event); XtDispatchEvent(&event); } } /* The next XSync() will get an expose event if the dialog was unmapped. */ XmUpdateDisplay(topshell); }