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: