[comp.windows.x] Placing popup shells

dbs@ulysses.att.com (Daniel Schonfeld[rs]) (07/27/90)

I'm currently writing an X11R4 application (using the HP X widgets) that needs
to control where it pops up some windows. I am trying to read the X and Y
coordinate information from the toplevel shell, and am getting inconsistent
results, depending on the window manager I am using and other factors.

I've included a short program to demonstrate what I am trying to do, and
the problem that occurs. When 'olwm' or 'twm' is running, with the program as
it stands, the popped up window ends up at position (30,30). However, if you
uncomment the lines with the XSync() sleep() calls, the behavior changes.
Under 'olwm', the program works (the popped up window is placed on top of the
toplevel window). Under 'twm' the program works iff the user has
RandomPlacement set OR the toplevel window is placed by the user within
N seconds, where N is the argument to sleep() in the program.

Is there a better way to get the position information from a realized
widget or window? 

Thanks for your help!

Dan Schonfeld
dbs@ulysses.att.com

-----------  PROGRAM FOLLOWS ------------

#include <stdio.h>
#include <X11/Intrinsic.h>
#include <X11/Shell.h>
#include <X11/Xutil.h>
#include <X11/Xw/Xw.h>
#include <X11/StringDefs.h>
#include <X11/Xw/SText.h>

Widget	toplevel, msg, child, childtxt;
Arg args[2];

main(argc,argv)
int argc;
char *argv[];
{
	toplevel=XtInitialize("testpopup","TEstpopup",args,0,&argc,argv);

	XtSetArg(args[0],XtNstring,"This is the toplevel window.\n\n\nIt should have one child.\n\n\nThis child should popup on top of this one.");
	msg=XtCreateManagedWidget("msg",XwstaticTextWidgetClass,toplevel,
					args,1);
	XtRealizeWidget(toplevel);

	/* if you make these lines in the program, olwm will handle it
	   correctly, while twm will handle it correctly iff the user
	   has "RandomPlacement" in the .twmrc or the user places the toplevel
           window within 2 seconds. */
	/* XSync(XtDisplay(toplevel),False);
	sleep(2); */

	child=XtCreatePopupShell("child",shellWidgetClass,toplevel,args,0);

	XtSetArg(args[0],XtNstring,"This is the child window!");
	childtxt=XtCreateManagedWidget("childtxt",XwstaticTextWidgetClass,child,
					    args,1);
	mypopup(child);

	XtMainLoop();
}

mypopup(w)
Widget	w;
{
	XSizeHints	s;
	Window dummy;
	
	(void)XTranslateCoordinates(XtDisplay(toplevel),XtWindow(toplevel),
				    DefaultRootWindow(XtDisplay(toplevel)),
			            0,0,&s.x,&s.y,&dummy);
	s.flags=USPosition; s.x+=30; s.y+=30;
	XtSetArg(args[0],XtNx,s.x);
	XtSetArg(args[1],XtNy,s.y);
	XtSetValues(w,args,2);
	XtPopup(w, XtGrabExclusive);
	XSetNormalHints(XtDisplay(w),XtWindow(w),&s);
}