when a Layer or WinBorder is deleted, the RootLayer gets a chance to set some important pointers it keeps arround to NULL. It is not unlikely that this improves stability a bit.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13534 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2005-07-07 14:04:29 +00:00
parent ab8594e073
commit a5ca645e49
3 changed files with 35 additions and 4 deletions

View File

@ -1356,7 +1356,7 @@ fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_M
winBorderUnder = (WinBorder*)fEventMaskLayer;
}
} else {
if (fLastMouseMoved != target) {
if (fLastMouseMoved && fLastMouseMoved != target) {
fViewAction = B_EXITED_VIEW;
if (fLastMouseMoved->fOwner) {
if (fLastMouseMoved != fLastMouseMoved->fOwner->fTopLayer) {
@ -1831,6 +1831,21 @@ RootLayer::SetEventMaskLayer(Layer *lay, uint32 mask, uint32 options)
return returnValue;
}
// LayerRemoved
void
RootLayer::LayerRemoved(Layer* layer)
{
if (layer == fEventMaskLayer) {
fEventMaskLayer = NULL;
}
if (layer == fLastMouseMoved) {
fLastMouseMoved = NULL;
}
if (layer == fMouseTargetWinBorder) {
fMouseTargetWinBorder = NULL;
}
}
void
RootLayer::SetDragMessage(BMessage* msg)
{

View File

@ -123,6 +123,8 @@ public:
bool SetEventMaskLayer(Layer *lay, uint32 mask, uint32 options);
void LayerRemoved(Layer* layer);
static int32 WorkingThread(void *data);
CursorManager& GetCursorManager() { return fCursorManager; }

View File

@ -103,6 +103,13 @@ ServerWindow::~ServerWindow()
if (!fWinBorder->IsOffscreenWindow())
gDesktop->RemoveWinBorder(fWinBorder);
// just to be safe
RootLayer* rootLayer = fWinBorder->GetRootLayer();
if (rootLayer && rootLayer->Lock()) {
rootLayer->LayerRemoved(fWinBorder);
rootLayer->Unlock();
}
delete fWinBorder;
free(const_cast<char *>(fTitle));
@ -639,9 +646,15 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
fCurrentLayer->RemoveSelf();
fCurrentLayer->PruneTree();
if (invalidRegion && myRootLayer) {
myRootLayer->GoInvalidate(parent, *invalidRegion);
delete invalidRegion;
if (myRootLayer) {
myRootLayer->LayerRemoved(fCurrentLayer);
// trigger update
if (invalidRegion) {
myRootLayer->GoInvalidate(parent, *invalidRegion);
delete invalidRegion;
}
}
#ifdef DEBUG_SERVERWINDOW
@ -650,6 +663,7 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
STRACE(("DONE: ServerWindow %s: Message AS_DELETE_LAYER: Parent: %s Layer: %s\n", fTitle, parent->Name(), fCurrentLayer->Name()));
delete fCurrentLayer;
// TODO: It is necessary to do this, but I find it very obscure.
fCurrentLayer = parent;
break;
}