[comp.windows.x.motif] How does a client...

rtdickerson@lescsse.jsc.nasa.gov (russel dickerson) (03/20/91)

Does anyone know how a motif client can determine if it has
been iconified?  Attempts to get window hints have returned
nothing useful.  Source example would be nice too...

thanks

--
Russell Dickerson          Internet: dickerson@vf.jsc.nasa.gov
Lockheed (LESC), A22       ===================================
SSE System Project         X Windows & Motif on Apollo/PC/Mac
Space Station Freedom      Phone +1 713 283 5193  

lynnes@ALEX.CSS.GOV (Christopher Lynnes) (03/20/91)

>Does anyone know how a motif client can determine if it has
>been iconified?  Attempts to get window hints have returned
>nothing useful.  Source example would be nice too...

	Earlier I suggested getting the XmNiconic resource of the
toplevel shell, but this does not seem to work. On the other hand,
at least under mwm (Motif 1.1, Sun-3), the toplevel shell is unmanaged 
when iconified. The following timer callback checks iconification
using both methods every 5 seconds. The toplevel shell is obtained
via MrmFetchWidget. The first method always prints out that the top
widget is not iconified. The second method correctly identifies whether
it is iconified.
	HOWEVER. I have a sneaking suspicion that this may be
dependent on the window manager, so use with caution.
------------------------------------------------------------------------
#include <Xm/Xm.h>
void CheckIconify(client_data, id)
	caddr_t	client_data;
	XtIntervalId	*id;
{
	Widget	top= (Widget)client_data;
	Arg	arg[1];
	Boolean	is_iconic = 1;

/* Method 1: doesn't work under mwm */
	XtSetArg(arg[0], XmNiconic, &is_iconic);
	XtGetValues(top, arg, 1);
	printf("I am%s an icon?\n", is_iconic ? "" : " NOT");
/* Method 2: works under mwm */
	printf("I am%s an icon!\n\n", XtIsManaged(top) ? " NOT" : "");
	XtAddTimeOut(5000, CheckIconify, client_data);
}
------------------------------------------------------------------------
Chris Lynnes                                ===== : = :::::
Teledyne Geotech                           ===== :: == :::::
Alexandria, Virginia                            ::: ===
(703) 739-7316                                  ::   ==
lynnes@seismo.CSS.GOV                           :     =

wwang@osf.org ("Weidong Wang from OSF") (03/20/91)

  >  
  >  >Does anyone know how a motif client can determine if it has
  >  >been iconified?  Attempts to get window hints have returned
  >  >nothing useful.  Source example would be nice too...
  >  
  >  	Earlier I suggested getting the XmNiconic resource of the
  >  toplevel shell, but this does not seem to work. On the other hand,
  >  at least under mwm (Motif 1.1, Sun-3), the toplevel shell is unmanaged 
  >  when iconified. The following timer callback checks iconification
  >  using both methods every 5 seconds. The toplevel shell is obtained
  >  via MrmFetchWidget. The first method always prints out that the top
  >  widget is not iconified. The second method correctly identifies whether
  >  it is iconified.
  >  	HOWEVER. I have a sneaking suspicion that this may be
  >  dependent on the window manager, so use with caution.
  >  ------------------------------------------------------------------------
  >  #include <Xm/Xm.h>
  >  void CheckIconify(client_data, id)
  >  	caddr_t	client_data;
  >  	XtIntervalId	*id;
  >  {
  >  	Widget	top= (Widget)client_data;
  >  	Arg	arg[1];
  >  	Boolean	is_iconic = 1;
  >  
  >  /* Method 1: doesn't work under mwm */
  >  	XtSetArg(arg[0], XmNiconic, &is_iconic);
  >  	XtGetValues(top, arg, 1);
  >  	printf("I am%s an icon?\n", is_iconic ? "" : " NOT");
  >  /* Method 2: works under mwm */
  >  	printf("I am%s an icon!\n\n", XtIsManaged(top) ? " NOT" : "");
  >  	XtAddTimeOut(5000, CheckIconify, client_data);
  >  }

This code mentioned above may work, but clearly it is not the RIGHT way to do it.
XmNiconic only specifies whether the the application wishes to start as an icon. 
According to the refence manual, it is examined by the Intrinsics only during a call
to XtRealize; it is ignored at all other times. So you can not depend on it.

Here is a right way I think to do it: catch the PropertyNotify event, then use 
XGetWindowProperty() to get the value of WM_STATE. Here is the code:

void propertyCB(w, cd, event)
Widget w;
char *cd;
XPropertyEvent *event;
{
  Arg args[1];
  Boolean iconic;
  Atom actual_type;
  int  actual_format;
  unsigned long nitems, bytes_after;
  unsigned char *data;
  long     *state;

  if (event->type == PropertyNotify) {
    printf("Got PropertyNotify event\n");
    printf("Atom is %s, the state is %d\n", XGetAtomName(dpy, event->atom),
	   event->state);

    XGetWindowProperty(event->display, event->window, event->atom,
		       0L, 1L, False, AnyPropertyType,  &actual_type,
		       &actual_format, &nitems, &bytes_after, &data);

    printf("actual_type: %s, actual_format: %d, nitems: %d, bytes_after: %d\n",
	   XGetAtomName(dpy, actual_type), actual_format, nitems, bytes_after);

    state = (long *)data;
    if (*state == NormalState) printf("NormalState\n");
    if (*state == IconicState) printf("IconicState\n");
    if (*state == WithdrawnState) printf("WithdrawnState\n");

    return;
  }

}


main(argc, argv)
int argc;
char **argv;
{
    XtAppContext app_context;

    topLevel = XtVaAppInitialize(
            &app_context,       /* Application context */
            "Test",            /* Application class */
            NULL, 0,            /* command line option list */
            &argc, argv,        /* command line args */
            NULL,               /* for missing app-defaults file */
            NULL);              /* terminate varargs list */

    XtAddEventHandler(topLevel, PropertyChangeMask, 
		      False, propertyCB, NULL);

    ........
}


--------------------------------
Weidong Wang
Systems Engineering, OSF