summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRye Mutt <rye@alchemyviewer.org>2022-10-19 16:23:25 -0400
committerRye Mutt <rye@alchemyviewer.org>2022-10-19 16:28:03 -0400
commitbbd8df15de6b8f9b321f251c3e764ea654d5ecc7 (patch)
tree58c0edcab9957d03dad372b37601c479953eee5d
parenta48374e8cfbdf261b4902024fb66e60432602b12 (diff)
Fix menu leaks and lazy creation in text editing and scroll lists
-rw-r--r--indra/llui/lllineeditor.cpp16
-rw-r--r--indra/llui/llscrolllistctrl.cpp28
-rw-r--r--indra/llui/llscrolllistctrl.h2
-rw-r--r--indra/llui/lltextbase.cpp6
-rw-r--r--indra/llui/lltexteditor.cpp31
-rw-r--r--indra/llui/lltexteditor.h2
-rw-r--r--indra/llui/lltoolbar.cpp7
-rw-r--r--indra/newview/lllistcontextmenu.cpp10
8 files changed, 67 insertions, 35 deletions
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 33037b5001..f16f8c3e8d 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -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)
{
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 65c7b420ce..167593bd52 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -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;
+ auto menu = mPopupMenuHandle.get();
+ if (menu)
+ {
+ menu->die();
+ mPopupMenuHandle.markDead();
+ }
llassert(LLMenuGL::sMenuContainer != NULL);
- mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
+ menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
menu_name, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
- if (mPopupMenu)
+ 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;
}
}
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 77d10fdec7..6f7d4768e1 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -526,7 +526,7 @@ private:
S32 mHighlightedItem;
class LLViewBorder* mBorder;
- LLContextMenu *mPopupMenu;
+ LLHandle<LLContextMenu> mPopupMenuHandle;
LLView *mCommentTextView;
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 7e4aaa53bf..fcfdd64e6a 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -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;
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index b1f8b00cab..3d2a426913 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -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);
}
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 1a10d2fd1e..f3939248c2 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -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
diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index 5150df25f2..2707f7a15c 100644
--- a/indra/llui/lltoolbar.cpp
+++ b/indra/llui/lltoolbar.cpp
@@ -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;
diff --git a/indra/newview/lllistcontextmenu.cpp b/indra/newview/lllistcontextmenu.cpp
index 6bda8b1d0d..77185411c5 100644
--- a/indra/newview/lllistcontextmenu.cpp
+++ b/indra/newview/lllistcontextmenu.cpp
@@ -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();
}