diff --git a/doc/contributions.txt b/doc/contributions.txt index ac14691a74..2f91702406 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -1393,6 +1393,8 @@ Sovereign Engineer SL-15096 SL-16127 SL-18249 + SL-18394 + SL-18412 SpacedOut Frye VWR-34 VWR-45 diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp index c7b4d08b3b..a7086e09de 100644 --- a/indra/llui/llfolderview.cpp +++ b/indra/llui/llfolderview.cpp @@ -163,6 +163,7 @@ LLFolderView::LLFolderView(const Params& p) : LLFolderViewFolder(p), mScrollContainer( NULL ), mPopupMenuHandle(), + mMenuFileName(p.options_menu), mAllowMultiSelect(p.allow_multiselect), mAllowDrag(p.allow_drag), mShowEmptyMessage(p.show_empty_message), @@ -186,6 +187,7 @@ LLFolderView::LLFolderView(const Params& p) mDragStartY(0), // [/SL:KB] mCallbackRegistrar(NULL), + mEnableRegistrar(NULL), mUseEllipses(p.use_ellipses), mDraggingOverItem(NULL), mStatusTextBox(NULL), @@ -248,17 +250,6 @@ LLFolderView::LLFolderView(const Params& p) mStatusTextBox->setFollowsTop(); addChild(mStatusTextBox); - - // make the popup menu available - llassert(LLMenuGL::sMenuContainer != NULL); - LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile(p.options_menu, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance()); - if (!menu) - { - menu = LLUICtrlFactory::getDefaultWidget("inventory_menu"); - } - menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor")); - mPopupMenuHandle = menu->getHandle(); - mViewModelItem->openItem(); mAreChildrenInited = true; // root folder is a special case due to not being loaded normally, assume that it's inited. @@ -280,6 +271,7 @@ LLFolderView::~LLFolderView( void ) mStatusTextBox = NULL; if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die(); + mPopupMenuHandle.markDead(); mAutoOpenItems.removeAllNodes(); clearSelection(); @@ -1534,22 +1526,56 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask ) BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL; S32 count = mSelectedItems.size(); - LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); + LLMenuGL* menu = static_cast(mPopupMenuHandle.get()); + if (!menu) + { + if (mCallbackRegistrar) + { + mCallbackRegistrar->pushScope(); + } + if (mEnableRegistrar) + { + mEnableRegistrar->pushScope(); + } + llassert(LLMenuGL::sMenuContainer != NULL); + menu = LLUICtrlFactory::getInstance()->createFromFile(mMenuFileName, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance()); + if (!menu) + { + menu = LLUICtrlFactory::getDefaultWidget("inventory_menu"); + } + menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor")); + mPopupMenuHandle = menu->getHandle(); + if (mEnableRegistrar) + { + mEnableRegistrar->popScope(); + } + if (mCallbackRegistrar) + { + mCallbackRegistrar->popScope(); + } + } bool hide_folder_menu = mSuppressFolderMenu && isFolderSelected(); - if ((handled - && ( count > 0 && (hasVisibleChildren()) ) // show menu only if selected items are visible - && menu ) && + if (menu && (handled + && ( count > 0 && (hasVisibleChildren()) )) && // show menu only if selected items are visible !hide_folder_menu) { if (mCallbackRegistrar) { mCallbackRegistrar->pushScope(); } + if (mEnableRegistrar) + { + mEnableRegistrar->pushScope(); + } updateMenuOptions(menu); menu->updateParent(LLMenuGL::sMenuContainer); LLMenuGL::showPopup(this, menu, x, y); + if (mEnableRegistrar) + { + mEnableRegistrar->popScope(); + } if (mCallbackRegistrar) { mCallbackRegistrar->popScope(); @@ -1627,7 +1653,7 @@ void LLFolderView::deleteAllChildren() { closeRenamer(); if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die(); - mPopupMenuHandle = LLHandle(); + mPopupMenuHandle.markDead(); mScrollContainer = NULL; mRenameItem = NULL; mRenamer = NULL; diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h index 491028556c..e6d6d76ad9 100644 --- a/indra/llui/llfolderview.h +++ b/indra/llui/llfolderview.h @@ -240,6 +240,7 @@ public: bool showItemLinkOverlays() { return mShowItemLinkOverlays; } void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; } + void setEnableRegistrar(LLUICtrl::EnableCallbackRegistry::ScopedRegistrar* registrar) { mEnableRegistrar = registrar; } LLPanel* getParentPanel() { return mParentPanel.get(); } // DEBUG only @@ -277,6 +278,7 @@ protected: protected: LLHandle mPopupMenuHandle; + std::string mMenuFileName; selected_items_t mSelectedItems; bool mKeyboardSelection, @@ -336,6 +338,7 @@ protected: LLFolderViewItem* mDraggingOverItem; // See EXT-719 LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* mCallbackRegistrar; + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar* mEnableRegistrar; public: static F32 sAutoOpenTime; diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 63482df996..b2f5ec795a 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -164,8 +164,6 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) mHighlightColor(p.highlight_color()), mPreeditBgColor(p.preedit_bg_color()), mGLFont(p.font), - // Delay context menu initialization if LLMenuGL::sMenuContainer is still NULL - mDelayedInit(false), mContextMenuHandle(), mAutoreplaceCallback() { @@ -212,24 +210,6 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) setPrevalidateInput(p.prevalidate_input_callback()); setPrevalidate(p.prevalidate_callback()); - - // Delay context menu initialization if LLMenuGL::sMenuContainer is still NULL - if (LLMenuGL::sMenuContainer) - { - // - llassert(LLMenuGL::sMenuContainer != NULL); - LLContextMenu* menu = LLUICtrlFactory::instance().createFromFile - ("menu_text_editor.xml", - LLMenuGL::sMenuContainer, - LLMenuHolderGL::child_registry_t::instance()); - setContextMenu(menu); - // Delay context menu initialization if LLMenuGL::sMenuContainer is still NULL - } - else - { - mDelayedInit = true; - } - // } LLLineEditor::~LLLineEditor() @@ -244,9 +224,6 @@ LLLineEditor::~LLLineEditor() } setContextMenu(NULL); - // Delay context menu initialization if LLMenuGL::sMenuContainer is still NULL - mDelayedInit = false; - // calls onCommit() while LLLineEditor still valid gFocusMgr.releaseFocusIfNeeded( this ); } @@ -2759,24 +2736,16 @@ LLWString LLLineEditor::getConvertedText() const void LLLineEditor::showContextMenu(S32 x, S32 y, bool set_cursor_pos) // { - //LLContextMenu* menu = static_cast(mContextMenuHandle.get()); - // Delay context menu initialization if LLMenuGL::sMenuContainer is still NULL - LLContextMenu* menu = NULL; - if (mDelayedInit && !mContextMenuHandle.get()) + LLContextMenu* menu = static_cast(mContextMenuHandle.get()); + if (!menu) { llassert(LLMenuGL::sMenuContainer != NULL); - menu = LLUICtrlFactory::instance().createFromFile + menu = LLUICtrlFactory::createFromFile ("menu_text_editor.xml", - LLMenuGL::sMenuContainer, - LLMenuHolderGL::child_registry_t::instance()); + LLMenuGL::sMenuContainer, + LLMenuHolderGL::child_registry_t::instance()); setContextMenu(menu); } - else - { - menu = static_cast(mContextMenuHandle.get()); - } - mDelayedInit = false; - // if (menu) { @@ -2827,8 +2796,6 @@ void LLLineEditor::setContextMenu(LLContextMenu* new_context_menu) { menu->die(); mContextMenuHandle.markDead(); - // Delay context menu initialization if LLMenuGL::sMenuContainer is still NULL - mDelayedInit = false; } if (new_context_menu) diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index 2387cc1478..a7b4029d32 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -422,9 +422,6 @@ protected: LLHandle mContextMenuHandle; - // Delay context menu initialization if LLMenuGL::sMenuContainer is still NULL - bool mDelayedInit; - private: // Instances that by default point to the statics but can be overidden in XML. LLPointer mBgImage; diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index d0d1db88dd..18b789da24 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -4125,12 +4125,7 @@ void LLTearOffMenu::closeTearOff() LLContextMenuBranch::LLContextMenuBranch(const LLContextMenuBranch::Params& p) : LLMenuItemGL(p) - //mBranch( p.branch()->getHandle() ) // Context menu memory leak fix by Rye Mutt { - // Context menu memory leak fix by Rye Mutt - //mBranch.get()->hide(); - //mBranch.get()->setParentMenuItem(this); - // LLContextMenu* branch = static_cast(p.branch); if (branch) { @@ -4140,7 +4135,6 @@ LLContextMenuBranch::LLContextMenuBranch(const LLContextMenuBranch::Params& p) } } -// Context menu memory leak fix by Rye Mutt LLContextMenuBranch::~LLContextMenuBranch() { if (mBranch.get()) @@ -4148,30 +4142,21 @@ LLContextMenuBranch::~LLContextMenuBranch() mBranch.get()->die(); } } -// // called to rebuild the draw label void LLContextMenuBranch::buildDrawLabel( void ) { - // Context menu memory leak fix by Rye Mutt auto menu = getBranch(); if (menu) - // { // default enablement is this -- if any of the subitems are // enabled, this item is enabled. JC - // Context menu memory leak fix by Rye Mutt - //U32 sub_count = mBranch.get()->getItemCount(); U32 sub_count = menu->getItemCount(); - // U32 i; BOOL any_enabled = FALSE; for (i = 0; i < sub_count; i++) { - // Context menu memory leak fix by Rye Mutt - //LLMenuItemGL* item = mBranch.get()->getItem(i); LLMenuItemGL* item = menu->getItem(i); - // item->buildDrawLabel(); if (item->getEnabled() && !item->getDrawTextDisabled() ) { @@ -4193,28 +4178,18 @@ void LLContextMenuBranch::buildDrawLabel( void ) void LLContextMenuBranch::showSubMenu() { - // Context menu memory leak fix by Rye Mutt - //LLMenuItemGL* menu_item = mBranch.get()->getParentMenuItem(); - //if (menu_item != NULL && menu_item->getVisible()) - //{ - // S32 center_x; - // S32 center_y; - // localPointToScreen(getRect().getWidth(), getRect().getHeight() , ¢er_x, ¢er_y); - // mBranch.get()->show(center_x, center_y); - //} auto menu = getBranch(); - if (menu) + if(menu) { LLMenuItemGL* menu_item = menu->getParentMenuItem(); if (menu_item != NULL && menu_item->getVisible()) { S32 center_x; S32 center_y; - localPointToScreen(getRect().getWidth(), getRect().getHeight() , ¢er_x, ¢er_y); + localPointToScreen(getRect().getWidth(), getRect().getHeight(), ¢er_x, ¢er_y); menu->show(center_x, center_y); } } - // } // onCommit() - do the primary funcationality of the menu item. @@ -4227,15 +4202,6 @@ void LLContextMenuBranch::setHighlight( BOOL highlight ) { if (highlight == getHighlight()) return; LLMenuItemGL::setHighlight(highlight); - // Context menu memory leak fix by Rye Mutt - //if( highlight ) - //{ - // showSubMenu(); - //} - //else - //{ - // mBranch.get()->hide(); - //} auto menu = getBranch(); if (menu) { @@ -4248,7 +4214,6 @@ void LLContextMenuBranch::setHighlight( BOOL highlight ) menu->hide(); } } - // } diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 73600f01f3..760d3eff6c 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -754,11 +754,7 @@ public: LLContextMenuBranch(const Params&); - // Context menu memory leak fix by Rye Mutt - //virtual ~LLContextMenuBranch() - //{} virtual ~LLContextMenuBranch(); - // // called to rebuild the draw label virtual void buildDrawLabel( void ); diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 7cd0157785..3d97c7f660 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -201,7 +201,6 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p) mHighlightedItem(-1), mBorder(NULL), mSortCallback(NULL), - mPopupMenu(NULL), mCommentTextView(NULL), mNumDynamicWidthColumns(0), mTotalStaticColumnWidth(0), @@ -412,6 +411,13 @@ LLScrollListCtrl::~LLScrollListCtrl() mItemList.clear(); clearColumns(); //clears columns and deletes headers delete mIsFriendSignal; + + auto menu = mPopupMenuHandle.get(); + if (menu) + { + menu->die(); + mPopupMenuHandle.markDead(); + } } @@ -2252,17 +2258,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( - 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( + menu_name, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance()); + if (menu) + { + mPopupMenuHandle = menu->getHandle(); if (mIsFriendSignal) { bool isFriend = *(*mIsFriendSignal)(uuid); - LLView* addFriendButton = mPopupMenu->getChild("add_friend"); - LLView* removeFriendButton = mPopupMenu->getChild("remove_friend"); + LLView* addFriendButton = menu->getChild("add_friend"); + LLView* removeFriendButton = menu->getChild("remove_friend"); if (addFriendButton && removeFriendButton) { @@ -2271,8 +2283,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 8b62ea735d..d8e967790a 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -563,7 +563,7 @@ private: S32 mHighlightedItem; class LLViewBorder* mBorder; - LLContextMenu *mPopupMenu; + LLHandle mPopupMenuHandle; LLView *mCommentTextView; diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 0e8f9f2c5e..1031dd9db1 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -303,6 +303,12 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p) LLTextBase::~LLTextBase() { mSegments.clear(); + LLContextMenu* menu = static_cast(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 942af90fd8..c208c0006b 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -258,7 +258,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), @@ -303,8 +302,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(mContextMenuHandle.get()); + if(menu) + { + menu->die(); + mContextMenuHandle.markDead(); + } } //////////////////////////////////////////////////////////// @@ -2236,19 +2240,19 @@ void LLTextEditor::setEnabled(BOOL enabled) void LLTextEditor::showContextMenu(S32 x, S32 y, bool set_cursor_pos) // { - if (!mContextMenu) + LLContextMenu* menu = static_cast(mContextMenuHandle.get()); + if (!menu) { llassert(LLMenuGL::sMenuContainer != NULL); - mContextMenu = LLUICtrlFactory::instance().createFromFile("menu_text_editor.xml", + menu = LLUICtrlFactory::createFromFile("menu_text_editor.xml", LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance()); - // FIRE-31081 defend against null this prt exception in setItemVisible found in BugSplat - if(!mContextMenu) - { - LL_WARNS() << "Failed to create context menu 'menu_text_editor'" << LL_ENDL; - return; - } - // + if(!menu) + { + LL_WARNS() << "Failed to create menu for LLTextEditor: " << getName() << LL_ENDL; + return; + } + mContextMenuHandle = menu->getHandle(); } // Route menu to this class @@ -2295,11 +2299,11 @@ void LLTextEditor::showContextMenu(S32 x, S32 y, bool set_cursor_pos) } } - 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 714247c1c6..4fc837c439 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -345,7 +345,7 @@ private: keystroke_signal_t mKeystrokeSignal; LLTextValidate::validate_func_t mPrevalidateFunc; - LLContextMenu* mContextMenu; + LLHandle 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 dcce2aa1fd..bf8c3f51e5 100644 --- a/indra/llui/lltoolbar.cpp +++ b/indra/llui/lltoolbar.cpp @@ -162,7 +162,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/llchathistory.cpp b/indra/newview/llchathistory.cpp index c06e2793db..6cd8bc0bc1 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -155,6 +155,18 @@ public: { mAvatarNameCacheConnection.disconnect(); } + auto menu = mPopupMenuHandleAvatar.get(); + if (menu) + { + menu->die(); + mPopupMenuHandleAvatar.markDead(); + } + menu = mPopupMenuHandleObject.get(); + if (menu) + { + menu->die(); + mPopupMenuHandleObject.markDead(); + } } BOOL handleMouseUp(S32 x, S32 y, MASK mask) @@ -587,36 +599,6 @@ public: BOOL postBuild() { - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - LLUICtrl::EnableCallbackRegistry::ScopedRegistrar registrar_enable; - - registrar.add("AvatarIcon.Action", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemClicked, this, _2)); - registrar_enable.add("AvatarIcon.Check", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemChecked, this, _2)); - registrar_enable.add("AvatarIcon.Enable", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemEnabled, this, _2)); - registrar_enable.add("AvatarIcon.Visible", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemVisible, this, _2)); - registrar.add("ObjectIcon.Action", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemClicked, this, _2)); - registrar_enable.add("ObjectIcon.Visible", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemVisible, this, _2)); - - LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile("menu_avatar_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - if (menu) - { - mPopupMenuHandleAvatar = menu->getHandle(); - } - else - { - LL_WARNS() << " Failed to create menu_avatar_icon.xml" << LL_ENDL; - } - - menu = LLUICtrlFactory::getInstance()->createFromFile("menu_object_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - if (menu) - { - mPopupMenuHandleObject = menu->getHandle(); - } - else - { - LL_WARNS() << " Failed to create menu_object_icon.xml" << LL_ENDL; - } - setDoubleClickCallback(boost::bind(&LLChatHistoryHeader::showInspector, this)); setMouseEnterCallback(boost::bind(&LLChatHistoryHeader::showInfoCtrl, this)); @@ -936,13 +918,53 @@ protected: void showObjectContextMenu(S32 x,S32 y) { LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandleObject.get(); - if(menu) + if (!menu) + { + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar registrar_enable; + registrar.add("ObjectIcon.Action", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemClicked, this, _2)); + registrar_enable.add("ObjectIcon.Visible", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemVisible, this, _2)); + + menu = LLUICtrlFactory::getInstance()->createFromFile("menu_object_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + if (menu) + { + mPopupMenuHandleObject = menu->getHandle(); + menu->updateParent(LLMenuGL::sMenuContainer); + LLMenuGL::showPopup(this, menu, x, y); + } + else + { + LL_WARNS() << " Failed to create menu_object_icon.xml" << LL_ENDL; + } + } + else + { LLMenuGL::showPopup(this, menu, x, y); + } } void showAvatarContextMenu(S32 x,S32 y) { LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandleAvatar.get(); + if (!menu) + { + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar registrar_enable; + registrar.add("AvatarIcon.Action", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemClicked, this, _2)); + registrar_enable.add("AvatarIcon.Check", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemChecked, this, _2)); + registrar_enable.add("AvatarIcon.Enable", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemEnabled, this, _2)); + registrar_enable.add("AvatarIcon.Visible", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemVisible, this, _2)); + + menu = LLUICtrlFactory::getInstance()->createFromFile("menu_avatar_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + if (menu) + { + mPopupMenuHandleAvatar = menu->getHandle(); + } + else + { + LL_WARNS() << " Failed to create menu_avatar_icon.xml" << LL_ENDL; + } + } if(menu) { diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index ae54043cba..9d3ad0effc 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -98,7 +98,6 @@ LLSysWellChiclet::LLSysWellChiclet(const Params& p) , mMaxDisplayedCount(p.max_displayed_count) , mIsNewMessagesState(false) , mFlashToLitTimer(NULL) - , mContextMenu(NULL) { LLButton::Params button_params = p.button; mButton = LLUICtrlFactory::create(button_params); @@ -110,6 +109,12 @@ LLSysWellChiclet::LLSysWellChiclet(const Params& p) LLSysWellChiclet::~LLSysWellChiclet() { mFlashToLitTimer->unset(); + LLContextMenu* menu = static_cast(mContextMenuHandle.get()); + if (menu) + { + menu->die(); + mContextMenuHandle.markDead(); + } } void LLSysWellChiclet::setCounter(S32 counter) @@ -176,14 +181,16 @@ void LLSysWellChiclet::updateWidget(bool is_window_empty) // virtual BOOL LLSysWellChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask) { - if(!mContextMenu) + LLContextMenu* menu_avatar = mContextMenuHandle.get(); + if(!menu_avatar) { createMenu(); + menu_avatar = mContextMenuHandle.get(); } - if (mContextMenu) + if (menu_avatar) { - mContextMenu->show(x, y); - LLMenuGL::showPopup(this, mContextMenu, x, y); + menu_avatar->show(x, y); + LLMenuGL::showPopup(this, menu_avatar, x, y); } return TRUE; } @@ -207,6 +214,13 @@ LLIMWellChiclet::LLIMWellChiclet(const Params& p) LLIMWellChiclet::~LLIMWellChiclet() { + LLContextMenu* menu = static_cast(mContextMenuHandle.get()); + if (menu) + { + menu->die(); + mContextMenuHandle.markDead(); + } + LLIMWellWindow* im_well_window = LLIMWellWindow::findInstance(); if (im_well_window) { @@ -237,7 +251,7 @@ bool LLIMWellChiclet::enableMenuItem(const LLSD& user_data) void LLIMWellChiclet::createMenu() { - if(mContextMenu) + if(mContextMenuHandle.get()) { LL_WARNS() << "Menu already exists" << LL_ENDL; return; @@ -251,10 +265,14 @@ void LLIMWellChiclet::createMenu() enable_registrar.add("IMWellChicletMenu.EnableItem", boost::bind(&LLIMWellChiclet::enableMenuItem, this, _2)); - mContextMenu = LLUICtrlFactory::getInstance()->createFromFile + LLContextMenu* menu = LLUICtrlFactory::getInstance()->createFromFile ("menu_fs_im_well_button.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance()); + if (menu) + { + mContextMenuHandle = menu->getHandle(); + } } void LLIMWellChiclet::messageCountChanged(const LLSD& session_data) @@ -358,7 +376,7 @@ bool LLNotificationChiclet::enableMenuItem(const LLSD& user_data) void LLNotificationChiclet::createMenu() { - if(mContextMenu) + if(mContextMenuHandle.get()) { LL_WARNS() << "Menu already exists" << LL_ENDL; return; @@ -373,10 +391,14 @@ void LLNotificationChiclet::createMenu() boost::bind(&LLNotificationChiclet::enableMenuItem, this, _2)); llassert(LLMenuGL::sMenuContainer != NULL); - mContextMenu = LLUICtrlFactory::getInstance()->createFromFile + LLContextMenu* menu = LLUICtrlFactory::getInstance()->createFromFile ("menu_notification_well_button.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance()); + if (menu) + { + mContextMenuHandle = menu->getHandle(); + } } /*virtual*/ @@ -492,12 +514,21 @@ LLIMChiclet::LLIMChiclet(const LLIMChiclet::Params& p) , mCounterCtrl(NULL) // [FS communication UI] , mChicletButton(NULL) -, mPopupMenu(NULL) { // [FS communication UI] enableCounterControl(p.enable_counter); } +LLIMChiclet::~LLIMChiclet() +{ + auto menu = mPopupMenuHandle.get(); + if (menu) + { + menu->die(); + mPopupMenuHandle.markDead(); + } +} + /* virtual*/ BOOL LLIMChiclet::postBuild() { @@ -688,16 +719,18 @@ LLIMChiclet::EType LLIMChiclet::getIMSessionType(const LLUUID& session_id) BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask) { - if(!mPopupMenu) + auto menu = static_cast(mPopupMenuHandle.get()); + if(!menu) { createPopupMenu(); + menu = static_cast(mPopupMenuHandle.get()); } - if (mPopupMenu) + if (menu) { updateMenuItems(); - mPopupMenu->arrangeAndClear(); - LLMenuGL::showPopup(this, mPopupMenu, x, y); + menu->arrangeAndClear(); + LLMenuGL::showPopup(this, menu, x, y); } return TRUE; @@ -705,15 +738,16 @@ BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask) void LLIMChiclet::hidePopupMenu() { - if (mPopupMenu) + auto menu = mPopupMenuHandle.get(); + if (menu) { - mPopupMenu->setVisible(FALSE); + menu->setVisible(FALSE); } } bool LLIMChiclet::canCreateMenu() { - if(mPopupMenu) + if(mPopupMenuHandle.get()) { LL_WARNS() << "Menu already exists" << LL_ENDL; return false; @@ -784,17 +818,17 @@ void LLIMP2PChiclet::setOtherParticipantId(const LLUUID& other_participant_id) void LLIMP2PChiclet::updateMenuItems() { - if(!mPopupMenu) + if(!mPopupMenuHandle.get()) return; if(getSessionId().isNull()) return; FSFloaterIM* open_im_floater = FSFloaterIM::findInstance(getSessionId()); bool open_window_exists = open_im_floater && open_im_floater->getVisible(); - mPopupMenu->getChild("Send IM")->setEnabled(!open_window_exists); + mPopupMenuHandle.get()->getChild("Send IM")->setEnabled(!open_window_exists); bool is_friend = LLAvatarActions::isFriend(getOtherParticipantId()); - mPopupMenu->getChild("Add Friend")->setEnabled(!is_friend); + mPopupMenuHandle.get()->getChild("Add Friend")->setEnabled(!is_friend); } void LLIMP2PChiclet::createPopupMenu() @@ -805,8 +839,12 @@ void LLIMP2PChiclet::createPopupMenu() LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; registrar.add("IMChicletMenu.Action", boost::bind(&LLIMP2PChiclet::onMenuItemClicked, this, _2)); - mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile + LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile ("menu_fs_imchiclet_p2p.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + if (menu) + { + mPopupMenuHandle = menu->getHandle(); + } } void LLIMP2PChiclet::onMenuItemClicked(const LLSD& user_data) @@ -925,8 +963,12 @@ void LLAdHocChiclet::createPopupMenu() LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; registrar.add("IMChicletMenu.Action", boost::bind(&LLAdHocChiclet::onMenuItemClicked, this, _2)); - mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile + auto menu = LLUICtrlFactory::getInstance()->createFromFile ("menu_fs_imchiclet_adhoc.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + if (menu) + { + mPopupMenuHandle = menu->getHandle(); + } } void LLAdHocChiclet::onMenuItemClicked(const LLSD& user_data) @@ -1060,14 +1102,14 @@ void LLIMGroupChiclet::changed(LLGroupChange gc) void LLIMGroupChiclet::updateMenuItems() { - if(!mPopupMenu) + if(!mPopupMenuHandle.get()) return; if(getSessionId().isNull()) return; FSFloaterIM* open_im_floater = FSFloaterIM::findInstance(getSessionId()); bool open_window_exists = open_im_floater && open_im_floater->getVisible(); - mPopupMenu->getChild("Chat")->setEnabled(!open_window_exists); + mPopupMenuHandle.get()->getChild("Chat")->setEnabled(!open_window_exists); } void LLIMGroupChiclet::createPopupMenu() @@ -1078,8 +1120,12 @@ void LLIMGroupChiclet::createPopupMenu() LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; registrar.add("IMChicletMenu.Action", boost::bind(&LLIMGroupChiclet::onMenuItemClicked, this, _2)); - mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile + auto menu = LLUICtrlFactory::getInstance()->createFromFile ("menu_fs_imchiclet_group.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + if (menu) + { + mPopupMenuHandle = menu->getHandle(); + } } void LLIMGroupChiclet::onMenuItemClicked(const LLSD& user_data) @@ -2010,8 +2056,13 @@ void LLScriptChiclet::createPopupMenu() LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; registrar.add("ScriptChiclet.Action", boost::bind(&LLScriptChiclet::onMenuItemClicked, this, _2)); - mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile + LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile ("menu_script_chiclet.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + if (menu) + { + mPopupMenuHandle = menu->getHandle(); + } + } ////////////////////////////////////////////////////////////////////////// @@ -2095,8 +2146,12 @@ void LLInvOfferChiclet::createPopupMenu() LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; registrar.add("InvOfferChiclet.Action", boost::bind(&LLInvOfferChiclet::onMenuItemClicked, this, _2)); - mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile + LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile ("menu_inv_offer_chiclet.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + if (menu) + { + mPopupMenuHandle = menu->getHandle(); + } } // EOF diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h index 598678f6ea..478e02a1ef 100644 --- a/indra/newview/llchiclet.h +++ b/indra/newview/llchiclet.h @@ -325,7 +325,7 @@ public: {}; - virtual ~LLIMChiclet() {}; + virtual ~LLIMChiclet(); /** * It is used for default setting up of chicklet:click handler, etc. @@ -456,7 +456,7 @@ protected: bool canCreateMenu(); - LLMenuGL* mPopupMenu; + LLHandle mPopupMenuHandle; bool mShowSpeaker; bool mCounterEnabled; @@ -633,6 +633,8 @@ public: */ /*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); } + /*virtual*/ ~LLIMP2PChiclet() {}; + protected: LLIMP2PChiclet(const Params& p); friend class LLUICtrlFactory; @@ -705,6 +707,8 @@ public: */ /*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); } + /*virtual*/ ~LLAdHocChiclet() {}; + protected: LLAdHocChiclet(const Params& p); friend class LLUICtrlFactory; @@ -884,7 +888,7 @@ protected: bool mIsNewMessagesState; LLFlashTimer* mFlashToLitTimer; - LLContextMenu* mContextMenu; + LLHandle mContextMenuHandle; }; class LLNotificationChiclet : public LLSysWellChiclet diff --git a/indra/newview/llfloaterbump.cpp b/indra/newview/llfloaterbump.cpp index 7d15480091..71c0d8d57b 100644 --- a/indra/newview/llfloaterbump.cpp +++ b/indra/newview/llfloaterbump.cpp @@ -81,6 +81,14 @@ LLFloaterBump::LLFloaterBump(const LLSD& key) // Destroys the object LLFloaterBump::~LLFloaterBump() { + // Improved bump list + //auto menu = mPopupMenuHandle.get(); + //if (menu) + //{ + // menu->die(); + // mPopupMenuHandle.markDead(); + //} + // } BOOL LLFloaterBump::postBuild() @@ -90,11 +98,15 @@ BOOL LLFloaterBump::postBuild() //mList->setAllowMultipleSelection(false); //mList->setRightMouseDownCallback(boost::bind(&LLFloaterBump::onScrollListRightClicked, this, _1, _2, _3)); - //mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile("menu_avatar_other.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - //mPopupMenu->setItemVisible(std::string("Normal"), false); - //mPopupMenu->setItemVisible(std::string("Always use impostor"), false); - //mPopupMenu->setItemVisible(std::string("Never use impostor"), false); - //mPopupMenu->setItemVisible(std::string("Impostor seperator"), false); + //LLContextMenu* menu = LLUICtrlFactory::getInstance()->createFromFile("menu_avatar_other.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + //if (menu) + //{ + // mPopupMenuHandle = menu->getHandle(); + // menu->setItemVisible(std::string("Normal"), false); + // menu->setItemVisible(std::string("Always use impostor"), false); + // menu->setItemVisible(std::string("Never use impostor"), false); + // menu->setItemVisible(std::string("Impostor seperator"), false); + //} //return TRUE; mList = getChild("bump_list"); @@ -227,18 +239,19 @@ void LLFloaterBump::onScrollListRightClicked(LLUICtrl* ctrl, S32 x, S32 y) if (!gMeanCollisionList.empty()) { LLScrollListItem* item = mList->hitItem(x, y); - if (item && mPopupMenu) + auto menu = mPopupMenuHandle.get(); + if (item && menu) { mItemUUID = item->getUUID(); - mPopupMenu->buildDrawLabels(); - mPopupMenu->updateParent(LLMenuGL::sMenuContainer); + menu->buildDrawLabels(); + menu->updateParent(LLMenuGL::sMenuContainer); std::string mute_msg = (LLMuteList::getInstance()->isMuted(mItemUUID, mNames[mItemUUID])) ? "UnmuteAvatar" : "MuteAvatar"; - mPopupMenu->getChild("Avatar Mute")->setValue(LLTrans::getString(mute_msg)); - mPopupMenu->setItemEnabled(std::string("Zoom In"), bool(gObjectList.findObject(mItemUUID))); + menu->getChild("Avatar Mute")->setValue(LLTrans::getString(mute_msg)); + menu->setItemEnabled(std::string("Zoom In"), bool(gObjectList.findObject(mItemUUID))); - ((LLContextMenu*)mPopupMenu)->show(x, y); - LLMenuGL::showPopup(ctrl, mPopupMenu, x, y); + menu->show(x, y); + LLMenuGL::showPopup(ctrl, menu, x, y); } } } diff --git a/indra/newview/llfloaterbump.h b/indra/newview/llfloaterbump.h index a951d53fdc..66414dd7d0 100644 --- a/indra/newview/llfloaterbump.h +++ b/indra/newview/llfloaterbump.h @@ -76,7 +76,7 @@ private: // Improved bump list //LLScrollListCtrl* mList; - //LLMenuGL* mPopupMenu; + //LLHandle mPopupMenuHandle; //LLUUID mItemUUID; //typedef std::map uuid_map_t; diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index af96c3ce22..c9d549dc6d 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -215,6 +215,7 @@ BOOL LLFloaterIMContainer::postBuild() p.options_menu = "menu_conversation.xml"; mConversationsRoot = LLUICtrlFactory::create(p); mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar); + mConversationsRoot->setEnableRegistrar(&mEnableCallbackRegistrar); // Add listener to conversation model events mConversationsEventStream.listen("ConversationsRefresh", boost::bind(&LLFloaterIMContainer::onConversationModelEvent, this, _1)); diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 220f567ba9..660891f564 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -319,6 +319,7 @@ BOOL LLFloaterIMSessionTab::postBuild() p.name = "root"; mConversationsRoot = LLUICtrlFactory::create(p); mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar); + mConversationsRoot->setEnableRegistrar(&mEnableCallbackRegistrar); // Attach that root to the scroller mScroller->addChild(mConversationsRoot); mConversationsRoot->setScrollContainer(mScroller); diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 6cda352d7a..765e66bd13 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -233,7 +233,11 @@ LLFolderView * LLInventoryPanel::createFolderRoot(LLUUID root_id ) p.item_top_pad = default_params.item_top_pad - (default_params.item_height - fsFolderViewItemHeight) / 2 - 1; // - return LLUICtrlFactory::create(p); + LLFolderView* fv = LLUICtrlFactory::create(p); + fv->setCallbackRegistrar(&mCommitCallbackRegistrar); + fv->setEnableRegistrar(&mEnableCallbackRegistrar); + + return fv; } void LLInventoryPanel::clearFolderRoot() @@ -286,6 +290,7 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params) } mCommitCallbackRegistrar.popScope(); mFolderRoot.get()->setCallbackRegistrar(&mCommitCallbackRegistrar); + mFolderRoot.get()->setEnableRegistrar(&mEnableCallbackRegistrar); // Scroller LLRect scroller_view_rect = getRect(); 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(); } diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 5bba2f9e54..6e728b7f6d 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -112,7 +112,6 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) : mTrusted(p.trusted_content), mWindowShade(NULL), mHoverTextChanged(false), - mContextMenu(NULL), mAllowFileDownload(false) { { @@ -157,6 +156,13 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) : LLMediaCtrl::~LLMediaCtrl() { + auto menu = mContextMenuHandle.get(); + if (menu) + { + menu->die(); + mContextMenuHandle.markDead(); + } + if (mMediaSource) { mMediaSource->remObserver( this ); @@ -342,15 +348,33 @@ BOOL LLMediaCtrl::handleRightMouseDown( S32 x, S32 y, MASK mask ) setFocus( TRUE ); } - if (mContextMenu) + auto menu = mContextMenuHandle.get(); + if (!menu) + { + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registar; + registar.add("Open.WebInspector", boost::bind(&LLMediaCtrl::onOpenWebInspector, this)); + + // stinson 05/05/2014 : use this as the parent of the context menu if the static menu + // container has yet to be created + LLPanel* menuParent = (LLMenuGL::sMenuContainer != NULL) ? dynamic_cast(LLMenuGL::sMenuContainer) : dynamic_cast(this); + llassert(menuParent != NULL); + menu = LLUICtrlFactory::getInstance()->createFromFile( + "menu_media_ctrl.xml", menuParent, LLViewerMenuHolderGL::child_registry_t::instance()); + if (menu) + { + mContextMenuHandle = menu->getHandle(); + } + } + + if (menu) { // hide/show debugging options bool media_plugin_debugging_enabled = gSavedSettings.getBOOL("MediaPluginDebugging"); - mContextMenu->setItemVisible("open_webinspector", media_plugin_debugging_enabled ); - mContextMenu->setItemVisible("debug_separator", media_plugin_debugging_enabled ); + menu->setItemVisible("open_webinspector", media_plugin_debugging_enabled ); + menu->setItemVisible("debug_separator", media_plugin_debugging_enabled ); - mContextMenu->show(x, y); - LLMenuGL::showPopup(this, mContextMenu, x, y); + menu->show(x, y); + LLMenuGL::showPopup(this, menu, x, y); } return TRUE; @@ -460,15 +484,6 @@ void LLMediaCtrl::setFocus(BOOL b) // BOOL LLMediaCtrl::postBuild () { - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registar; - registar.add("Open.WebInspector", boost::bind(&LLMediaCtrl::onOpenWebInspector, this)); - - // stinson 05/05/2014 : use this as the parent of the context menu if the static menu - // container has yet to be created - LLPanel* menuParent = (LLMenuGL::sMenuContainer != NULL) ? dynamic_cast(LLMenuGL::sMenuContainer) : dynamic_cast(this); - llassert(menuParent != NULL); - mContextMenu = LLUICtrlFactory::getInstance()->createFromFile( - "menu_media_ctrl.xml", menuParent, LLViewerMenuHolderGL::child_registry_t::instance()); setVisibleCallback(boost::bind(&LLMediaCtrl::onVisibilityChanged, this, _2)); return TRUE; @@ -1300,11 +1315,6 @@ void LLMediaCtrl::setTrustedContent(bool trusted) } } -void LLMediaCtrl::updateContextMenuParent(LLView* pNewParent) -{ - mContextMenu->updateParent(pNewParent); -} - bool LLMediaCtrl::wantsKeyUpKeyDown() const { return true; diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h index 2372e3d7b0..0f1bcb6f75 100644 --- a/indra/newview/llmediactrl.h +++ b/indra/newview/llmediactrl.h @@ -175,8 +175,6 @@ public: LLUUID getTextureID() {return mMediaTextureID;} - void updateContextMenuParent(LLView* pNewParent); - // The Browser windows want keyup and keydown events. Overridden from LLFocusableElement to return true. virtual bool wantsKeyUpKeyDown() const; virtual bool wantsReturnKey() const; @@ -221,7 +219,7 @@ public: mTextureHeight; class LLWindowShade* mWindowShade; - LLContextMenu* mContextMenu; + LLHandle mContextMenuHandle; }; #endif // LL_LLMediaCtrl_H diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index e92476f465..1133552263 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -136,11 +136,10 @@ LLNetMap::LLNetMap (const Params & p) mParcelRawImagep(), mParcelImagep(), // [/SL:KB] - mClosestAgentToCursor(), + mClosestAgentToCursor() // mClosestAgentAtLastRightClick(), // Synchronize tooltips throughout instances - //mToolTipMsg(), - mPopupMenu(NULL) + //mToolTipMsg() { // Fixing borked minimap zoom level persistance //mScale = gSavedSettings.getF32("MiniMapScale"); @@ -152,6 +151,13 @@ LLNetMap::LLNetMap (const Params & p) LLNetMap::~LLNetMap() { + auto menu = static_cast(mPopupMenuHandle.get()); + if (menu) + { + menu->die(); + mPopupMenuHandle.markDead(); + } + // Protect avatar name lookup callbacks for (avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.begin(); it != mAvatarNameCacheConnections.end(); ++it) { @@ -240,7 +246,8 @@ BOOL LLNetMap::postBuild() mParcelOverlayConn = LLViewerParcelOverlay::setUpdateCallback(boost::bind(&LLNetMap::refreshParcelOverlay, this)); // [/SL:KB] - mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile("menu_mini_map.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile("menu_mini_map.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + mPopupMenuHandle = menu->getHandle(); // Synchronize tooltips throughout instances LLNetMap::updateToolTipMsg(); @@ -1556,11 +1563,15 @@ void LLNetMap::setAvatarProfileLabel(const LLUUID& av_id, const LLAvatarName& av mAvatarNameCacheConnections.erase(it); } - LLMenuItemGL* pItem = mPopupMenu->findChild(item_name, TRUE /*recurse*/); - if (pItem) + auto menu = static_cast(mPopupMenuHandle.get()); + if (menu) { - pItem->setLabel(avName.getCompleteName()); - pItem->getMenu()->arrange(); + LLMenuItemGL* pItem = menu->findChild(item_name, TRUE /*recurse*/); + if (pItem) + { + pItem->setLabel(avName.getCompleteName()); + pItem->getMenu()->arrange(); + } } } @@ -1614,23 +1625,24 @@ void LLNetMap::handleTextureType(const LLSD& sdParam) const BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask) { - if (mPopupMenu) + auto menu = static_cast(mPopupMenuHandle.get()); + if (menu) { // [SL:KB] - Patch: World-MiniMap | Checked: 2012-07-08 (Catznip-3.3) mClosestAgentRightClick = mClosestAgentToCursor; mClosestAgentsRightClick = mClosestAgentsToCursor; mPosGlobalRightClick = viewPosToGlobal(x, y); - mPopupMenu->setItemVisible("Add to Set Multiple", mClosestAgentsToCursor.size() > 1); - mPopupMenu->setItemVisible("More Options", mClosestAgentsToCursor.size() == 1); - mPopupMenu->setItemVisible("View Profile", mClosestAgentsToCursor.size() == 1); + menu->setItemVisible("Add to Set Multiple", mClosestAgentsToCursor.size() > 1); + menu->setItemVisible("More Options", mClosestAgentsToCursor.size() == 1); + menu->setItemVisible("View Profile", mClosestAgentsToCursor.size() == 1); bool can_show_names = !RlvActions::hasBehaviour(RLV_BHVR_SHOWNAMES); - mPopupMenu->setItemEnabled("Add to Set Multiple", can_show_names); - mPopupMenu->setItemEnabled("More Options", can_show_names); - mPopupMenu->setItemEnabled("View Profile", can_show_names); + menu->setItemEnabled("Add to Set Multiple", can_show_names); + menu->setItemEnabled("More Options", can_show_names); + menu->setItemEnabled("View Profile", can_show_names); - LLMenuItemBranchGL* pProfilesMenu = mPopupMenu->getChild("View Profiles"); + LLMenuItemBranchGL* pProfilesMenu = menu->getChild("View Profiles"); if (pProfilesMenu) { pProfilesMenu->setVisible(mClosestAgentsToCursor.size() > 1); @@ -1669,22 +1681,22 @@ BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask) pProfilesMenu->getBranch()->addChild(pMenuItem); } } - mPopupMenu->setItemVisible("Cam", LLAvatarActions::canZoomIn(mClosestAgentToCursor)); - mPopupMenu->setItemVisible("MarkAvatar", mClosestAgentToCursor.notNull()); - mPopupMenu->setItemVisible("Start Tracking", mClosestAgentToCursor.notNull()); - mPopupMenu->setItemVisible("Profile Separator", (mClosestAgentsToCursor.size() >= 1 || mClosestAgentToCursor.notNull())); - mPopupMenu->setItemEnabled("Place Profile", RlvActions::canShowLocation()); - mPopupMenu->setItemEnabled("World Map", !RlvActions::hasBehaviour(RLV_BHVR_SHOWWORLDMAP)); + menu->setItemVisible("Cam", LLAvatarActions::canZoomIn(mClosestAgentToCursor)); + menu->setItemVisible("MarkAvatar", mClosestAgentToCursor.notNull()); + menu->setItemVisible("Start Tracking", mClosestAgentToCursor.notNull()); + menu->setItemVisible("Profile Separator", (mClosestAgentsToCursor.size() >= 1 || mClosestAgentToCursor.notNull())); + menu->setItemEnabled("Place Profile", RlvActions::canShowLocation()); + menu->setItemEnabled("World Map", !RlvActions::hasBehaviour(RLV_BHVR_SHOWWORLDMAP)); // [/SL:KB] - mPopupMenu->buildDrawLabels(); - mPopupMenu->updateParent(LLMenuGL::sMenuContainer); + menu->buildDrawLabels(); + menu->updateParent(LLMenuGL::sMenuContainer); // [SL:KB] - Patch: World-MiniMap | Checked: 2012-07-08 (Catznip-3.3) - mPopupMenu->setItemVisible("Stop Tracking", LLTracker::isTracking(0)); - mPopupMenu->setItemVisible("Stop Tracking Separator", LLTracker::isTracking(0)); + menu->setItemVisible("Stop Tracking", LLTracker::isTracking(0)); + menu->setItemVisible("Stop Tracking Separator", LLTracker::isTracking(0)); // [/SL:KB] -// mPopupMenu->setItemEnabled("Stop Tracking", LLTracker::isTracking(0)); - LLMenuGL::showPopup(this, mPopupMenu, x, y); +// menu->setItemEnabled("Stop Tracking", LLTracker::isTracking(0)); + LLMenuGL::showPopup(this, menu, x, y); } return TRUE; } @@ -1940,11 +1952,12 @@ void LLNetMap::handleStartTracking() void LLNetMap::handleStopTracking (const LLSD& userdata) { - if (mPopupMenu) + auto menu = static_cast(mPopupMenuHandle.get()); + if (menu) { // Hide tracking option instead of disabling - //mPopupMenu->setItemEnabled ("Stop Tracking", false); - mPopupMenu->setItemVisible ("Stop Tracking", false); + //menu->setItemEnabled ("Stop Tracking", false); + menu->setItemVisible ("Stop Tracking", false); // LLTracker::stopTracking (LLTracker::isTracking(NULL)); } diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h index a06a10b8e5..d6e36c3259 100644 --- a/indra/newview/llnetmap.h +++ b/indra/newview/llnetmap.h @@ -245,7 +245,7 @@ private: void handleEstateBan(); void handleDerender(bool permanent); - LLMenuGL* mPopupMenu; + LLHandle mPopupMenuHandle; uuid_vec_t gmSelected; }; diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index b46d79ac43..7ec10f9bed 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -419,6 +419,13 @@ LLPanelMainInventory::~LLPanelMainInventory( void ) gInventory.removeObserver(this); delete mSavedFolderState; + + auto menu = mMenuAddHandle.get(); + if(menu) + { + menu->die(); + mMenuAddHandle.markDead(); + } } LLInventoryPanel* LLPanelMainInventory::getAllItemsPanel() @@ -1624,13 +1631,12 @@ void LLPanelMainInventory::initListCommandsHandlers() mEnableCallbackRegistrar.add("Inventory.GearDefault.Check", boost::bind(&LLPanelMainInventory::isActionChecked, this, _2)); mEnableCallbackRegistrar.add("Inventory.GearDefault.Enable", boost::bind(&LLPanelMainInventory::isActionEnabled, this, _2)); mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile("menu_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - mGearMenuButton->setMenu(mMenuGearDefault); + mGearMenuButton->setMenu(mMenuGearDefault, LLMenuButton::MP_TOP_LEFT, true); LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); mMenuAddHandle = menu->getHandle(); mMenuVisibility = LLUICtrlFactory::getInstance()->createFromFile("menu_inventory_search_visibility.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - mVisibilityMenuButton->setMenu(mMenuVisibility); - mVisibilityMenuButton->setMenuPosition(LLMenuButton::MP_BOTTOM_LEFT); + mVisibilityMenuButton->setMenu(mMenuVisibility, LLMenuButton::MP_BOTTOM_LEFT, true); // Update the trash button when selected item(s) get worn or taken off. LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLPanelMainInventory::updateListCommands, this)); diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index 39ce92f724..479c17d266 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -1536,6 +1536,7 @@ void LLPanelObjectInventory::reset() mFolders = LLUICtrlFactory::create(p); mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar); + mFolders->setEnableRegistrar(&mEnableCallbackRegistrar); if (hasFocus()) { diff --git a/indra/newview/llviewerinput.cpp b/indra/newview/llviewerinput.cpp index 881a7df71a..df68909ffc 100644 --- a/indra/newview/llviewerinput.cpp +++ b/indra/newview/llviewerinput.cpp @@ -1707,12 +1707,22 @@ BOOL LLViewerInput::handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK mask, clicktype = CLICK_DOUBLELEFT; } + // If the first LMB click is handled by the menu, skip the following double click + static bool skip_double_click = false; + if (clicktype == CLICK_LEFT && down ) + { + skip_double_click = handled; + } if (double_click_sp && down) { // Consume click. // Due to handling, double click that is not handled will be immediately followed by LMB click } + else if (clicktype == CLICK_DOUBLELEFT && skip_double_click) + { + handled = true; + } // If UI handled 'down', it should handle 'up' as well // If we handle 'down' not by UI, then we should handle 'up'/'level' regardless of UI else if (handled) diff --git a/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp index f042040e98..1751ee1ebb 100644 --- a/indra/newview/llviewerpartsource.cpp +++ b/indra/newview/llviewerpartsource.cpp @@ -793,7 +793,7 @@ void LLViewerPartSourceBeam::update(const F32 dt) } LLViewerPart* part = new LLViewerPart(); - part->init(this, mImagep, NULL); + part->init(this, mImagep, updatePart); part->mFlags = LLPartData::LL_PART_INTERP_COLOR_MASK | LLPartData::LL_PART_INTERP_SCALE_MASK | diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index d060715e26..291640b33d 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -3914,6 +3914,59 @@ void LLViewerWindow::updateUI() root_view = mRootView; } + static LLCachedControl dump_menu_holder(gSavedSettings, "DumpMenuHolderSize", false); + if (dump_menu_holder) + { + static bool init = false; + static LLFrameTimer child_count_timer; + static std::vector child_vec; + if (!init) + { + child_count_timer.resetWithExpiry(5.f); + init = true; + } + if (child_count_timer.hasExpired()) + { + LL_INFOS() << "gMenuHolder child count: " << gMenuHolder->getChildCount() << LL_ENDL; + std::vector local_child_vec; + LLView::child_list_t child_list = *gMenuHolder->getChildList(); + for (auto child : child_list) + { + local_child_vec.emplace_back(child->getName()); + } + if (!local_child_vec.empty() && local_child_vec != child_vec) + { + std::vector out_vec; + std::sort(local_child_vec.begin(), local_child_vec.end()); + std::sort(child_vec.begin(), child_vec.end()); + std::set_difference(child_vec.begin(), child_vec.end(), local_child_vec.begin(), local_child_vec.end(), std::inserter(out_vec, out_vec.begin())); + if (!out_vec.empty()) + { + LL_INFOS() << "gMenuHolder removal diff size: '"<