Fix menu leaks and lazy creation in text editing and scroll lists

master
Rye Mutt 2022-10-19 16:23:25 -04:00
parent a48374e8cf
commit bbd8df15de
8 changed files with 69 additions and 37 deletions

View File

@ -209,13 +209,6 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
setPrevalidateInput(p.prevalidate_input_callback());
setPrevalidate(p.prevalidate_callback());
llassert(LLMenuGL::sMenuContainer != NULL);
LLContextMenu* menu = LLUICtrlFactory::instance().createFromFile<LLContextMenu>
("menu_text_editor.xml",
LLMenuGL::sMenuContainer,
LLMenuHolderGL::child_registry_t::instance());
setContextMenu(menu);
}
LLLineEditor::~LLLineEditor()
@ -2637,6 +2630,15 @@ LLWString LLLineEditor::getConvertedText() const
void LLLineEditor::showContextMenu(S32 x, S32 y)
{
LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get());
if (!menu)
{
llassert(LLMenuGL::sMenuContainer != NULL);
menu = LLUICtrlFactory::createFromFile<LLContextMenu>
("menu_text_editor.xml",
LLMenuGL::sMenuContainer,
LLMenuHolderGL::child_registry_t::instance());
setContextMenu(menu);
}
if (menu)
{

View File

@ -196,7 +196,6 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
mHighlightedItem(-1),
mBorder(NULL),
mSortCallback(NULL),
mPopupMenu(NULL),
mCommentTextView(NULL),
mNumDynamicWidthColumns(0),
mTotalStaticColumnWidth(0),
@ -348,6 +347,13 @@ LLScrollListCtrl::~LLScrollListCtrl()
mItemList.clear();
clearColumns(); //clears columns and deletes headers
delete mIsFriendSignal;
auto menu = mPopupMenuHandle.get();
if (menu)
{
menu->die();
mPopupMenuHandle.markDead();
}
}
@ -1997,17 +2003,23 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
// create the context menu from the XUI file and display it
std::string menu_name = is_group ? "menu_url_group.xml" : "menu_url_agent.xml";
delete mPopupMenu;
llassert(LLMenuGL::sMenuContainer != NULL);
mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
menu_name, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
if (mPopupMenu)
auto menu = mPopupMenuHandle.get();
if (menu)
{
menu->die();
mPopupMenuHandle.markDead();
}
llassert(LLMenuGL::sMenuContainer != NULL);
menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
menu_name, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
if (menu)
{
mPopupMenuHandle = menu->getHandle();
if (mIsFriendSignal)
{
bool isFriend = *(*mIsFriendSignal)(uuid);
LLView* addFriendButton = mPopupMenu->getChild<LLView>("add_friend");
LLView* removeFriendButton = mPopupMenu->getChild<LLView>("remove_friend");
LLView* addFriendButton = menu->getChild<LLView>("add_friend");
LLView* removeFriendButton = menu->getChild<LLView>("remove_friend");
if (addFriendButton && removeFriendButton)
{
@ -2016,8 +2028,8 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
}
}
mPopupMenu->show(x, y);
LLMenuGL::showPopup(this, mPopupMenu, x, y);
menu->show(x, y);
LLMenuGL::showPopup(this, menu, x, y);
return TRUE;
}
}

View File

@ -526,7 +526,7 @@ private:
S32 mHighlightedItem;
class LLViewBorder* mBorder;
LLContextMenu *mPopupMenu;
LLHandle<LLContextMenu> mPopupMenuHandle;
LLView *mCommentTextView;

View File

