|
Top Document: comp.windows.x.intrinsics Frequently Asked Questions (FAQ) Previous Document: 9. Why doesn't my widget get destroyed when I call XtDestroyWidget()? Next Document: 11. How do I resize a Shell widget? See reader questions & answers on this topic! - Help others by sharing your knowledge
----------------------------------------------------------------------
The problem is if a simple and entirely reasonable approach to exiting
an application is used, such as calling exit() directly, then a widget
may not have a chance to clean up any external state -- such as open
sockets, temporary files, allocated X resources, etc. (this code for
simplicity reasons assumes only a single toplevel widget):
Widget
ToplevelGet (gw)
Widget gw; /* widget to find toplevel */
{
Widget top;
for (top = gw; XtParent (top); top = XtParent (top))
/* empty */;
return (top);
}
void
ExitCallback (gw, closure, call_data)
Widget gw; /* widget */
XtPointer closure; /* data the app specified */
XtPointer call_data; /* widget specific data */
{
Widget toplevel;
toplevel = ToplevelGet (gw);
XtUnmapWidget (toplevel); /* make it disappear quickly */
XtDestroyWidget (toplevel);
exit (0);
}
One can see that the above code exit's immediately after destroying
the toplevel widget. The trouble is the phase 2 destruction may never
occur.
This works for most widgets and most applications but will not work
for those widgets that have any external state. You might think that
since it works now it will always work but remember that part of the
reason an object oriented approach is used is so one can be ignorant
of the implementation details for each widget. Which means that the
widget may change and someday require that some external state is
cleaned up by the Destroy callbacks.
One alternative is to modify ExitCallback() to set a global flag and
then test for that flag in a private event loop.
Or try the following code:
#include <X11/Intrinsic.h>
extern Widget ToplevelGet (
#if NeedFunctionPrototypes
Widget gw
#endif
);
extern Boolean ExitWorkProc (
#if NeedFunctionPrototypes
XtPointer closure
#endif
);
extern void ExitCallback (
#if NeedFunctionPrototypes
Widget gw,
XtPointer closure,
XtPointer call_data
#endif
);
Widget
ToplevelGet (gw)
Widget gw; /* widget to find toplevel */
{
Widget top;
for (top = gw; XtParent (top); top = XtParent (top))
/* empty */;
return (top);
}
void
ExitCallback (gw, closure, call_data)
Widget gw; /* widget */
XtPointer closure; /* data the app specified */
XtPointer call_data; /* widget specific data */
{
Widget toplevel;
toplevel = ToplevelGet (gw);
XtUnmapWidget (toplevel); /* make it disappear quickly */
XtDestroyWidget (toplevel);
XtAppAddWorkProc (XtWidgetToApplicationContext (gw),
ExitWorkProc, (XtPointer) NULL);
}
Boolean
ExitWorkProc (closure)
XtPointer closure;
{
exit (0);
/*NOTREACHED*/
}
ExitCallback() adds a work procedure that will get called when the
application is next idle -- which happens after all the events are
processed and the destroy callbacks are executed.
User Contributions:Top Document: comp.windows.x.intrinsics Frequently Asked Questions (FAQ) Previous Document: 9. Why doesn't my widget get destroyed when I call XtDestroyWidget()? Next Document: 11. How do I resize a Shell widget? Single Page [ Usenet FAQs | Web FAQs | Documents | RFC Index ] Send corrections/additions to the FAQ Maintainer: ware@cis.ohio-state.edu
Last Update March 27 2014 @ 02:11 PM
|

Comment about this article, ask questions, or add new information about this topic: