[comp.windows.x] destroyCallback under R4 Athena Widgets

spanki@color.ced.berkeley.edu (Frank Goodman) (02/22/90)

It's me again...

I'm still working on implementing a widget of my own design under athena.

My Widget has a bunch of stuff that needs to be released/freed before it dies, 
including the removal of a tmp file.

In my widget's .c file is as follows:

.
.
.
static void Destroy();
.
.
.


MyWidgetClassRec myWidgetClassRec = {
.
.
.
/* visible_interest         */      FALSE,
/* destroy                  */      Destroy,
.
.
.
}

static void Destroy(w, call, client)
   {
   printf(I'm in Destroy...\n);
   fflush(stdout);
   /*
    * free my widget stuff
    * remove temp file
    */
   }


My Application Exit function looks like this:

void Exit(status)
    int status;
    {
    XtUnmapWidget(top);
    XtDestroyApplicationContext(XtWidgetToApplicationContext(top));
    exit(status);
    }

However,
   My widget's destroy function is never getting called. Am I missing something
   here? I've tried explicitly calling XtDestroyWidget(myWidget), before
   the XtDestroyAppl call in Exit, and I've also tried not defining the
   Destroy callback in the WidgetRec, but using XtAddCallback in the
   Initializes routine of my widget. None of these work? What am I doing
   wrong?

Considering all the discussion about memeory leaks, this seems pretty
important.

---------------------------------------------------------------------------
Frank  Goodman				arpa:  spanki@CED.Berkeley.EDU
University of California, Berkeley	  or:  spanki%CED@jade.Berkeley.EDU
College of Environmental Design		uucp:  ...hplabs!ucbvax!ced!spanki 
S.I.S Research Laboratory	 	phone: Novelty item, not necessary
---------------------------------------------------------------------------

asente@decwrl.dec.com (Paul Asente) (02/22/90)

In article <1990Feb21.195029.27391@agate.berkeley.edu> spanki@color.ced.berkeley.edu (Frank Goodman) writes:
> [That his widget's destroy procedure doesn't get called when he does]
>
>void Exit(status)
>    int status;
>    {
>    XtUnmapWidget(top);
>    XtDestroyApplicationContext(XtWidgetToApplicationContext(top));
>    exit(status);
>    }

That's right.  Destroying an application context does not destroy the
widgets created for displays on that context; you must destroy them
explicitly.

>   I've tried explicitly calling XtDestroyWidget(myWidget), before
>   the XtDestroyAppl call in Exit, and I've also tried not defining the
>   Destroy callback in the WidgetRec, but using XtAddCallback in the
>   Initializes routine of my widget. None of these work? What am I doing
>   wrong?

You're not waiting long enough :-)

When you call XtDestroyWidget from within a procedure called as a result
of event dispatching (i.e. an event handler, an action procedure, or any
procedure called from one of these) the widget is marked as being
destroyed but is not actually destroyed.  This prevents the widget data
structures from disappearing out from under the event dispatcher.  When
the current event dispatch is complete, the widgets are actually
destroyed.  This includes calling their XtNdestroyCallback callbacks and
their Destroy procedures.  In your case, since you were exiting the
program before returning from the event dispatch, the widgets were not
actually destroyed.

In this case you probably want to do something like just setting a global
flag when you decide to exit and to have a custom event dispatching loop
that tests this flag.

	-paul asente
	    asente@decwrl.dec.com	decwrl!asente