diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/newview/llconversationmodel.cpp | 26 | ||||
| -rw-r--r-- | indra/newview/llfloaterimsessiontab.cpp | 45 | 
2 files changed, 55 insertions, 16 deletions
| diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp index 4335168417..4cd85ac756 100644 --- a/indra/newview/llconversationmodel.cpp +++ b/indra/newview/llconversationmodel.cpp @@ -357,22 +357,20 @@ void LLConversationItemSession::clearParticipants()  void LLConversationItemSession::clearAndDeparentModels()  { -    std::for_each(mChildren.begin(), mChildren.end(), -        [](LLFolderViewModelItem* c) +    for (LLFolderViewModelItem* child : mChildren) +    { +        if (child->getNumRefs() == 0)          { -            if (c->getNumRefs() == 0) -            { -                // LLConversationItemParticipant can be created but not assigned to any view, -                // it was waiting for an "add_participant" event to be processed -                delete c; -            } -            else -            { -                // Model is still assigned to some view/widget -                c->setParent(NULL); -            } +            // LLConversationItemParticipant can be created but not assigned to any view, +            // it was waiting for an "add_participant" event to be processed +            delete child;          } -    ); +        else +        { +            // Model is still assigned to some view/widget +            child->setParent(NULL); +        } +    }      mChildren.clear();  } diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index dc64d09f9f..aaf839c50c 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -102,6 +102,26 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)  LLFloaterIMSessionTab::~LLFloaterIMSessionTab()  {      delete mRefreshTimer; + +    LLFloaterIMContainer* im_container = LLFloaterIMContainer::findInstance(); +    if (im_container) +    { +        LLParticipantList* session = dynamic_cast<LLParticipantList*>(im_container->getSessionModel(mSessionID)); +        if (session) +        { +            for (const conversations_widgets_map::value_type& widget_pair : mConversationsWidgets) +            { +                LLFolderViewItem* widget = widget_pair.second; +                LLFolderViewModelItem* item_vmi = widget->getViewModelItem(); +                if (item_vmi && item_vmi->getNumRefs() == 1) +                { +                    // This is the last pointer, remove participant from session +                    // before participant gets deleted on destroyView. +                    session->removeChild(item_vmi); +                } +            } +        } +    }  }  // static @@ -663,9 +683,30 @@ void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& part      LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id);      if (widget)      { +        LLFolderViewModelItem* item_vmi = widget->getViewModelItem(); +        if (item_vmi && item_vmi->getNumRefs() == 1) +        { +            // This is the last pointer, remove participant from session +            // before participant gets deleted on destroyView. +            //  +            // Floater (widget) and participant's view can simultaneously +            // co-own the model, in which case view is responsible for +            // the deletion and floater is free to clear and recreate +            // the list, yet there are cases where only widget owns +            // the pointer so it should do the cleanup. +            // See "add_participant". +            // +            // Todo: If it keeps causing issues turn participants +            // into LLPointers in the session  +            LLParticipantList* session = getParticipantList(); +            if (session) +            { +                session->removeChild(item_vmi); +            } +        }          widget->destroyView(); -    } -    mConversationsWidgets.erase(participant_id); +	} +	mConversationsWidgets.erase(participant_id);  }  void LLFloaterIMSessionTab::updateConversationViewParticipant(const LLUUID& participant_id) | 
