Bug: destroying a widget

wacom

23-02-2008 23:20:09

Hallo,

when I use sheet->removeAndDestroyChild("NameOfWindow") or guiManager->destroyWidget("NameOfWindow") to remove a window by clicking on a button in it, the app crashes. That's probably because the widget of the button doesn't exist any more, but it still seems to receive an event (strange enough, Widget::drag() gets called).

I used sheet->removeChild() instead, but that has the effect to not work after some time, because after I created the window a second time (with the same name), it wasn't found with sheet->getChildWidget().

So what shall I do?

kungfoomasta

24-02-2008 02:42:51

The widget of a button? What type of Widget is being destroyed?

The GUIManager stores a map of all unique names used for Widgets. Since removing a child widget does not destroy it, the GUIManager still has reference to the name. When you try to create the window a second time, instead of throwing an exception, a unique name is generated for the widget and used instead. I'll change this so that an exception is thrown.

For the destruction issue, can you provide a call stack, or code so I can reproduce it and debug?

wacom

24-02-2008 09:32:02

The widget of a button? What type of Widget is being destroyed?

A window. The button is on the window. The button has an eventhandler which closes (destroys) the window.

This is the relevant callstack:


QuickGUI_d.dll!QuickGUI::GUIManager::getMouseCursor() Line 243 + 0x3 Bytes C++
QuickGUI_d.dll!QuickGUI::Widget::drag(const float & pixelX=3.0000000, const float & pixelY=-1.0000000) Line 435 + 0x12 Bytes C++
QuickGUI_d.dll!QuickGUI::GUIManager::injectMouseMove(const int & xPixelOffset=3, const int & yPixelOffset=-1) Line 580 C++
xxxxx.exe!GraphicalUserInterface::injectMouseMove(const int & X=3, const int & Y=-1) Line 27 + 0x16 Bytes C++


As you can see, it crashes not when clicking the button (the window gets destroyed as it should), but when moving the mouse afterwards.

BTW, I solved the issue myself by destroying the window this way:


mSheet->removeChild(windowName);
mGUIManager->destroyWidget(windowName);
mGUIManager->notifyNameFree(windowName);

kungfoomasta

24-02-2008 17:43:50

That works. :)

I'm wondering why its crashing. Normally the close button hides the window, but you added a handler to destroy the window also, right? Can you give me the code to setup the window, so I can see why the window is being dragged while its being destroyed? (sounds like an odd scenario to me)

wacom

25-02-2008 11:40:54

I'm wondering why its crashing. Normally the close button hides the window, but you added a handler to destroy the window also, right?

No, I have a custom button, which does some stuff plus destroying the window (so it only has one event handler).

Can you give me the code to setup the window, so I can see why the window is being dragged while its being destroyed? (sounds like an odd scenario to me)

Nothing fancy, I guess:


std::string windowName("ChooseCharacterMenu");
QuickGUI::Window *window = (QuickGUI::Window*)mSheet->getChildWidget(windowName);

// the choose type window can be destroyed after use

if (window)
return;

QuickGUI::Button* butt = 0;
float w = 320.0f, bh = 28.0f, bi = 22.0f, bw = w-bi-bi, next = bi; // "bi" = button interspace

window = mSheet->createWindow(windowName);
window->setMovingEnabled(false);
window->allowResizing(false);
window->hideTitlebar();

butt = window->createButton(windowName + "/Hunter");
butt->setDimensions(QuickGUI::Rect(bi, next, bw/2.0f - bi/2.0f, bh));
butt->setText("Hunter");
butt->addEventHandler(QuickGUI::Widget::EVENT_MOUSE_BUTTON_UP, &UserInterface::eventHandler_ClickButton_ChooseHunter, this);

butt = window->createButton(windowName + "/Prey");
butt->setDimensions(QuickGUI::Rect(bi + bi/2.0f + bw/2.0f, next, bw/2.0f - bi/2.0f, bh));
butt->setText("Prey");
butt->addEventHandler(QuickGUI::Widget::EVENT_MOUSE_BUTTON_UP, &UserInterface::eventHandler_ClickButton_ChoosePrey, this);

next += bh+bi;

butt = window->createButton(windowName + "/Back");
butt->setDimensions(QuickGUI::Rect(bi + 3.0f*bw/8.0f, next, bw/4.0f, bh));
butt->setText("Back");
butt->addEventHandler(QuickGUI::Widget::EVENT_MOUSE_BUTTON_UP, &UserInterface::eventHandler_ClickButton_Back, this);
next += bh+bi;

window->setDimensions(QuickGUI::Rect((mManager->getViewportWidth()-w)/2.0f, mManager->getViewportHeight()-next-10.0f, w, next)); // "next" is now the height of the window

kungfoomasta

25-02-2008 17:59:29

So all 3 buttons destroy the window?

What does the code for the handlers look like?

Thanks for providing most the code, its probably an easy repro like you say. If this is the case, it should be easy to fix. :)

wacom

25-02-2008 20:58:17

The event handlers call some functions which ultimately called mSheet->removeAndDestroyChild(windowName) - there really wasn't any other QUickGUI-related in that code. But I changed the code.
Somehow I think my problems lie deeper, because I always have some problems with mouse movement. Hmm. :/