From 94b72950752b3a0e187203211327da9430d30b37 Mon Sep 17 00:00:00 2001 From: Rye Mutt <rye@alchemyviewer.org> Date: Sun, 15 Mar 2020 12:33:53 -0400 Subject: [PATCH] Fix teleport history panel menu leaks --- indra/newview/llpanelteleporthistory.cpp | 79 +++++++++++++----------- indra/newview/llpanelteleporthistory.h | 8 +-- 2 files changed, 48 insertions(+), 39 deletions(-) diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index fe0608d5441..ab6b90501e2 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -366,31 +366,40 @@ void LLTeleportHistoryFlatItemStorage::purge() //////////////////////////////////////////////////////////////////////////////// LLTeleportHistoryPanel::ContextMenu::ContextMenu() : - mMenu(NULL), mIndex(0) + mMenuHandle(), mIndex(0) { } +LLTeleportHistoryPanel::ContextMenu::~ContextMenu() +{ + if (auto menu = mMenuHandle.get()) + { + menu->die(); + mMenuHandle.markDead(); + } +} + void LLTeleportHistoryPanel::ContextMenu::show(LLView* spawning_view, S32 index, S32 x, S32 y) { - if (mMenu) + auto menu = mMenuHandle.get(); + if (menu) { - //preventing parent (menu holder) from deleting already "dead" context menus on exit - LLView* parent = mMenu->getParent(); - if (parent) - { - parent->removeChild(mMenu); - } - delete mMenu; + menu->die(); + mMenuHandle.markDead(); } mIndex = index; - mMenu = createMenu(); + mMenuHandle = createMenu(); - mMenu->show(x, y); - LLMenuGL::showPopup(spawning_view, mMenu, x, y); + menu = mMenuHandle.get(); + if (menu) + { + menu->show(x, y); + LLMenuGL::showPopup(spawning_view, menu, x, y); + } } -LLContextMenu* LLTeleportHistoryPanel::ContextMenu::createMenu() +LLHandle<LLContextMenu> LLTeleportHistoryPanel::ContextMenu::createMenu() { // set up the callbacks for all of the avatar menu items // (N.B. callbacks don't take const refs as mID is local scope) @@ -403,7 +412,7 @@ LLContextMenu* LLTeleportHistoryPanel::ContextMenu::createMenu() // create the context menu from the XUI llassert(LLMenuGL::sMenuContainer != NULL); return LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>( - "menu_teleport_history_item.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance()); + "menu_teleport_history_item.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance())->getHandle(); } void LLTeleportHistoryPanel::ContextMenu::onTeleport() @@ -443,7 +452,6 @@ LLTeleportHistoryPanel::LLTeleportHistoryPanel() mCurrentItem(0), mTeleportHistory(NULL), mHistoryAccordion(NULL), - mAccordionTabMenu(NULL), mLastSelectedFlatlList(NULL), mLastSelectedItemIndex(-1), mMenuGearButton(NULL) @@ -454,8 +462,13 @@ LLTeleportHistoryPanel::LLTeleportHistoryPanel() LLTeleportHistoryPanel::~LLTeleportHistoryPanel() { LLTeleportHistoryFlatItemStorage::instance().purge(); - if (mGearMenuHandle.get()) mGearMenuHandle.get()->die(); mTeleportHistoryChangedConnection.disconnect(); + auto menu = mAccordionTabMenuHandle.get(); + if (menu) + { + menu->die(); + mAccordionTabMenuHandle.markDead(); + } } BOOL LLTeleportHistoryPanel::postBuild() @@ -519,13 +532,7 @@ BOOL LLTeleportHistoryPanel::postBuild() mEnableCallbackRegistrar.add("TeleportHistory.GearMenu.Enable", boost::bind(&LLTeleportHistoryPanel::isActionEnabled, this, _2)); mMenuGearButton = getChild<LLMenuButton>("gear_btn"); - - LLToggleableMenu* gear_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_teleport_history_gear.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());; - if(gear_menu) - { - mGearMenuHandle = gear_menu->getHandle(); - mMenuGearButton->setMenu(gear_menu); - } + mMenuGearButton->setMenu("menu_teleport_history_gear.xml"); return TRUE; } @@ -977,15 +984,14 @@ void LLTeleportHistoryPanel::onAccordionTabRightClick(LLView *view, S32 x, S32 y if (y < tab->getRect().getHeight() - tab->getHeaderHeight() - tab->getPaddingBottom()) return; - if (mAccordionTabMenu) + if (!mAccordionTabMenuHandle.isDead()) { - //preventing parent (menu holder) from deleting already "dead" context menus on exit - LLView* parent = mAccordionTabMenu->getParent(); - if (parent) + auto menu = mAccordionTabMenuHandle.get(); + if (menu) { - parent->removeChild(mAccordionTabMenu); + menu->die(); + mAccordionTabMenuHandle.markDead(); } - delete mAccordionTabMenu; } // set up the callbacks for all of the avatar menu items @@ -997,14 +1003,17 @@ void LLTeleportHistoryPanel::onAccordionTabRightClick(LLView *view, S32 x, S32 y // create the context menu from the XUI llassert(LLMenuGL::sMenuContainer != NULL); - mAccordionTabMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>( + auto menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>( "menu_teleport_history_tab.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance()); + if (menu) + { + mAccordionTabMenuHandle = menu->getHandle(); + menu->setItemVisible("TabOpen", !tab->isExpanded() ? true : false); + menu->setItemVisible("TabClose", tab->isExpanded() ? true : false); - mAccordionTabMenu->setItemVisible("TabOpen", !tab->isExpanded() ? true : false); - mAccordionTabMenu->setItemVisible("TabClose", tab->isExpanded() ? true : false); - - mAccordionTabMenu->show(x, y); - LLMenuGL::showPopup(tab, mAccordionTabMenu, x, y); + menu->show(x, y); + LLMenuGL::showPopup(tab, menu, x, y); + } } void LLTeleportHistoryPanel::onAccordionTabOpen(LLAccordionCtrlTab *tab) diff --git a/indra/newview/llpanelteleporthistory.h b/indra/newview/llpanelteleporthistory.h index b88861c5c63..d93802dc6e9 100644 --- a/indra/newview/llpanelteleporthistory.h +++ b/indra/newview/llpanelteleporthistory.h @@ -48,17 +48,18 @@ class LLTeleportHistoryPanel : public LLPanelPlacesTab { public: ContextMenu(); + ~ContextMenu(); void show(LLView* spawning_view, S32 index, S32 x, S32 y); private: - LLContextMenu* createMenu(); + LLHandle<LLContextMenu> createMenu(); void onTeleport(); void onInfo(); void onCopyToClipboard(); static void gotSLURLCallback(const std::string& slurl); - LLContextMenu* mMenu; + LLHandle<LLContextMenu> mMenuHandle; S32 mIndex; }; @@ -116,8 +117,7 @@ class LLTeleportHistoryPanel : public LLPanelPlacesTab item_containers_t mItemContainers; ContextMenu mContextMenu; - LLContextMenu* mAccordionTabMenu; - LLHandle<LLView> mGearMenuHandle; + LLHandle<LLContextMenu> mAccordionTabMenuHandle; LLMenuButton* mMenuGearButton; boost::signals2::connection mTeleportHistoryChangedConnection; -- GitLab