diff --git a/headers/private/app/ServerProtocol.h b/headers/private/app/ServerProtocol.h index efc4aa1f79..6fd75a7bd2 100644 --- a/headers/private/app/ServerProtocol.h +++ b/headers/private/app/ServerProtocol.h @@ -234,7 +234,6 @@ enum { AS_LAYER_CREATE, AS_LAYER_DELETE, AS_LAYER_CREATE_ROOT, - AS_LAYER_DELETE_ROOT, AS_LAYER_ADD_CHILD, AS_LAYER_REMOVE_CHILD, AS_LAYER_REMOVE_SELF, diff --git a/src/kits/interface/View.cpp b/src/kits/interface/View.cpp index a1c6476d33..3df94d6650 100644 --- a/src/kits/interface/View.cpp +++ b/src/kits/interface/View.cpp @@ -3369,18 +3369,23 @@ BView::RemoveSelf() // Remove this child from its parent - if (fOwner && fOwner->Lock()) { - BLooper* owner = fOwner; + BWindow* owner = fOwner; + check_lock_no_pick(); + if (owner != NULL) { _UpdateStateForRemove(); _Detach(); - - owner->Unlock(); } if (!fParent || !fParent->_RemoveChildFromList(this)) return false; + if (owner != NULL && fTopLevelView) { + // the top level view is deleted by the app_server automatically + owner->fLink->StartMessage(AS_LAYER_DELETE); + owner->fLink->Attach(_get_object_token_(fParent)); + } + STRACE(("DONE: BView(%s)::RemoveSelf()\n", Name())); return true; @@ -3974,7 +3979,7 @@ BView::_CreateSelf() fOwner->fLink->Attach(Flags()); fOwner->fLink->Attach(IsHidden(this)); fOwner->fLink->Attach(fState->view_color); - if (fTopLevelView) + if (fTopLevelView) fOwner->fLink->Attach(B_NULL_TOKEN); else fOwner->fLink->Attach(_get_object_token_(fParent)); @@ -4162,13 +4167,11 @@ BView::_Detach() if (fOwner->fLastViewToken == _get_object_token_(this)) fOwner->fLastViewToken = B_NULL_TOKEN; - BWindow *owner = fOwner; _SetOwner(NULL); - - owner->fLink->StartMessage(AS_LAYER_DELETE); } } + void BView::_Draw(BRect updateRectScreen) { @@ -4406,8 +4409,6 @@ void BView::_ReservedView5(){} void BView::_ReservedView6(){} void BView::_ReservedView7(){} void BView::_ReservedView8(){} - -#if !_PR3_COMPATIBLE_ void BView::_ReservedView9(){} void BView::_ReservedView10(){} void BView::_ReservedView11(){} @@ -4416,7 +4417,6 @@ void BView::_ReservedView13(){} void BView::_ReservedView14(){} void BView::_ReservedView15(){} void BView::_ReservedView16(){} -#endif BView::BView(const BView &other) diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index fcad3df682..d8faa4e165 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -900,15 +900,6 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) //fDesktop->UnlockSingleWindow(); break; - case AS_LAYER_DELETE_ROOT: - { - // Received when a window deletes its internal top view -printf("AS_LAYER_DELETE_ROOT\n"); - // TODO: Implement AS_LAYER_DELETE_ROOT - STRACE(("ServerWindow %s: Message Delete_Layer_Root unimplemented\n", Title())); - break; - } - case AS_GET_MOUSE: { fDesktop->UnlockSingleWindow(); @@ -956,7 +947,8 @@ fDesktop->LockSingleWindow(); case AS_SET_CURRENT_LAYER: { int32 token; - link.Read(&token); + if (link.Read(&token) != B_OK) + break; ViewLayer *current; if (App()->ViewTokens().GetToken(token, B_HANDLER_TOKEN, @@ -1054,27 +1046,31 @@ ServerWindow::_DispatchViewMessage(int32 code, } case AS_LAYER_DELETE: { - // Received when a view is detached from a window. This is definitely - // the less taxing operation - we call PruneTree() on the removed - // layer, detach the layer itself, delete it, and invalidate the - // area assuming that the view was visible when removed - ViewLayer *parent = fCurrentLayer->Parent(); + // Received when a view is detached from a window - STRACE(("ServerWindow %s: AS_LAYER_DELETE view: %p, parent: %p\n", fTitle, - fCurrentLayer, parent)); + int32 token; + if (link.Read(&token) != B_OK) + break; - if (parent != NULL) { - parent->RemoveChild(fCurrentLayer); + ViewLayer *view; + if (App()->ViewTokens().GetToken(token, B_HANDLER_TOKEN, + (void**)&view) == B_OK + && view->Window()->ServerWindow() != this) { + ViewLayer* parent = view->Parent(); - if (fCurrentLayer->EventMask() != 0) { - fDesktop->EventDispatcher().RemoveListener(EventTarget(), - fCurrentLayer->Token()); + STRACE(("ServerWindow %s: AS_LAYER_DELETE view: %p, parent: %p\n", + fTitle, view, parent)); + + if (parent != NULL) { + parent->RemoveChild(view); + + if (view->EventMask() != 0) { + fDesktop->EventDispatcher().RemoveListener(EventTarget(), + token); + } + delete view; } - - delete fCurrentLayer; } - // TODO: It is necessary to do this, but I find it very obscure. - _SetCurrentLayer(parent); break; } case AS_LAYER_SET_STATE: