[comp.windows.x.motif] Changing the pointer in ALL windows

theslim@engin.umich.edu (Eric Michael Slimko) (04/28/91)

I am writing a motif application which has many top-level windows.
I would like to have the pointer change to a watch in all those windows
to notify the user to wait.  Unfotunately, it looks to me like you have
to do a XDefineCursor using the window ID for EACH of the popup windows
to get that to happen.  Is there anyway around this?  I tried using the
toplevel widget returned from XtInitialize, but that only changes the
pointer for that window.  

Thanks in advance,
Eric Slimko

markus@hcmv2.ti.com (Markus Richardson) (05/01/91)

theslim@engin.umich.edu (Eric Michael Slimko) writes:

>I am writing a motif application which has many top-level windows.
>I would like to have the pointer change to a watch in all those windows
>to notify the user to wait.  Unfotunately, it looks to me like you have
>to do a XDefineCursor using the window ID for EACH of the popup windows
>to get that to happen.  Is there anyway around this?  I tried using the
>toplevel widget returned from XtInitialize, but that only changes the
>pointer for that window.  

I have been fighting with this one too!

I chose to create an InputOnly window with its pointer defined as a
stopwatch.  By mapping the window, all user-generated input events 
can be safely ignored until the processing is completed upon which the
window is unmapped.

But I get the same behavior as Eric is having :-(  I have even tried
to force it to be the top window in the stacking order as well as setting
the override_redirect window resource to True.  Both attempts made no
difference.  Here is [the perintent portions of] my code:


To initialize the shells and InputOnly window and cursor:

	...

	[ the first top level shell created here ]
	...

	XSetWindowAttributes attr;
	attr.override_redirect = True;
	Dimension x, y, width, height;
	argcnt = 0;
	XtSetArg(args[argcnt], XmNx, &x); argcnt++;
	XtSetArg(args[argcnt], XmNy, &y); argcnt++;
	XtSetArg(args[argcnt], XmNwidth, &width); argcnt++;
	XtSetArg(args[argcnt], XmNheight, &height); argcnt++;
	XtGetValues(Top_app_shell, args, argcnt);
	Wait_window = XCreateWindow(Main_display, Main_window, x, y, 
		width, height, 0, 0, InputOnly, 
		DefaultVisualOfScreen(Main_screen),
		CWOverrideRedirect, &attr);

	Wait_cursor = XCreateFontCursor(Main_display, XC_watch);
	XDefineCursor(Main_display, Wait_window, Wait_cursor);

	...

	[ other top level application shells created here ]
	...

And when extended processing is about to occur:

	XMapRaised(Main_display, Wait_window);
	XmUpdateDisplay(Top_widget);

And when processing is completed:

	XUnmapWindow(Main_display, Wait_window);


It works fine when the mouse pointer is in the "Wait_window", but
the pointer changes back when in other top level shells.  Are the
other shell windows overriding the XMapRaised call?  I thought it might
be mwm getting in the way, so I ran it with no wm but no difference.

Thanks for any pointers :-)

In case it matters, I'm running Motif v1.1.1

--
Markus R.  (markus@ti.com)

"If people built houses the way we write programs, the first woodpecker 
 would wipe out civilization"  _The Cuckoo's Egg_ by Cliff Stoll

ssn@modulex.dk (Svend Skafte Nielsen) (05/01/91)

theslim@engin.umich.edu (Eric Michael Slimko) writes:

>I am writing a motif application which has many top-level windows.
>I would like to have the pointer change to a watch in all those windows
>to notify the user to wait.  Unfotunately, it looks to me like you have
>to do a XDefineCursor using the window ID for EACH of the popup windows
>to get that to happen.  Is there anyway around this?  I tried using the
>toplevel widget returned from XtInitialize, but that only changes the
>pointer for that window.  

>Thanks in advance,
>Eric Slimko

   You can possibly use "XGrabPointer" on the rootwindow instead.


---------------------------------------------------
Svend Skafte Nielsen    | Email:    ssn@modulex.dk
A/S MODULEX		| Phone:    +45 44 53 30 11
Lyskaer 15		| Telefax:  +45 44 53 30 74
DK-2730 Herlev		|
Denmark			|

aw@BAE.BELLCORE.COM (Andrew Wason) (05/01/91)

agate!bionet!uwm.edu!cs.utexas.edu!csc.ti.com!ti-csl!m2.csc.ti.com!hcmv2!markus
@ucbvax.Berkeley.EDU (Markus Richardson) writes:
> theslim@engin.umich.edu (Eric Michael Slimko) writes:
> 
> >I am writing a motif application which has many top-level windows.
> >I would like to have the pointer change to a watch in all those windows
> >to notify the user to wait.  Unfotunately, it looks to me like you have
> >to do a XDefineCursor using the window ID for EACH of the popup windows
> >to get that to happen.  Is there anyway around this?  I tried using the
> >toplevel widget returned from XtInitialize, but that only changes the
> >pointer for that window.  
> 
> I have been fighting with this one too!