@ -273,6 +273,12 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
LLTextBase::~LLTextBase()
{
mSegments.clear();
LLContextMenu* menu = static_cast<LLContextMenu*>(mPopupMenuHandle.get());
if (menu)
{
menu->die();
mPopupMenuHandle.markDead();
}
delete mURLClickSignal;
delete mIsFriendSignal;
delete mIsObjectBlockedSignal;

View File

@ -257,7 +257,6 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) :
mMouseDownY(0),
mTabsToNextField(p.ignore_tab),
mPrevalidateFunc(p.prevalidate_callback()),
mContextMenu(NULL),
mShowContextMenu(p.show_context_menu),
mEnableTooltipPaste(p.enable_tooltip_paste),
mPassDelete(FALSE),
@ -301,8 +300,13 @@ LLTextEditor::~LLTextEditor()
// Scrollbar is deleted by LLView
std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer());
mUndoStack.clear();
// context menu is owned by menu holder, not us
//delete mContextMenu;
// Mark the menu as dead or its retained in memory till shutdown.
LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get());
if(menu)
{
menu->die();
mContextMenuHandle.markDead();
}
}
////////////////////////////////////////////////////////////
@ -2051,12 +2055,19 @@ void LLTextEditor::setEnabled(BOOL enabled)
void LLTextEditor::showContextMenu(S32 x, S32 y)
{
if (!mContextMenu)
LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get());
if (!menu)
{
llassert(LLMenuGL::sMenuContainer != NULL);
mContextMenu = LLUICtrlFactory::instance().createFromFile<LLContextMenu>("menu_text_editor.xml",
menu = LLUICtrlFactory::createFromFile<LLContextMenu>("menu_text_editor.xml",
LLMenuGL::sMenuContainer,
LLMenuHolderGL::child_registry_t::instance());
if(!menu)
{
LL_WARNS() << "Failed to create menu for LLTextEditor: " << getName() << LL_ENDL;
return;
}
mContextMenuHandle = menu->getHandle();
}
// Route menu to this class
@ -2102,11 +2113,11 @@ void LLTextEditor::showContextMenu(S32 x, S32 y)
}
}
mContextMenu->setItemVisible("Suggestion Separator", (use_spellcheck) && (!mSuggestionList.empty()));
mContextMenu->setItemVisible("Add to Dictionary", (use_spellcheck) && (is_misspelled));
mContextMenu->setItemVisible("Add to Ignore", (use_spellcheck) && (is_misspelled));
mContextMenu->setItemVisible("Spellcheck Separator", (use_spellcheck) && (is_misspelled));
mContextMenu->show(screen_x, screen_y, this);
menu->setItemVisible("Suggestion Separator", (use_spellcheck) && (!mSuggestionList.empty()));
menu->setItemVisible("Add to Dictionary", (use_spellcheck) && (is_misspelled));
menu->setItemVisible("Add to Ignore", (use_spellcheck) && (is_misspelled));
menu->setItemVisible("Spellcheck Separator", (use_spellcheck) && (is_misspelled));
menu->show(screen_x, screen_y, this);
}

View File

@ -329,7 +329,7 @@ private:
keystroke_signal_t mKeystrokeSignal;
LLTextValidate::validate_func_t mPrevalidateFunc;
LLContextMenu* mContextMenu;
LLHandle<LLContextMenu> mContextMenuHandle;
}; // end class LLTextEditor
// Build time optimization, generate once in .cpp file

View File

@ -127,7 +127,12 @@ LLToolBar::LLToolBar(const LLToolBar::Params& p)
LLToolBar::~LLToolBar()
{
delete mPopupMenuHandle.get();
auto menu = mPopupMenuHandle.get();
if (menu)
{
menu->die();
mPopupMenuHandle.markDead();
}
delete mButtonAddSignal;
delete mButtonEnterSignal;
delete mButtonLeaveSignal;

View File

@ -51,6 +51,7 @@ LLListContextMenu::~LLListContextMenu()
if (!mMenuHandle.isDead())
{
mMenuHandle.get()->die();
mMenuHandle.markDead();
}
}
@ -59,13 +60,8 @@ void LLListContextMenu::show(LLView* spawning_view, const uuid_vec_t& uuids, S32
LLContextMenu* menup = mMenuHandle.get();
if (menup)
{
//preventing parent (menu holder) from deleting already "dead" context menus on exit
LLView* parent = menup->getParent();
if (parent)
{
parent->removeChild(menup);
}
delete menup;
menup->die();
mMenuHandle.markDead();
mUUIDs.clear();
}