diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp index fa98ee2ed4..8851c34826 100644 --- a/indra/llaudio/llaudioengine.cpp +++ b/indra/llaudio/llaudioengine.cpp @@ -660,7 +660,7 @@ bool LLAudioEngine::preloadSound(const LLUUID &uuid) LL_DEBUGS("AudioEngine")<<"( "< Protect against corrupted sounds. Just do a quick exit instead of trying to preload over and over again. - if( gAudiop->isCorruptSound( uuid ) ) + if (gAudiop && gAudiop->isCorruptSound(uuid)) return false; // @@ -1317,7 +1317,7 @@ std::map gSoundHistory; void LLAudioSource::logSoundPlay(const LLUUID& id, LLVector3d position, S32 type, const LLUUID& assetid, const LLUUID& ownerid, const LLUUID& sourceid, bool is_trigger, bool is_looped) { // Corrupt asset, do not bother - if( gAudiop->isCorruptSound( assetid ) ) + if (gAudiop && gAudiop->isCorruptSound(assetid)) return; // diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp index 9c40acaa62..1977f509d0 100644 --- a/indra/llinventory/llinventory.cpp +++ b/indra/llinventory/llinventory.cpp @@ -1073,7 +1073,13 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new) // TODO - figure out if this should be moved into the noclobber fields above mThumbnailUUID.setNull(); mFavorite = false; - mPermissions.init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null); + // [FIRE-36028] Fix OpenSim object permissions + //mPermissions.init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null); + if (!LLPermissions::getIsInOpenSim()) + { + mPermissions.init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null); + } + // // iterate as map to avoid making unnecessary temp copies of everything LLSD::map_const_iterator i, end; diff --git a/indra/llinventory/llpermissions.cpp b/indra/llinventory/llpermissions.cpp index 03cd7771d4..c49bacf040 100644 --- a/indra/llinventory/llpermissions.cpp +++ b/indra/llinventory/llpermissions.cpp @@ -39,6 +39,8 @@ const LLPermissions LLPermissions::DEFAULT; +bool LLPermissions::sIsInOpenSim = false; // [FIRE-36028] Fix OpenSim object permissions + // No creator = created by system LLPermissions::LLPermissions() { diff --git a/indra/llinventory/llpermissions.h b/indra/llinventory/llpermissions.h index 469eacc5ef..70b29cd312 100644 --- a/indra/llinventory/llpermissions.h +++ b/indra/llinventory/llpermissions.h @@ -103,6 +103,8 @@ private: // values. bool mIsGroupOwned; + static bool sIsInOpenSim; // [FIRE-36028] Fix OpenSim object permissions + // Correct for fair use - you can never take away the right to // move stuff you own, and you can never take away the right to // transfer something you cannot otherwise copy. @@ -288,6 +290,11 @@ public: inline bool allowOpenSimExportBy(const LLUUID& agent_id) const; // OpenSim export permission #endif + // [FIRE-36028] Fix OpenSim object permissions + static bool getIsInOpenSim() { return sIsInOpenSim; } + static void setupIsInOpenSim(bool is_in_open_sim) { sIsInOpenSim = is_in_open_sim; } + // + // // MISC METHODS and OPERATORS // diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp index 495ba2f40f..1a64c2699d 100644 --- a/indra/llui/llaccordionctrl.cpp +++ b/indra/llui/llaccordionctrl.cpp @@ -303,8 +303,11 @@ void LLAccordionCtrl::ctrlSetLeftTopAndSize(LLView* panel, S32 left, S32 top, S3 return; LLRect panel_rect = panel->getRect(); panel_rect.setLeftTopAndSize( left, top, width, height); - panel->reshape( width, height, 1); - panel->setRect(panel_rect); + if (panel->getRect() != panel_rect) + { + panel->reshape( width, height, 1); + panel->setRect(panel_rect); + } } void LLAccordionCtrl::ctrlShiftVertical(LLView* panel, S32 delta) @@ -494,6 +497,7 @@ void LLAccordionCtrl::arrangeMultiple() void LLAccordionCtrl::arrange() { + LL_PROFILE_ZONE_SCOPED; updateNoTabsHelpTextVisibility(); if (mAccordionTabs.empty()) diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp index ac66525030..bdf93348bb 100644 --- a/indra/llui/llaccordionctrltab.cpp +++ b/indra/llui/llaccordionctrltab.cpp @@ -248,10 +248,22 @@ void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::draw() void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::reshape(S32 width, S32 height, bool called_from_parent /* = true */) { S32 header_height = mHeaderTextbox->getTextPixelHeight(); + LLRect old_header_rect = mHeaderTextbox->getRect(); LLRect textboxRect(HEADER_TEXT_LEFT_OFFSET, (height + header_height) / 2, width, (height - header_height) / 2); - mHeaderTextbox->reshape(textboxRect.getWidth(), textboxRect.getHeight()); - mHeaderTextbox->setRect(textboxRect); + if (old_header_rect.getHeight() != textboxRect.getHeight() + || old_header_rect.mLeft != textboxRect.mLeft + || old_header_rect.mTop != textboxRect.mTop + || old_header_rect.getWidth() > textboxRect.getWidth() // reducing header's width + || (old_header_rect.getWidth() < textboxRect.getWidth() && old_header_rect.getWidth() < mHeaderTextbox->getTextPixelWidth())) + { + // Expensive text reflow + // Update if position or height changes + // Update if width reduces + // But do not update if text already fits and width increases (arguably LLTextBox::reshape should be smarter, not Accordion) + mHeaderTextbox->reshape(textboxRect.getWidth(), textboxRect.getHeight()); + mHeaderTextbox->setRect(textboxRect); + } if (mHeaderTextbox->getTextPixelWidth() > mHeaderTextbox->getRect().getWidth()) { @@ -416,8 +428,11 @@ void LLAccordionCtrlTab::reshape(S32 width, S32 height, bool called_from_parent LLRect headerRect; headerRect.setLeftTopAndSize(0, height, width, HEADER_HEIGHT); - mHeader->setRect(headerRect); - mHeader->reshape(headerRect.getWidth(), headerRect.getHeight()); + if (mHeader->getRect() != headerRect) + { + mHeader->setRect(headerRect); + mHeader->reshape(headerRect.getWidth(), headerRect.getHeight()); + } if (!mDisplayChildren) return; @@ -932,7 +947,7 @@ void LLAccordionCtrlTab::adjustContainerPanel(const LLRect& child_rect) show_hide_scrollbar(child_rect); updateLayout(child_rect); } - else + else if (mContainerPanel->getRect() != child_rect) { mContainerPanel->reshape(child_rect.getWidth(), child_rect.getHeight()); mContainerPanel->setRect(child_rect); diff --git a/indra/llui/llchatmentionhelper.cpp b/indra/llui/llchatmentionhelper.cpp index 5745389a58..d7cf60daef 100644 --- a/indra/llui/llchatmentionhelper.cpp +++ b/indra/llui/llchatmentionhelper.cpp @@ -39,6 +39,13 @@ bool LLChatMentionHelper::isActive(const LLUICtrl* ctrl) const bool LLChatMentionHelper::isCursorInNameMention(const LLWString& wtext, S32 cursor_pos, S32* mention_start_pos) const { + // Enable auto-completion of @ mentions + static LLUICachedControl useMentionAutoComplete("FSUseChatMentionAutoComplete", true); + if (!useMentionAutoComplete) + { + return false; + } + // if (cursor_pos <= 0 || cursor_pos > static_cast(wtext.size())) return false; diff --git a/indra/llui/llemojihelper.cpp b/indra/llui/llemojihelper.cpp index 7d5be5f049..3367eb0f0a 100644 --- a/indra/llui/llemojihelper.cpp +++ b/indra/llui/llemojihelper.cpp @@ -58,7 +58,7 @@ bool LLEmojiHelper::isActive(const LLUICtrl* ctrl_p) const bool LLEmojiHelper::isCursorInEmojiCode(const LLWString& wtext, S32 cursorPos, S32* pShortCodePos) { // FIRE-33735: Option to suppress emoji chooser window from automatically popping up while typing in chat bars - static LLUICachedControl FSEnableEmojiWindowPopupWhileTyping("FSEnableEmojiWindowPopupWhileTyping"); + static LLUICachedControl FSEnableEmojiWindowPopupWhileTyping("FSEnableEmojiWindowPopupWhileTyping", true); if (!FSEnableEmojiWindowPopupWhileTyping) { return false; diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index e06affab37..c28b7d6070 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1592,6 +1592,8 @@ void LLTextBase::reshape(S32 width, S32 height, bool called_from_parent) // up-to-date mVisibleTextRect updateRects(); + // Todo: This might be wrong. updateRects already sets needsReflow conditionaly. + // Reflow is expensive and doing it at any twith can be too much. needsReflow(); } } diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp index b4f2b722c9..d686082878 100644 --- a/indra/llwebrtc/llwebrtc.cpp +++ b/indra/llwebrtc/llwebrtc.cpp @@ -353,6 +353,7 @@ void LLWebRTCImpl::init() //updateDevices(); } }); + } void LLWebRTCImpl::terminate() diff --git a/indra/newview/poses/hand_presets/Flat.xml b/indra/newview/app_settings/poses/hand_presets/Flat.xml similarity index 100% rename from indra/newview/poses/hand_presets/Flat.xml rename to indra/newview/app_settings/poses/hand_presets/Flat.xml diff --git a/indra/newview/poses/hand_presets/Grip.xml b/indra/newview/app_settings/poses/hand_presets/Grip.xml similarity index 100% rename from indra/newview/poses/hand_presets/Grip.xml rename to indra/newview/app_settings/poses/hand_presets/Grip.xml diff --git a/indra/newview/poses/hand_presets/Horns.xml b/indra/newview/app_settings/poses/hand_presets/Horns.xml similarity index 100% rename from indra/newview/poses/hand_presets/Horns.xml rename to indra/newview/app_settings/poses/hand_presets/Horns.xml diff --git a/indra/newview/poses/hand_presets/Okay.xml b/indra/newview/app_settings/poses/hand_presets/Okay.xml similarity index 100% rename from indra/newview/poses/hand_presets/Okay.xml rename to indra/newview/app_settings/poses/hand_presets/Okay.xml diff --git a/indra/newview/poses/hand_presets/Pointing.xml b/indra/newview/app_settings/poses/hand_presets/Pointing.xml similarity index 100% rename from indra/newview/poses/hand_presets/Pointing.xml rename to indra/newview/app_settings/poses/hand_presets/Pointing.xml diff --git a/indra/newview/poses/hand_presets/Relaxed.xml b/indra/newview/app_settings/poses/hand_presets/Relaxed.xml similarity index 100% rename from indra/newview/poses/hand_presets/Relaxed.xml rename to indra/newview/app_settings/poses/hand_presets/Relaxed.xml diff --git a/indra/newview/poses/hand_presets/Thumbs_Up.xml b/indra/newview/app_settings/poses/hand_presets/Thumbs_Up.xml similarity index 100% rename from indra/newview/poses/hand_presets/Thumbs_Up.xml rename to indra/newview/app_settings/poses/hand_presets/Thumbs_Up.xml diff --git a/indra/newview/poses/hand_presets/Tight_Grip.xml b/indra/newview/app_settings/poses/hand_presets/Tight_Grip.xml similarity index 100% rename from indra/newview/poses/hand_presets/Tight_Grip.xml rename to indra/newview/app_settings/poses/hand_presets/Tight_Grip.xml diff --git a/indra/newview/poses/hand_presets/Two_Finger_Salute.xml b/indra/newview/app_settings/poses/hand_presets/Two_Finger_Salute.xml similarity index 99% rename from indra/newview/poses/hand_presets/Two_Finger_Salute.xml rename to indra/newview/app_settings/poses/hand_presets/Two_Finger_Salute.xml index 4648f19c9b..7a750ec015 100644 --- a/indra/newview/poses/hand_presets/Two_Finger_Salute.xml +++ b/indra/newview/app_settings/poses/hand_presets/Two_Finger_Salute.xml @@ -758,7 +758,7 @@ version value - 5 + 6 diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 9b7d6935ac..22d01c90e6 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -26469,6 +26469,17 @@ Change of this parameter will affect the layout of buttons in notification toast Value 1 + FSUseChatMentionAutoComplete + + Comment + Enable auto-completion when typing @ mentions in chat. + Persist + 1 + Type + Boolean + Value + 1 + FSUseBWEmojis Comment diff --git a/indra/newview/fsfloaterposer.cpp b/indra/newview/fsfloaterposer.cpp index 02202e34ee..cd9934dc41 100644 --- a/indra/newview/fsfloaterposer.cpp +++ b/indra/newview/fsfloaterposer.cpp @@ -462,28 +462,32 @@ void FSFloaterPoser::createUserPoseDirectoryIfNeeded() gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, POSE_SAVE_SUBDIRECTORY); std::string userHandPresetsPath = userPath + gDirUtilp->getDirDelimiter() + std::string(POSE_PRESETS_HANDS_SUBDIRECTORY); - if (gDirUtilp->fileExists(userHandPresetsPath)) - return; try { - if (!gDirUtilp->fileExists(userPath)) - { - LL_WARNS("Poser") << "Couldn't find folder: " << userPath << " - creating one." << LL_ENDL; - LLFile::mkdir(userPath); - } - if (!gDirUtilp->fileExists(userHandPresetsPath)) { - LL_WARNS("Poser") << "Couldn't find folder: " << userHandPresetsPath << " - creating one." << LL_ENDL; - LLFile::mkdir(userHandPresetsPath); + if (!gDirUtilp->fileExists(userPath)) + { + LL_WARNS("Poser") << "Couldn't find folder: " << userPath << " - creating one." << LL_ENDL; + LLFile::mkdir(userPath); + } + + if (!gDirUtilp->fileExists(userHandPresetsPath)) + { + LL_WARNS("Poser") << "Couldn't find folder: " << userHandPresetsPath << " - creating one." << LL_ENDL; + LLFile::mkdir(userHandPresetsPath); + } } std::string sourcePresetPath = - gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, POSE_SAVE_SUBDIRECTORY, std::string(POSE_PRESETS_HANDS_SUBDIRECTORY)); + gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, POSE_SAVE_SUBDIRECTORY, std::string(POSE_PRESETS_HANDS_SUBDIRECTORY)); if (!gDirUtilp->fileExists(sourcePresetPath)) + { + LL_WARNS("Poser") << "Can not copy poser presets because failed to find path: " << sourcePresetPath << LL_ENDL; return; + } auto posesToCopy = gDirUtilp->getFilesInDir(sourcePresetPath); for (const auto& pose : posesToCopy) @@ -491,13 +495,24 @@ void FSFloaterPoser::createUserPoseDirectoryIfNeeded() std::string source = sourcePresetPath + gDirUtilp->getDirDelimiter() + pose; std::string destination = userHandPresetsPath + gDirUtilp->getDirDelimiter() + pose; + S32 sourceVersion = tryGetPoseVersion(source); + S32 destinationVersion = tryGetPoseVersion(destination); + if (destinationVersion >= sourceVersion) + continue; + + if (gDirUtilp->fileExists(destination)) + { + LL_WARNS("Poser") << "Removing pose file " << destination << " to replace with updated version " << LL_ENDL; + LLFile::remove(destination); + } + if (!LLFile::copy(source, destination)) LL_WARNS("Poser") << "Failed to copy " << source << " to " << destination << LL_ENDL; } } catch (const std::exception& e) { - LL_WARNS("Posing") << "Exception caught trying to create: " << userPath << e.what() << LL_ENDL; + LL_WARNS("Posing") << "Exception caught trying to create/update poses: " << e.what() << LL_ENDL; } } @@ -947,6 +962,51 @@ void FSFloaterPoser::onClickLoadRightHandPose() onClickLoadHandPose(true); } +S32 FSFloaterPoser::tryGetPoseVersion(std::string pathToPoseFile) +{ + S32 version = -1; + if (pathToPoseFile.empty()) + return version; + + if (!gDirUtilp->fileExists(pathToPoseFile)) + return version; + + try + { + LLSD pose; + llifstream infile; + + infile.open(pathToPoseFile); + if (!infile.is_open()) + return version; + + while (!infile.eof()) + { + S32 lineCount = LLSDSerialize::fromXML(pose, infile); + if (lineCount == LLSDParser::PARSE_FAILURE) + { + LL_WARNS("Posing") << "Failed to parse pose file: " << pathToPoseFile << LL_ENDL; + return version; + } + + for (LLSD::map_const_iterator itr = pose.beginMap(); itr != pose.endMap(); ++itr) + { + std::string const& name = itr->first; + LLSD const& control_map = itr->second; + + if (name == "version") + return (S32)control_map["value"].asInteger(); + } + } + } + catch (const std::exception& e) + { + LL_WARNS("Posing") << "Threw an exception trying read the pose file: " << pathToPoseFile << " exception: " << e.what() << LL_ENDL; + } + + return version; +} + void FSFloaterPoser::onClickLoadHandPose(bool isRightHand) { LLScrollListItem* item = mHandPresetsScrollList->getFirstSelected(); diff --git a/indra/newview/fsfloaterposer.h b/indra/newview/fsfloaterposer.h index a88f690a4b..8d289f53f7 100644 --- a/indra/newview/fsfloaterposer.h +++ b/indra/newview/fsfloaterposer.h @@ -231,6 +231,7 @@ public: void onPoseMenuAction(const LLSD& param); bool loadPoseFromXml(LLVOAvatar* avatar, const std::string& poseFileName, E_LoadPoseMethods loadMethod); bool poseFileStartsFromTeePose(const std::string& poseFileName); + S32 tryGetPoseVersion(std::string pathToPoseFile); void setPoseSaveFileTextBoxToUiSelectedAvatarSaveFileName(); void setUiSelectedAvatarSaveFileName(const std::string& saveFileName); void timedReload(); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index e06a4dade7..bdc89674a5 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -931,7 +931,9 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, if (!isItemMovable() || !canMenuCut()) { disabled_items.push_back(std::string("Cut")); - disabled_items.push_back(std::string("New folder from selected")); + // [FIRE-35996] Restore allowing creating folder from selected on recent and favorites panels + //disabled_items.push_back(std::string("New folder from selected")); + // } } else @@ -984,7 +986,9 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, if (!isItemMovable() || !canMenuCut()) { disabled_items.push_back(std::string("Cut")); - disabled_items.push_back(std::string("New folder from selected")); + // [FIRE-35996] Restore allowing creating folder from selected on recent and favorites panels + //disabled_items.push_back(std::string("New folder from selected")); + // } if (canListOnMarketplace() && !isMarketplaceListingsFolder() && !isInboxFolder()) diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp index cfa37cc3ee..73cc953692 100644 --- a/indra/newview/llinventoryitemslist.cpp +++ b/indra/newview/llinventoryitemslist.cpp @@ -40,6 +40,10 @@ #include "llinventorymodel.h" #include "llviewerinventory.h" +bool LLInventoryItemsList::sListIdleRegistered = false; +LLInventoryItemsList::all_list_t LLInventoryItemsList::sAllLists; +LLInventoryItemsList::all_list_t::iterator LLInventoryItemsList::sAllListIter; + LLInventoryItemsList::Params::Params() {} @@ -55,13 +59,39 @@ LLInventoryItemsList::LLInventoryItemsList(const LLInventoryItemsList::Params& p setNoFilteredItemsMsg(LLTrans::getString("InventoryNoMatchingItems")); - gIdleCallbacks.addFunction(idle, this); + sAllLists.push_back(this); + sAllListIter = sAllLists.begin(); + + if (!sListIdleRegistered) + { + sAllListIter = sAllLists.begin(); + gIdleCallbacks.addFunction(idle, nullptr); + + LLEventPumps::instance().obtain("LLApp").listen( + "LLInventoryItemsList", + [](const LLSD& stat) + { + std::string status(stat["status"]); + if (status != "running") + { + // viewer is starting shutdown + gIdleCallbacks.deleteFunction(idle, nullptr); + } + return false; + }); + sListIdleRegistered = true; + } } // virtual LLInventoryItemsList::~LLInventoryItemsList() { - gIdleCallbacks.deleteFunction(idle, this); + auto it = std::find(sAllLists.begin(), sAllLists.end(), this); + if (it != sAllLists.end()) + { + sAllLists.erase(it); + sAllListIter = sAllLists.begin(); + } } void LLInventoryItemsList::refreshList(const LLInventoryModel::item_array_t item_array) @@ -111,25 +141,55 @@ void LLInventoryItemsList::updateSelection() mSelectTheseIDs.clear(); } -void LLInventoryItemsList::doIdle() +bool LLInventoryItemsList::doIdle() { - if (mRefreshState == REFRESH_COMPLETE) return; + if (mRefreshState == REFRESH_COMPLETE) return true; // done if (isInVisibleChain() || mForceRefresh || !getFilterSubString().empty()) { refresh(); mRefreshCompleteSignal(this, LLSD()); + return false; // keep going } + return true; // done } //static void LLInventoryItemsList::idle(void* user_data) { - LLInventoryItemsList* self = static_cast(user_data); - if ( self ) - { // Do the real idle - self->doIdle(); + if (sAllLists.empty()) + return; + + LL_PROFILE_ZONE_SCOPED; + + using namespace std::chrono; + auto start = steady_clock::now(); + const milliseconds time_limit = milliseconds(3); + const auto end_time = start + time_limit; + S32 max_update_count = 50; + + if (sAllListIter == sAllLists.end()) + { + sAllListIter = sAllLists.begin(); + } + + S32 updated = 0; + while (steady_clock::now() < end_time + && updated < max_update_count + && sAllListIter != sAllLists.end()) + { + LLInventoryItemsList* list = *sAllListIter; + // Refresh is split into multiple separate parts, + // so keep repeating it while there is time, until done. + // Todo: refresh() split is pointless now? + // Or still useful for large folders? + if (list->doIdle()) + { + // Item is done + ++sAllListIter; + updated++; + } } } @@ -141,6 +201,7 @@ void LLInventoryItemsList::refresh() { case REFRESH_ALL: { + LL_PROFILE_ZONE_NAMED("items_refresh_all"); mAddedItems.clear(); mRemovedItems.clear(); computeDifference(getIDs(), mAddedItems, mRemovedItems); @@ -163,6 +224,7 @@ void LLInventoryItemsList::refresh() } case REFRESH_LIST_ERASE: { + LL_PROFILE_ZONE_NAMED("items_refresh_erase"); uuid_vec_t::const_iterator it = mRemovedItems.begin(); for (; mRemovedItems.end() != it; ++it) { @@ -175,6 +237,7 @@ void LLInventoryItemsList::refresh() } case REFRESH_LIST_APPEND: { + LL_PROFILE_ZONE_NAMED("items_refresh_append"); static const unsigned ADD_LIMIT = 25; // Note: affects perfomance unsigned int nadded = 0; @@ -239,6 +302,7 @@ void LLInventoryItemsList::refresh() } case REFRESH_LIST_SORT: { + LL_PROFILE_ZONE_NAMED("items_refresh_sort"); // Filter, sort, rearrange and notify parent about shape changes filterItems(true, true); @@ -255,7 +319,10 @@ void LLInventoryItemsList::refresh() break; } default: - break; + { + mRefreshState = REFRESH_COMPLETE; + break; + } } setForceRefresh(mRefreshState != REFRESH_COMPLETE); diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h index 9ebeb5e52b..b20c27eec8 100644 --- a/indra/newview/llinventoryitemslist.h +++ b/indra/newview/llinventoryitemslist.h @@ -59,7 +59,10 @@ public: * Sets the flag indicating that the list needs to be refreshed even if it is * not currently visible. */ - void setForceRefresh(bool force_refresh) { mForceRefresh = force_refresh; } + void setForceRefresh(bool force_refresh) + { + mForceRefresh = force_refresh; + } /** * If refreshes when invisible. @@ -76,7 +79,7 @@ public: * This is needed for example to filter items of the list hidden by closed * accordion tab. */ - virtual void doIdle(); // Real idle routine + bool doIdle(); // Real idle routine static void idle(void* user_data); // static glue to doIdle() protected: @@ -126,6 +129,12 @@ private: bool mForceRefresh; commit_signal_t mRefreshCompleteSignal; + + // Update synchronization + typedef std::vector all_list_t; + static all_list_t sAllLists; + static all_list_t::iterator sAllListIter; + static bool sListIdleRegistered; }; #endif //LL_LLINVENTORYITEMSLIST_H diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index fe18dc1861..12e912d7a1 100644 --- a/indra/newview/lloutfitgallery.cpp +++ b/indra/newview/lloutfitgallery.cpp @@ -818,6 +818,7 @@ void LLOutfitGallery::getCurrentCategories(uuid_vec_t& vcur) void LLOutfitGallery::updateAddedCategory(LLUUID cat_id) { + LL_PROFILE_ZONE_SCOPED; LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id); if (!cat) return; diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 374eb09769..1dc127f8e0 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -189,6 +189,7 @@ void LLOutfitsList::onOpen(const LLSD& info) void LLOutfitsList::updateAddedCategory(LLUUID cat_id) { + LL_PROFILE_ZONE_SCOPED; LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id); if (!cat) return; @@ -260,7 +261,9 @@ void LLOutfitsList::updateAddedCategory(LLUUID cat_id) if (AISAPI::isAvailable() && LLInventoryModelBackgroundFetch::instance().folderFetchActive()) { - // for reliability just fetch it whole, linked items included + // For reliability just fetch it whole, linked items included + // Todo: list is not warrantied to exist once callback arrives + // Fix it! LLInventoryModelBackgroundFetch::instance().fetchFolderAndLinks(cat_id, [cat_id, list] { if (list) @@ -1153,6 +1156,7 @@ void LLOutfitListBase::onIdle(void* userdata) void LLOutfitListBase::onIdleRefreshList() { + LL_PROFILE_ZONE_SCOPED; if (LLAppViewer::instance()->quitRequested()) { mRefreshListState.CategoryUUID.setNull(); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 6d5c51f234..49ea751b18 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -4909,6 +4909,10 @@ bool process_login_success_response(U32 &first_sim_size_x, U32 &first_sim_size_y // [FIRE-34775] Use PST/PDT when logged into OpenSim LLStringOps::setupUsingPacificTime(!LLGridManager::getInstance()->isInSecondLife()); // + // [FIRE-36028] Fix OpenSim object permissions + LLPermissions::setupIsInOpenSim(!LLGridManager::getInstance()->isInSecondLife()); + // + } // set up the voice configuration. Ultimately, we should pass this up as part of each voice diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index d2204c7513..425eb2d020 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -4897,7 +4897,7 @@ void process_preload_sound(LLMessageSystem *msg, void **user_data) msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_OwnerID, owner_id); // Protect against corrupted sounds - if (gAudiop->isCorruptSound(sound_id)) + if (gAudiop && gAudiop->isCorruptSound(sound_id)) return; // @@ -4952,7 +4952,7 @@ void process_attached_sound(LLMessageSystem *msg, void **user_data) msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_OwnerID, owner_id); // Protect against corrupted sounds - if (gAudiop->isCorruptSound(sound_id)) + if (gAudiop && gAudiop->isCorruptSound(sound_id)) return; // diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp index e5f5db3a3c..acda5a5a44 100644 --- a/indra/newview/llvoicewebrtc.cpp +++ b/indra/newview/llvoicewebrtc.cpp @@ -281,6 +281,7 @@ void LLWebRTCVoiceClient::initWebRTC() llwebrtc::init(this); mWebRTCDeviceInterface = llwebrtc::getDeviceInterface(); + mWebRTCDeviceInterface->unsetDevicesObserver(this); // initWebRTC() can get multiple times - make sure to unset previous observers before re-adding mWebRTCDeviceInterface->setDevicesObserver(this); mMainQueue = LL::WorkQueue::getInstance("mainloop"); refreshDeviceLists(); diff --git a/indra/newview/skins/default/xui/de/panel_preferences_chat.xml b/indra/newview/skins/default/xui/de/panel_preferences_chat.xml index b2031ed5eb..557cc8db5d 100644 --- a/indra/newview/skins/default/xui/de/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/de/panel_preferences_chat.xml @@ -148,7 +148,8 @@ - + + diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml index 27137d2c16..2e88b99ba4 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml @@ -916,6 +916,14 @@ top_pad="1" height="16" width="400" /> + - [https://accounts.secondlife.com/billing_information/ 支払い情報]|[https://www.secondlife.com/my/lindex/buy.php L$の購入] + [https://accounts.secondlife.com/billing_information/?lang=ja-JP 支払い情報]|[https://www.secondlife.com/my/lindex/buy.php?lang=ja-JP L$の購入] 金額を再入力して、最新の為替レートを確認してください。 diff --git a/indra/newview/skins/default/xui/ja/menu_conversation.xml b/indra/newview/skins/default/xui/ja/menu_conversation.xml index b26fef3e1d..89334964e0 100755 --- a/indra/newview/skins/default/xui/ja/menu_conversation.xml +++ b/indra/newview/skins/default/xui/ja/menu_conversation.xml @@ -17,7 +17,7 @@ - + diff --git a/indra/newview/skins/default/xui/ja/menu_conversation_log_gear.xml b/indra/newview/skins/default/xui/ja/menu_conversation_log_gear.xml index 3600af0f4a..839c722c15 100755 --- a/indra/newview/skins/default/xui/ja/menu_conversation_log_gear.xml +++ b/indra/newview/skins/default/xui/ja/menu_conversation_log_gear.xml @@ -12,6 +12,6 @@ - + diff --git a/indra/newview/skins/default/xui/ja/menu_im_conversation.xml b/indra/newview/skins/default/xui/ja/menu_im_conversation.xml index e6aff37ab1..61eeee49f6 100755 --- a/indra/newview/skins/default/xui/ja/menu_im_conversation.xml +++ b/indra/newview/skins/default/xui/ja/menu_im_conversation.xml @@ -9,7 +9,7 @@ - + diff --git a/indra/newview/skins/default/xui/ja/menu_profile_other.xml b/indra/newview/skins/default/xui/ja/menu_profile_other.xml index 30f8bae3ae..0d17d4cad7 100644 --- a/indra/newview/skins/default/xui/ja/menu_profile_other.xml +++ b/indra/newview/skins/default/xui/ja/menu_profile_other.xml @@ -11,7 +11,7 @@ - + diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml b/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml index 2a97b25e66..5d5209c0fc 100644 --- a/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml @@ -147,7 +147,8 @@ - + + diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_firestorm.xml b/indra/newview/skins/default/xui/ja/panel_preferences_firestorm.xml index 45748b2e4d..ce687a10f8 100644 --- a/indra/newview/skins/default/xui/ja/panel_preferences_firestorm.xml +++ b/indra/newview/skins/default/xui/ja/panel_preferences_firestorm.xml @@ -82,7 +82,7 @@