Try mapping an InputOnly window on top of *all* of your toplevel
windows.  Give it a watch cursor.

Do something like the following for all of your toplevel widgets
after they are realized:


typedef struct _BusyWindowRec {
    Window window;              /* busy window */
    Widget w;                   /* widget which needs the busy window */
} BusyWindowRec, *BusyWindow;


void
CreateBusyWindow(busy)
BusyWindow busy;
{
    unsigned long valueMask;
    XSetWindowAttributes attributes;

    /*
     *Ignore device events while the busy cursor is displayed.
     */
    valueMask = CWDontPropagate | CWCursor;
    attributes.do_not_propagate_mask =  (KeyPressMask | KeyReleaseMask |
                                         ButtonPressMask | ButtonReleaseMask |
                                         PointerMotionMask);
    attributes.cursor = appData.busy_cursor;

    /*
     * The window will be as big as the display screen, and clipped by
     * it's own parent window, so we never have to worry about resizing.
     * (well, almost never)
     */
    busy->window =  XCreateWindow(XtDisplay(busy->w), XtWindow(busy->w), 0, 0,
                                  WidthOfScreen(XtScreen(busy->w)),
                                  HeightOfScreen(XtScreen(busy->w)),
                                  (unsigned int) 0, CopyFromParent, InputOnly,
                                  CopyFromParent, valueMask, &attributes);
}


Andrew

_______________________________________________________________________________

Andrew Wason                                       Bell Communications Research
aw@bae.bellcore.com                                Piscataway, NJ
bellcore!bae!aw

steve@mnetor.UUCP (Steve Rees) (05/02/91)

I believe the only way to do this is to have a 'watch' window for each
shell in your application.  The server clips the 'watch' window to its
parent _window_, not application.  It knows diddly about your hierarchy,
which is maintained/organized/etc. on the client end.  To show the watch,
map & raise all 'watch' windows.

Good luck, and let us know if you find a better way.
-- 
    Steve Rees
{uunet|utzoo}!mnetor!steve or (better) steve%mnetor.uucp@uunet.uu.net
Ma Bell: +1 416 475 8980  ext. 322
					Why isn't ping pong called pik pok?

masa@hpsciz.sc.hp.com (Masayoshi Habu) (05/03/91)

In comp.windows.x.motif, theslim@engin.umich.edu (Eric Michael Slimko) writes:

    I am writing a motif application which has many top-level windows.
    I would like to have the pointer change to a watch in all those windows
    to notify the user to wait.  Unfotunately, it looks to me like you have
    to do a XDefineCursor using the window ID for EACH of the popup windows
    to get that to happen.  Is there anyway around this?  I tried using the
    toplevel widget returned from XtInitialize, but that only changes the
    pointer for that window.  

As far as I know, that's correct. So I ended up with writing a little
extra code which maintains a list of windows and when asked, change
the cursor of all those windows to either a watch or an arrow.

Masa Habu
HP Santa Clara Div.

toml@marvin.Solbourne.COM (Tom LaStrange) (05/11/91)

|>     I am writing a motif application which has many top-level windows.
|>     I would like to have the pointer change to a watch in all those windows
|>     to notify the user to wait.  Unfotunately, it looks to me like you have
|>     to do a XDefineCursor using the window ID for EACH of the popup windows
|>     to get that to happen.  Is there anyway around this?  I tried using the
|>     toplevel widget returned from XtInitialize, but that only changes the
|>     pointer for that window.  
|> 
|> As far as I know, that's correct. So I ended up with writing a little
|> extra code which maintains a list of windows and when asked, change
|> the cursor of all those windows to either a watch or an arrow.


It's much much easier than that.  You could simply create a large InputOnly
window as a child of your top-level window, set the cursor to whatever
you want and XMapRaised the thing.  Simply unmap it to get rid of
your cursor.  I'm not an Xt user so I can't tell you if there are any problems
with this approach.

--
(I kid you not)Tom LaStrange        toml@Solbourne.COM

beau1029@mstr.hgc.edu (donald beaudry) (05/14/91)

Look in the FAQ under comp.windows.x.  With very few lines of code, it is
easy to create an input-only window the size of the entire screen.  That
window is a child of the toplevel shell's window, and is clipped to the
size of its window.  The input-only window is the size of the screen to
handle any resizing of your toplevel shell.

Now simply XDefineCursor() a suitable busy cursor for the input-only window.  
When your app is busy, map the window.