Skip to content

Commit

Permalink
Fixed: Potential crash during startup
Browse files Browse the repository at this point in the history
Canvas's init function may actually end up destroying the Canvas
(e.g., FSAA mode changes during the startup). Thus Canvas must take
care not to perform any more actions after calling the init callback
function.

Also updated Canvas's parent pointer appropriately when handling a
canvas recreation.
  • Loading branch information
skyjake committed Mar 27, 2013
1 parent 2706ea5 commit 47d853c
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 8 deletions.
2 changes: 2 additions & 0 deletions doomsday/client/include/ui/canvas.h
Expand Up @@ -67,6 +67,8 @@ class Canvas : public QGLWidget
*/
void setInitFunc(void (*canvasInitializeFunc)(Canvas&));

void setParent(CanvasWindow *parent);

/**
* Sets the callback function that is called when the window's focus state changes.
* The callback is given @c true or @c false as argument, with
Expand Down
21 changes: 13 additions & 8 deletions doomsday/client/src/ui/canvas.cpp
Expand Up @@ -186,12 +186,10 @@ void Canvas::setInitFunc(void (*canvasInitializeFunc)(Canvas&))
d->initCallback = canvasInitializeFunc;
}

/*
void Canvas::setDrawFunc(void (*canvasDrawFunc)(Canvas&))
void Canvas::setParent(CanvasWindow *parent)
{
d->drawCallback = canvasDrawFunc;
d->parent = parent;
}
*/

void Canvas::setFocusFunc(void (*canvasFocusChanged)(Canvas&, bool))
{
Expand All @@ -200,7 +198,6 @@ void Canvas::setFocusFunc(void (*canvasFocusChanged)(Canvas&, bool))

void Canvas::useCallbacksFrom(Canvas &other)
{
//d->drawCallback = other.d->drawCallback;
d->focusCallback = other.d->focusCallback;
}

Expand Down Expand Up @@ -304,17 +301,25 @@ void Canvas::showEvent(QShowEvent* ev)

void Canvas::notifyInit()
{
if(!d->initNotified && d->initCallback)
if(d->initNotified) return;

d->initNotified = true;
if(d->parent)
{
d->initNotified = true;
d->parent->canvasReady(*this);
}

if(d->initCallback)
{
d->initCallback(*this);
d->parent->canvasReady(*this);
// Canvas might be destroyed now.
}
}

void Canvas::paintGL()
{
if(!d->parent) return;

// The parent knows what to draw here (UI widgets).
d->parent->paintCanvas(*this);

Expand Down
1 change: 1 addition & 0 deletions doomsday/client/src/ui/canvaswindow.cpp
Expand Up @@ -196,6 +196,7 @@ void CanvasWindow::recreateCanvas()
// We'll re-trap the mouse after the new canvas is ready.
d->mouseWasTrapped = canvas().isMouseTrapped();
canvas().trapMouse(false);
canvas().setParent(0);

// Create the replacement Canvas. Once it's created and visible, we'll
// finish the switch-over.
Expand Down

0 comments on commit 47d853c

Please sign in to comment.