diff --git a/src/servers/app/RootLayer.cpp b/src/servers/app/RootLayer.cpp index f91e83841f..aa1f847e11 100644 --- a/src/servers/app/RootLayer.cpp +++ b/src/servers/app/RootLayer.cpp @@ -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) { diff --git a/src/servers/app/RootLayer.h b/src/servers/app/RootLayer.h index f0d92d8d21..6485fbb07b 100644 --- a/src/servers/app/RootLayer.h +++ b/src/servers/app/RootLayer.h @@ -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; } diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index 96ecee261e..88d0d213e5 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -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(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; }