diff options
author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2025-02-06 19:06:09 +0200 |
---|---|---|
committer | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2025-02-07 18:34:04 +0200 |
commit | 95106e203cb20b596810c4227acfa45e81358ef9 (patch) | |
tree | ba49f0a12b651f24be1f4e1c377238c9c993ff43 | |
parent | 046ec79d2288cbe9e65999ea9e693652036c1813 (diff) |
#3505 Fix updateMenu() being called too frequently on fetch callback
The actual problem is fetch dumping thousands of callbacks, but this
should mitigate the problem
-rw-r--r-- | indra/llui/llfolderview.cpp | 40 | ||||
-rw-r--r-- | indra/llui/llfolderview.h | 1 |
2 files changed, 36 insertions, 5 deletions
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp index 42a9e267d2..a059c4d741 100644 --- a/indra/llui/llfolderview.cpp +++ b/indra/llui/llfolderview.cpp @@ -28,6 +28,7 @@ #include "llfolderview.h" #include "llfolderviewmodel.h" +#include "llcallbacklist.h" #include "llclipboard.h" // *TODO: remove this once hack below gone. #include "llkeyboard.h" #include "lllineeditor.h" @@ -274,7 +275,11 @@ LLFolderView::~LLFolderView( void ) mRenamer = NULL; mStatusTextBox = NULL; - if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die(); + if (mPopupMenuHandle.get()) + { + mPopupMenuHandle.get()->die(); + gIdleCallbacks.deleteFunction(onIdleUpdateMenu, this); + } mPopupMenuHandle.markDead(); mAutoOpenItems.removeAllNodes(); @@ -1095,7 +1100,10 @@ bool LLFolderView::handleKeyHere( KEY key, MASK mask ) LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); if (menu && menu->isOpen()) { - LLMenuGL::sMenuContainer->hideMenus(); + if (LLMenuGL::sMenuContainer->hideMenus()) + { + gIdleCallbacks.deleteFunction(onIdleUpdateMenu, this); + } } switch( key ) @@ -1340,7 +1348,10 @@ bool LLFolderView::handleUnicodeCharHere(llwchar uni_char) LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); if (menu && menu->isOpen()) { - LLMenuGL::sMenuContainer->hideMenus(); + if (LLMenuGL::sMenuContainer->hideMenus()) + { + gIdleCallbacks.deleteFunction(onIdleUpdateMenu, this); + } } //do text search @@ -1612,7 +1623,11 @@ void LLFolderView::deleteAllChildren() { LLUI::getInstance()->removePopup(mRenamer); } - if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die(); + if (mPopupMenuHandle.get()) + { + mPopupMenuHandle.get()->die(); + gIdleCallbacks.deleteFunction(onIdleUpdateMenu, this); + } mPopupMenuHandle.markDead(); mScrollContainer = NULL; mRenameItem = NULL; @@ -1979,9 +1994,24 @@ void LLFolderView::updateMenu() LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); if (menu && menu->getVisible()) { - updateMenuOptions(menu); + // When fetching folders in bulk or in parts, each callback + // cause updateMenu individually, so make sure it gets called + // only once per frame, after callbacks are done. + // gIdleCallbacks has built in dupplicate protection. + gIdleCallbacks.addFunction(onIdleUpdateMenu, this); + } +} + +void LLFolderView::onIdleUpdateMenu(void* user_data) +{ + LLFolderView* self = (LLFolderView*)user_data; + LLMenuGL* menu = (LLMenuGL*)self->mPopupMenuHandle.get(); + if (menu) + { + self->updateMenuOptions(menu); menu->needsArrange(); // update menu height if needed } + gIdleCallbacks.deleteFunction(onIdleUpdateMenu, NULL); } bool LLFolderView::isFolderSelected() diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h index 82637e33ea..7ed10d9223 100644 --- a/indra/llui/llfolderview.h +++ b/indra/llui/llfolderview.h @@ -266,6 +266,7 @@ public: private: void updateMenuOptions(LLMenuGL* menu); void updateRenamerPosition(); + static void onIdleUpdateMenu(void* user_data); protected: LLScrollContainer* mScrollContainer; // NULL if this is not a child of a scroll container. |