"Error in <RootX11ErrorHandler>: BadDrawable&quot

Dear Rooters,

I have written a small Root macro with a GUI and I have some troubles trying to exit from it.

The main requirement is that exiting must not close the Root session, since other processes depend on it. Therefore, I could not simply connect the exit button to some
"gApplication->Terminate(0);".
Instead, I have tried to use something like

where fMain is my TGMainFrame.

This seems to close the window correcly, but immediately after that the Root session (and in fact the whole terminal) crashes with a segfault, telling me

Error in <RootX11ErrorHandler>: BadDrawable (invalid Pixmap or Window parameter) (TGCompositeFrame XID: 62915090, XREQ: 62)
TGCompositeFrame:	62915090
	TGViewPort:	62915081
	TRootEmbeddedCanvas:	62915080
	TGVerticalFrame:	62915079
	TGHorizontalFrame:	62915078

After that follows a stack trace.

Up to now, I have not found any way out of this. What would be the correct way to exit from the macro and have the Root session still alive??

Thank you very much for any help!

Best,

Sven

Hi,

Well, fMain->CloseWindow(); is not sufficient, you have to delete (cleanup) your GUI elements, e.g. in this case the TRootEmbeddedCanvas. You can aslo try to use fMain->SetCleanup(kDeepCleanup).
If you still have problems, please post your code, or at least a snapshot reproducing the problem.

Cheers,
Bertrand.

Dear Bertrand,

sorry, I should maybe have posted a bit more of my code. Of course I do a

fMain->Cleanup();

as well, but it does not seem to help. Also a

fMain->SetCleanup(kDeepCleanup);

does not seem to make any difference.

A very simple example to reproduce the problem is in fact the first example described in the Root Users Guide. I have attached it for easy access. As long as you use the Exit button in this case, everything works fine but the Root session is also quit. However, when you close the window directly, this gives the segfault I have described above. Hence, I could rephrase my question: How would a slot method look like to which I can connect the Exit button and which exits the macro but leaves the Root session alive?

Thanks again for any help,

Sven
example.C (2.1 KB)

Hi Sven,

Here is an example:[code]MyMainFrame::MyMainFrame(const TGWindow *p,UInt_t w,UInt_t h) {
// Create a main frame
fMain = new TGMainFrame(p,w,h);
fMain->SetCleanup(kDeepCleanup);
fMain->Connect(“CloseWindow()”, “MyMainFrame”, this, “DoClose()”);
fMain->DontCallClose(); // to avoid double deletions.
[…]
TGTextButton *exit = new TGTextButton(hframe,"&Exit");
exit->Connect(“Clicked()”,“MyMainFrame”,this,“DoClose()”);
[…]

MyMainFrame::~MyMainFrame() {
// Clean up used widgets: frames, buttons, layouthints
fMain->CloseWindow();
}

void MyMainFrame::DoClose() {
// Close window slot: delete this and really close the window
delete this;
}[/code]
Just try the (modified) script in attachment (it works fine for me on Linux and Windows).

Cheers, Bertrand.
examplebb.C (2.4 KB)

Dear Bertrand,

thank you very much for your example, like this it works!

Cheers,

Sven

Hello,

I’m reviving this thread because I hit a very similar pbm.
I couldn’t adapt the solution proposed above in the case where one use
a TRootEmbeddedCanvas in a class directly inheriting TGMainFrame (rather than in a class embedding a TGMainFrame).

I’m using the attached small script in an interactive session. I do :

g = new TestGui(gClient->GetRoot())
g->init()

then close the gui window which provokes the crash.

I have a similar crash when closing the window when running the tutorial/gui/statusBar.C script.

There’s probably an obvious solution I’ve missed ?

Thanks for any help…
py_testrootembcanvas.C (717 Bytes)

Hi,

Why do you need these lines?:

   int wembCanvas = embCanvas->GetCanvasWindowId();
   TCanvas *c123 =  new TCanvas("c123", 10, 10, wembCanvas);
   embCanvas->AdoptCanvas(c123);

To get the pointer of the TCanvas created in the TRootEmbeddedCanvas, doing this is sufficient:

   TCanvas *c123 = embCanvas->GetCanvas();

And if you really need to create you own canvas, just delete the original one like this:

   delete embCanvas->GetCanvas();
   int wembCanvas = embCanvas->GetCanvasWindowId();
   TCanvas *c123 =  new TCanvas("c123", 10, 10, wembCanvas);
   embCanvas->AdoptCanvas(c123);

Usually, this kind of method: embCanvas->AdoptCanvas(c123); is useful if you have multiple canvases and want to exchange/replace canvases inside a TRootEmbeddedCanvas. But one has to take care of the creation/deletion of these canvases…

Cheers, Bertrand.

[quote]Why do you need these lines?:
[/quote]

Just because I copy-pasted them without taking the time to think about what they mean …

Thanks a lot !

It works fine now.

P.A.