[comp.windows.x] Motif XtDestroyWidget problem!

reha@cunixf.cc.columbia.edu (Reha Elci) (05/08/90)

XtDestroyWidget does not seem to work properly with Motif. For one thing
Motif uses amazing amounts of memory for widgets; create a bulletin
board with one button and 10 text widgets; you have used over 100K of memory
(in Ultrix)! What is even worse is that you cannot seem to free this space!
In a simple program where you create and destroy this set, each increment
causes a memory leak of 66K. Has anybody else encountered this problem?
The same problem occurs on Sparc's as well so it is not platform dependent.
XtUnrealizeWidget or even trying to destory each child widget does not solve
the problem. This makes the toolkit unusable in large applications. I have
a complicated window with over 100 widgets and it allocates 2M of memory
compared to DECwindows' 100K (at least DECwindows frees properly). Here is
the sample code (when you press the main button, it should create and free
a bulletin board):

#include <stdio.h>
#include "Xm/BulletinB.h"
#include "Xm/PushB.h"
#include "Xm/MainW.h"
#include <X11/Shell.h>

Widget appShell;

Widget current=NULL;

void createBulletinBoard()
  {
   Arg alist[20];
   int n;
   XmString title;
   Widget w;

   if (current)
     XtDestroyWidget(current);

   title=XmStringCreate("  Test BulletinBoard  ",XmSTRING_DEFAULT_CHARSET);
   n=0;
   XtSetArg(alist[n],XmNwidth,300); n++;
   XtSetArg(alist[n],XmNheight,400); n++;
   XtSetArg(alist[n],XmNunitType,XmPIXELS); n++;
   XtSetArg(alist[n],XmNdialogStyle,XmDIALOG_MODELESS); n++;
   XtSetArg(alist[n],XmNdefaultPosition,True); n++;
   XtSetArg(alist[n],XmNresize,XmRESIZE_NONE); n++;
   XtSetArg(alist[n],XmNdialogTitle,title); n++;
   XtSetArg(alist[n],XmNautoUnmanage,False); n++;
   XtSetArg(alist[n],XmNborderWidth,0); n++;
   XtSetArg(alist[n],XmNnoResize,True); n++;
   current=XmCreateBulletinBoardDialog(appShell,"test",alist,n);
   XtManageChild(current);
   XmStringFree(title);

   title=XmStringCreate("SomeButton",XmSTRING_DEFAULT_CHARSET);
   n=0;
   XtSetArg(alist[n],XmNx,10); n++;
   XtSetArg(alist[n],XmNy,10); n++;
   XtSetArg(alist[n],XmNlabelString,title); n++;
   XtSetArg(alist[n],XmNrecomputeSize,True); n++;
   w=XmCreatePushButton(current,"button1",alist,n);
   XtManageChild(w);
   XmStringFree(title);
  }

main(argc,argv)
 int argc;
 char **argv;
  {
   XtAppContext app;
   Display *disp;
   Widget w;
   Arg alist[10];
   int n;
   XmString l;
   XtCallbackRec cb[2];

   XtToolkitInitialize(); 
   app=XtCreateApplicationContext();
   disp=XtOpenDisplay(app,NULL,"Test","Test",NULL,0,&argc,argv);

   n=0;
   XtSetArg(alist[n],XmNwidth,200); n++;
   XtSetArg(alist[n],XmNheight,100); n++;
   appShell=XtAppCreateShell("test","test",
         applicationShellWidgetClass,disp,alist,n);

   cb[0].callback=createBulletinBoard;
   cb[0].closure=NULL;
   cb[1].callback=NULL;
   cb[1].closure=NULL;

   l=XmStringCreate(" Create New Dialog ",XmSTRING_DEFAULT_CHARSET);
   n=0;
   XtSetArg(alist[n],XmNactivateCallback,cb); n++;
   XtSetArg(alist[n],XmNlabelString,l); n++;
   XtSetArg(alist[n],XmNrecomputeSize,True); n++;
   w=XmCreatePushButton(appShell,"new_button",alist,n);
   XtManageChild(w);
   XmStringFree(l);

   XtRealizeWidget(appShell);

   XtAppMainLoop(app);
  }

If anybody has any solutions please post or email. Thanks a lot...

Reha Elci

dpb@viking.UUCP (Don Bennett 433-3311, 408) (05/29/90)

> XtDestroyWidget does not seem to work properly with Motif. For one thing
> Motif uses amazing amounts of memory for widgets; create a bulletin
> board with one button and 10 text widgets; you have used over 100K of memory
> (in Ultrix)! What is even worse is that you cannot seem to free this space!
> In a simple program where you create and destroy this set, each increment
> causes a memory leak of 66K. Has anybody else encountered this problem?
> The same problem occurs on Sparc's as well so it is not platform dependent.
> XtUnrealizeWidget or even trying to destory each child widget does not solve
> the problem. This makes the toolkit unusable in large applications. I have
> a complicated window with over 100 widgets and it allocates 2M of memory
> compared to DECwindows' 100K (at least DECwindows frees properly). Here is
> the sample code (when you press the main button, it should create and free
> a bulletin board):

The problem is not in Motif, it is a bug in the R3 intrinsics.

XtInstallAccelerators() merges the bulletin-board accelerators
into the translations of each of its children, and this merged table
is never freed. My fix was to:
(a) clear the source widget in the action record,
(b) cache the merged table,
(c) record the source widget in an application context,
(d) modify _XtTranslateEvent() to find the source widget in 
    the application context if necessary;
(e) Delete the context record when the destination widget is
    destroyed.

I'll send you the fix I use if you drop me a line.
No guarentees, but it works for me.

   Don Bennett           (408)433-3311
   dpb@frame.com
   Frame Technology