From 9ed050e0e0f2687bb0a78cc1eaaf706ffb9db587 Mon Sep 17 00:00:00 2001 From: Mnikolenko ProductEngine Date: Thu, 10 Mar 2016 14:31:16 +0200 Subject: [PATCH 01/62] MAINT-3171 WIP Alt-clicking while moving mouse can move the camera significantly --- indra/llwindow/llopenglview-objc.mm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index 406bc9cf47..f3b8dac844 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -341,6 +341,9 @@ attributedStringInfo getSegments(NSAttributedString *str) callRightMouseUp(mMousePos, [theEvent modifierFlags]); mSimulatedRightClick = false; } else { + NSPoint mPoint = [theEvent locationInWindow]; + mMousePos[0] = mPoint.x; + mMousePos[1] = mPoint.y; callLeftMouseUp(mMousePos, [theEvent modifierFlags]); } } From 5304945e03d6297a9fe78e7038f7154dcbbb87f1 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Wed, 9 Mar 2016 18:33:30 +0200 Subject: [PATCH 02/62] MAINT-2969 FIXED decompressDCTPatch crashes all viewers in certain regions --- indra/newview/llsurface.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp index 503dd6747d..cb356726e6 100755 --- a/indra/newview/llsurface.cpp +++ b/indra/newview/llsurface.cpp @@ -718,7 +718,6 @@ void LLSurface::decompressDCTPatch(LLBitPack &bitpack, LLGroupHeader *gopp, BOOL << " quant_wbits " << (S32)ph.quant_wbits << " patchids " << (S32)ph.patchids << LL_ENDL; - LLAppViewer::instance()->badNetworkHandler(); return; } From debc51af6b6a35f7f635be9483a3bc4d0846a90d Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Fri, 26 Feb 2016 20:18:50 +0200 Subject: [PATCH 03/62] MAINT-1539 'L$' indicator doesn't disappear when object is not for sale --- indra/newview/llpanelpermissions.cpp | 44 +++++++++++++++------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index 263c73dc0e..0088163fee 100755 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -1080,28 +1080,30 @@ void LLPanelPermissions::setAllSaleInfo() LLSaleInfo new_sale_info(sale_type, price); LLSelectMgr::getInstance()->selectionSetObjectSaleInfo(new_sale_info); - - U8 old_click_action = 0; - LLSelectMgr::getInstance()->selectionGetClickAction(&old_click_action); - if (old_sale_info.isForSale() - && !new_sale_info.isForSale() - && old_click_action == CLICK_ACTION_BUY) - { - // If turned off for-sale, make sure click-action buy is turned - // off as well - LLSelectMgr::getInstance()-> - selectionSetClickAction(CLICK_ACTION_TOUCH); - } - else if (new_sale_info.isForSale() - && !old_sale_info.isForSale() - && old_click_action == CLICK_ACTION_TOUCH) - { - // If just turning on for-sale, preemptively turn on one-click buy - // unless user have a different click action set - LLSelectMgr::getInstance()-> - selectionSetClickAction(CLICK_ACTION_BUY); - } + bool selection_set_for_sale = new_sale_info.isForSale(); + bool selection_was_for_sale = old_sale_info.isForSale(); + if (selection_was_for_sale != selection_set_for_sale) + { + // sale state changed, switch click-actions + // but don't touch user changed actions + U8 old_action = selection_set_for_sale ? CLICK_ACTION_TOUCH : CLICK_ACTION_BUY; + U8 new_action = selection_set_for_sale ? CLICK_ACTION_BUY : CLICK_ACTION_TOUCH; + struct f : public LLSelectedObjectFunctor + { + U8 mActionOld, mActionNew; + f(const U8& t_old, const U8& t_new) : mActionOld(t_old), mActionNew(t_new) {} + virtual bool apply(LLViewerObject* object) + { + if (object->getClickAction() == mActionOld) + { + object->setClickAction(mActionNew); + } + return true; + } + } func(old_action, new_action); + LLSelectMgr::getInstance()->getSelection()->applyToObjects(&func); + } } struct LLSelectionPayable : public LLSelectedObjectFunctor From 173886fec32f2f5a8b63e81997f5929b02ddc8c9 Mon Sep 17 00:00:00 2001 From: ruslantproductengine Date: Thu, 10 Mar 2016 19:50:12 +0200 Subject: [PATCH 04/62] MAINT-1109 FIXED Toggling graphics options causes viewer memory to increase, eventually causing the rendering pipeline to fall over and crashing the viewer Patchset #2 --- indra/llrender/llglslshader.cpp | 9 ++------- indra/newview/llviewerwindow.cpp | 7 +++++++ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 52b8de8365..750e35a71a 100755 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -345,15 +345,10 @@ void LLGLSLShader::unloadInternal() GLhandleARB obj[1024]; GLsizei count; - glGetAttachedObjectsARB(mProgramObject, 1024, &count, obj); + glGetAttachedObjectsARB(mProgramObject, sizeof(obj)/sizeof(obj[0]), &count, obj); for (GLsizei i = 0; i < count; i++) { -#if !LL_DARWIN - if (glIsProgramARB(obj[i])) -#endif - { - glDeleteObjectARB(obj[i]); - } + glDeleteObjectARB(obj[i]); } glDeleteObjectARB(mProgramObject); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index f96c4b7bf0..d3416ec5fc 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -4951,6 +4951,13 @@ void LLViewerWindow::stopGL(BOOL save_state) gGLManager.mIsDisabled = TRUE; stop_glerror(); + + //unload shader's + while (LLGLSLShader::sInstances.size()) + { + LLGLSLShader* shader = *(LLGLSLShader::sInstances.begin()); + shader->unload(); + } LL_INFOS() << "Remaining allocated texture memory: " << LLImageGL::sGlobalTextureMemory.value() << " bytes" << LL_ENDL; } From 230fc28d8a72e75a8f2af2ab5fa5ee0e3ccca4a1 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Fri, 11 Mar 2016 20:16:03 +0200 Subject: [PATCH 05/62] MAINT-6097 FIXED On required update, clicking link to release notes opens browser behind menu --- indra/llui/llnotifications.cpp | 6 ++++ indra/llui/llnotifications.h | 3 +- indra/llui/llnotificationtemplate.h | 17 +++++++---- indra/llui/lltextbase.cpp | 14 ++++++++-- indra/llui/lltextbase.h | 2 ++ indra/llui/llurlaction.cpp | 5 ++-- indra/llui/llurlaction.h | 2 +- indra/newview/lltoastalertpanel.cpp | 1 + .../skins/default/xui/en/notifications.xml | 28 +++++++++++-------- 9 files changed, 55 insertions(+), 23 deletions(-) diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 77e7d375c8..0cb959a315 100755 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -417,6 +417,7 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par mExpireOption(p.expire_option), mURLOption(p.url.option), mURLTarget(p.url.target), + mForceUrlsExternal(p.force_urls_external), mUnique(p.unique.isProvided()), mCombineBehavior(p.unique.combine), mPriority(p.priority), @@ -748,6 +749,11 @@ S32 LLNotification::getURLOpenExternally() const return(mTemplatep? mTemplatep->mURLTarget == "_external": -1); } +bool LLNotification::getForceUrlsExternal() const +{ + return (mTemplatep ? mTemplatep->mForceUrlsExternal : false); +} + bool LLNotification::hasUniquenessConstraints() const { return (mTemplatep ? mTemplatep->mUnique : false); diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 010e6caba2..354add0b82 100755 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -553,7 +553,8 @@ public: std::string getLabel() const; std::string getURL() const; S32 getURLOption() const; - S32 getURLOpenExternally() const; + S32 getURLOpenExternally() const; //for url responce option + bool getForceUrlsExternal() const; bool canLogToChat() const; bool canLogToIM() const; bool canShowToast() const; diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h index c23fc53763..bed29254d8 100755 --- a/indra/llui/llnotificationtemplate.h +++ b/indra/llui/llnotificationtemplate.h @@ -177,7 +177,8 @@ struct LLNotificationTemplate Optional persist, log_to_im, show_toast, - log_to_chat; + log_to_chat, + force_urls_external; Optional functor, icon, label, @@ -201,6 +202,7 @@ struct LLNotificationTemplate log_to_im("log_to_im", false), show_toast("show_toast", true), log_to_chat("log_to_chat", true), + force_urls_external("force_urls_external", false), functor("functor"), icon("icon"), label("label"), @@ -284,11 +286,16 @@ struct LLNotificationTemplate // that URL. Obsolete this and eliminate the buttons for affected // messages when we allow clickable URLs in the UI U32 mURLOption; - - std::string mURLTarget; - //This is a flag that tells if the url needs to open externally dispite + + //This is a flag that tells if option url needs to open externally dispite //what the user setting is. - + std::string mURLTarget; + + // All links clicked inside notification will be opened in external browser + // Note: Some notifications block and exit viewer, yet they provide a link + // to click, we should be able to open such links in external browser. + bool mForceUrlsExternal; + // does this notification persist across sessions? if so, it will be // serialized to disk on first receipt and read on startup bool mPersist; diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 4309e6557e..4ccf1ef009 100755 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -164,6 +164,7 @@ LLTextBase::Params::Params() trusted_content("trusted_content", true), use_ellipses("use_ellipses", false), parse_urls("parse_urls", false), + force_urls_external("force_urls_external", false), parse_highlights("parse_highlights", false) { addSynonym(track_end, "track_bottom"); @@ -216,6 +217,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p) mWordWrap(p.wrap), mUseEllipses( p.use_ellipses ), mParseHTML(p.parse_urls), + mForceUrlsExternal(p.force_urls_external), mParseHighlights(p.parse_highlights), mBGVisible(p.bg_visible), mScroller(NULL), @@ -1937,7 +1939,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url) registrar.add("Url.Open", boost::bind(&LLUrlAction::openURL, url)); registrar.add("Url.OpenInternal", boost::bind(&LLUrlAction::openURLInternal, url)); registrar.add("Url.OpenExternal", boost::bind(&LLUrlAction::openURLExternal, url)); - registrar.add("Url.Execute", boost::bind(&LLUrlAction::executeSLURL, url)); + registrar.add("Url.Execute", boost::bind(&LLUrlAction::executeSLURL, url, true)); registrar.add("Url.Block", boost::bind(&LLUrlAction::blockObject, url)); registrar.add("Url.Teleport", boost::bind(&LLUrlAction::teleportToLocation, url)); registrar.add("Url.ShowProfile", boost::bind(&LLUrlAction::showProfile, url)); @@ -3227,7 +3229,15 @@ BOOL LLNormalTextSegment::handleMouseUp(S32 x, S32 y, MASK mask) // Only process the click if it's actually in this segment, not to the right of the end-of-line. if(mEditor.getSegmentAtLocalPos(x, y, false) == this) { - LLUrlAction::clickAction(getStyle()->getLinkHREF(), mEditor.isContentTrusted()); + std::string url = getStyle()->getLinkHREF(); + if (!mEditor.mForceUrlsExternal) + { + LLUrlAction::clickAction(url, mEditor.isContentTrusted()); + } + else if (!LLUrlAction::executeSLURL(url, mEditor.isContentTrusted())) + { + LLUrlAction::openURLExternal(url); + } return TRUE; } } diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index ac408bbe7a..7d87271b0e 100755 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -300,6 +300,7 @@ public: wrap, use_ellipses, parse_urls, + force_urls_external, parse_highlights, clip, clip_partial, @@ -654,6 +655,7 @@ protected: S32 mLineSpacingPixels; // padding between lines bool mBorderVisible; bool mParseHTML; // make URLs interactive + bool mForceUrlsExternal; // URLs from this textbox will be opened in external browser bool mParseHighlights; // highlight user-defined keywords bool mWordWrap; bool mUseEllipses; diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp index 12537d9dd1..027a3e3a64 100755 --- a/indra/llui/llurlaction.cpp +++ b/indra/llui/llurlaction.cpp @@ -83,12 +83,13 @@ void LLUrlAction::openURLExternal(std::string url) } } -void LLUrlAction::executeSLURL(std::string url) +bool LLUrlAction::executeSLURL(std::string url, bool trusted_content) { if (sExecuteSLURLCallback) { - sExecuteSLURLCallback(url ,true); + return sExecuteSLURLCallback(url, trusted_content); } + return false; } void LLUrlAction::clickAction(std::string url, bool trusted_content) diff --git a/indra/llui/llurlaction.h b/indra/llui/llurlaction.h index 5f3626490c..5497e28bb4 100755 --- a/indra/llui/llurlaction.h +++ b/indra/llui/llurlaction.h @@ -57,7 +57,7 @@ public: static void openURLExternal(std::string url); /// execute the given secondlife: SLURL - static void executeSLURL(std::string url); + static bool executeSLURL(std::string url, bool trusted_content = true); /// if the Url specifies an SL location, teleport there static void teleportToLocation(std::string url); diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp index 530bd9a18f..bbce717c20 100755 --- a/indra/newview/lltoastalertpanel.cpp +++ b/indra/newview/lltoastalertpanel.cpp @@ -181,6 +181,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal params.wrap(true); params.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP); params.allow_scroll(true); + params.force_urls_external(mNotification->getForceUrlsExternal()); LLTextBox * msg_box = LLUICtrlFactory::create (params); // Compute max allowable height for the dialog text, so we can allocate diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index f1a6aca163..3831b52c2c 100755 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -3870,9 +3870,10 @@ We have downloaded an update to your [APP_NAME] installation. + icon="alertmodal.tga" + name="RequiredUpdateDownloadedVerboseDialog" + type="alertmodal" + force_urls_external="true"> We have downloaded a required software update. Version [VERSION] [[INFO_URL] Information about this update] @@ -3884,9 +3885,10 @@ We must restart [APP_NAME] to install the update. + icon="alertmodal.tga" + name="RequiredUpdateDownloadedDialog" + type="alertmodal" + force_urls_external="true"> We must restart [APP_NAME] to install the update. [[INFO_URL] Information about this update] confirm @@ -3926,9 +3928,10 @@ see [[INFO_URL] Information about this update] + icon="alertmodal.tga" + name="OtherChannelRequiredUpdateDownloadedVerboseDialog" + type="alertmodal" + force_urls_external="true"> We have downloaded a required software update. Version [VERSION] This experimental viewer has been replaced by a [NEW_CHANNEL] viewer; @@ -3942,9 +3945,10 @@ We must restart [APP_NAME] to install the update. + icon="alertmodal.tga" + name="OtherChannelRequiredUpdateDownloadedDialog" + type="alertmodal" + force_urls_external="true"> We must restart [APP_NAME] to install the update. This experimental viewer has been replaced by a [NEW_CHANNEL] viewer; see [[INFO_URL] Information about this update] From 2fe6b4143cb693c3675bc640046b52b4a21da18d Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Wed, 16 Mar 2016 17:56:14 +0200 Subject: [PATCH 06/62] MAINT-5938 FIXED when Marketplace is down viewer errors 499 at each login and teleport --- indra/newview/llmarketplacefunctions.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index d5bfe1df4a..0572ac4c8c 100755 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -174,8 +174,17 @@ protected: log_SLM_infos("Get /merchant", getStatus(), "Merchant is not migrated"); LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MIGRATED_MERCHANT); } - else - { + else if (HTTP_INTERNAL_ERROR == getStatus()) + { + // 499 includes timeout and ssl error - marketplace is down or having issues, we do not show it in this request according to MAINT-5938 + LL_WARNS("SLM") << "SLM Merchant Request failed with status: " << getStatus() + << ", reason : " << getReason() + << ", code : " << getContent().get("error_code") + << ", description : " << getContent().get("error_description") << LL_ENDL; + LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE); + } + else + { log_SLM_warning("Get /merchant", getStatus(), getReason(), getContent().get("error_code"), getContent().get("error_description")); LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE); } From 6adce024a533566bd0d48fb1f8ad49260809fb12 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Wed, 16 Mar 2016 17:56:14 +0200 Subject: [PATCH 07/62] MAINT-5938 FIXED when Marketplace is down viewer errors 499 at each login and teleport --- indra/newview/llmarketplacefunctions.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index dfa33b37ef..6cc7a0fc99 100755 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -795,6 +795,15 @@ void LLMarketplaceData::getMerchantStatusCoro() log_SLM_infos("Get /merchant", httpCode, std::string("Merchant is not migrated")); setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MIGRATED_MERCHANT); } + else if (httpCode == HTTP_INTERNAL_ERROR) + { + // 499 includes timeout and ssl error - marketplace is down or having issues, we do not show it in this request according to MAINT-5938 + LL_WARNS("SLM") << "SLM Merchant Request failed with status: " << httpCode + << ", reason : " << status.toString() + << ", code : " << result["error_code"].asString() + << ", description : " << result["error_description"].asString() << LL_ENDL; + LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE); + } else { std::string err_code = result["error_code"].asString(); From ef73114ede629198258ee4830d0df8f96e5eb477 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Thu, 17 Mar 2016 15:55:27 +0200 Subject: [PATCH 08/62] MAINT-6227 FIXED Crash on mesh upload --- indra/newview/llfloatermodelpreview.cpp | 16 ++++++++++++---- indra/newview/llfloatermodelpreview.h | 1 + 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 57d69589d3..d94c91c16d 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -338,25 +338,25 @@ BOOL LLFloaterModelPreview::postBuild() LLTextBox* text = getChild(lod_label_name[i]); if (text) { - text->setMouseDownCallback(boost::bind(&LLModelPreview::setPreviewLOD, mModelPreview, i)); + text->setMouseDownCallback(boost::bind(&LLFloaterModelPreview::setPreviewLOD, this, i)); } text = getChild(lod_triangles_name[i]); if (text) { - text->setMouseDownCallback(boost::bind(&LLModelPreview::setPreviewLOD, mModelPreview, i)); + text->setMouseDownCallback(boost::bind(&LLFloaterModelPreview::setPreviewLOD, this, i)); } text = getChild(lod_vertices_name[i]); if (text) { - text->setMouseDownCallback(boost::bind(&LLModelPreview::setPreviewLOD, mModelPreview, i)); + text->setMouseDownCallback(boost::bind(&LLFloaterModelPreview::setPreviewLOD, this, i)); } text = getChild(lod_status_name[i]); if (text) { - text->setMouseDownCallback(boost::bind(&LLModelPreview::setPreviewLOD, mModelPreview, i)); + text->setMouseDownCallback(boost::bind(&LLFloaterModelPreview::setPreviewLOD, this, i)); } } std::string current_grid = LLGridManager::getInstance()->getGridId(); @@ -1363,6 +1363,14 @@ void LLFloaterModelPreview::setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, childSetTextArg("import_dimensions", "[Z]", llformat("%.3f", z)); } +void LLFloaterModelPreview::setPreviewLOD(S32 lod) +{ + if (mModelPreview) + { + mModelPreview->setPreviewLOD(lod); + } +} + void LLModelPreview::rebuildUploadData() { diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index b2bb15ef05..a73ca50260 100755 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -95,6 +95,7 @@ public: static void setUploadAmount(S32 amount) { sUploadAmount = amount; } void setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost); + void setPreviewLOD(S32 lod); void onBrowseLOD(S32 lod); From 08a3c121cafc3aa1955cd3f614f1805ade28ce35 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Thu, 17 Mar 2016 23:41:57 +0100 Subject: [PATCH 09/62] Build fix --- indra/llui/llscrolllistctrl.cpp | 16 ++++++++-------- indra/llui/lltextbase.cpp | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 65fb7ab086..00366097d5 100755 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -2016,14 +2016,14 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask) // Additional convenience options registrar.add("Url.RemoveFriend", boost::bind(&LLScrollListCtrl::removeFriend, id)); - registrar.add("FS.ZoomIn", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + id + "/zoom")); - registrar.add("FS.TeleportToTarget", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + id + "/teleportto")); - registrar.add("FS.OfferTeleport", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + id + "/offerteleport")); - registrar.add("FS.RequestTeleport", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + id + "/requestteleport")); - registrar.add("FS.TrackAvatar", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + id + "/track")); - registrar.add("FS.AddToContactSet", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + id + "/addtocontactset")); // [FS:CR] - registrar.add("FS.BlockAvatar", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + id + "/blockavatar")); - registrar.add("FS.ViewLog", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + id + "/viewlog")); + registrar.add("FS.ZoomIn", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + id + "/zoom", true)); + registrar.add("FS.TeleportToTarget", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + id + "/teleportto", true)); + registrar.add("FS.OfferTeleport", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + id + "/offerteleport", true)); + registrar.add("FS.RequestTeleport", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + id + "/requestteleport", true)); + registrar.add("FS.TrackAvatar", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + id + "/track", true)); + registrar.add("FS.AddToContactSet", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + id + "/addtocontactset", true)); // [FS:CR] + registrar.add("FS.BlockAvatar", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + id + "/blockavatar", true)); + registrar.add("FS.ViewLog", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + id + "/viewlog", true)); // Additional convenience options // Add enable checks for menu items diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index d3289b7f30..05831e3dbc 100755 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -2125,14 +2125,14 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url) // Additional convenience options std::string target_id_str = LLUrlAction::extractUuidFromSlurl(url).asString(); - registrar.add("FS.ZoomIn", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + target_id_str + "/zoom")); - registrar.add("FS.TeleportToTarget", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + target_id_str + "/teleportto")); - registrar.add("FS.OfferTeleport", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + target_id_str + "/offerteleport")); - registrar.add("FS.RequestTeleport", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + target_id_str + "/requestteleport")); - registrar.add("FS.TrackAvatar", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + target_id_str + "/track")); - registrar.add("FS.AddToContactSet", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + target_id_str + "/addtocontactset")); // [FS:CR] - registrar.add("FS.BlockAvatar", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + target_id_str + "/blockavatar")); - registrar.add("FS.ViewLog", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + target_id_str + "/viewlog")); + registrar.add("FS.ZoomIn", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + target_id_str + "/zoom", true)); + registrar.add("FS.TeleportToTarget", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + target_id_str + "/teleportto", true)); + registrar.add("FS.OfferTeleport", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + target_id_str + "/offerteleport", true)); + registrar.add("FS.RequestTeleport", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + target_id_str + "/requestteleport", true)); + registrar.add("FS.TrackAvatar", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + target_id_str + "/track", true)); + registrar.add("FS.AddToContactSet", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + target_id_str + "/addtocontactset", true)); // [FS:CR] + registrar.add("FS.BlockAvatar", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + target_id_str + "/blockavatar", true)); + registrar.add("FS.ViewLog", boost::bind(&LLUrlAction::executeSLURL, "secondlife:///app/firestorm/" + target_id_str + "/viewlog", true)); // // Add enable checks for menu items From ca1d7da5718a4ad40856fe404ce89690da984f15 Mon Sep 17 00:00:00 2001 From: Mnikolenko ProductEngine Date: Mon, 21 Mar 2016 17:58:39 +0200 Subject: [PATCH 10/62] MAINT-3171 Alt-clicking while moving mouse can move the camera significantly --- indra/llwindow/llopenglview-objc.mm | 2 +- indra/llwindow/llwindowcallbacks.cpp | 4 ++++ indra/llwindow/llwindowcallbacks.h | 1 + indra/llwindow/llwindowmacosx-objc.h | 1 + indra/llwindow/llwindowmacosx.cpp | 12 ++++++++++ indra/newview/llviewerwindow.cpp | 35 ++++++++++++++++++++++++++-- indra/newview/llviewerwindow.h | 3 +++ 7 files changed, 55 insertions(+), 3 deletions(-) diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index f3b8dac844..ca502e0659 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -391,7 +391,7 @@ attributedStringInfo getSegments(NSAttributedString *str) NSPoint mPoint = [theEvent locationInWindow]; mMousePos[0] = mPoint.x; mMousePos[1] = mPoint.y; - callMouseMoved(mMousePos, 0); + callMouseDragged(mMousePos, 0); } - (void) otherMouseDown:(NSEvent *)theEvent diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp index eadff8a6b4..d2afb3f91b 100755 --- a/indra/llwindow/llwindowcallbacks.cpp +++ b/indra/llwindow/llwindowcallbacks.cpp @@ -112,6 +112,10 @@ void LLWindowCallbacks::handleMouseMove(LLWindow *window, const LLCoordGL pos, M { } +void LLWindowCallbacks::handleMouseDragged(LLWindow *window, const LLCoordGL pos, MASK mask) +{ +} + void LLWindowCallbacks::handleScrollWheel(LLWindow *window, S32 clicks) { } diff --git a/indra/llwindow/llwindowcallbacks.h b/indra/llwindow/llwindowcallbacks.h index 7da5959700..6a7137e593 100755 --- a/indra/llwindow/llwindowcallbacks.h +++ b/indra/llwindow/llwindowcallbacks.h @@ -52,6 +52,7 @@ public: virtual BOOL handleActivate(LLWindow *window, BOOL activated); virtual BOOL handleActivateApp(LLWindow *window, BOOL activating); virtual void handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask); + virtual void handleMouseDragged(LLWindow *window, LLCoordGL pos, MASK mask); virtual void handleScrollWheel(LLWindow *window, S32 clicks); virtual void handleResize(LLWindow *window, S32 width, S32 height); virtual void handleFocus(LLWindow *window); diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h index dc184b91fb..ce74fc83cc 100755 --- a/indra/llwindow/llwindowmacosx-objc.h +++ b/indra/llwindow/llwindowmacosx-objc.h @@ -133,6 +133,7 @@ void callLeftMouseUp(float *pos, unsigned int mask); void callDoubleClick(float *pos, unsigned int mask); void callResize(unsigned int width, unsigned int height); void callMouseMoved(float *pos, unsigned int mask); +void callMouseDragged(float *pos, unsigned int mask); void callScrollMoved(float delta); void callMouseExit(); void callWindowFocus(); diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 0d41884462..8cbf5a31fb 100755 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -343,6 +343,18 @@ void callMouseMoved(float *pos, MASK mask) //gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, 0); } +void callMouseDragged(float *pos, MASK mask) +{ + LLCoordGL outCoords; + outCoords.mX = ll_round(pos[0]); + outCoords.mY = ll_round(pos[1]); + float deltas[2]; + gWindowImplementation->getMouseDeltas(deltas); + outCoords.mX += deltas[0]; + outCoords.mY += deltas[1]; + gWindowImplementation->getCallbacks()->handleMouseDragged(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE)); +} + void callScrollMoved(float delta) { gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, delta); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index d3416ec5fc..50329d8576 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1037,7 +1037,16 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask) { - BOOL down = TRUE; + mAllowMouseDragging = FALSE; + if (!mMouseDownTimer.getStarted()) + { + mMouseDownTimer.start(); + } + else + { + mMouseDownTimer.reset(); + } + BOOL down = TRUE; return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_LEFT,down); } @@ -1056,7 +1065,11 @@ BOOL LLViewerWindow::handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK ma BOOL LLViewerWindow::handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) { - BOOL down = FALSE; + if (mMouseDownTimer.getStarted()) + { + mMouseDownTimer.stop(); + } + BOOL down = FALSE; return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_LEFT,down); } @@ -1288,6 +1301,22 @@ void LLViewerWindow::handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask } } +void LLViewerWindow::handleMouseDragged(LLWindow *window, LLCoordGL pos, MASK mask) +{ + if (mMouseDownTimer.getStarted()) + { + if (mMouseDownTimer.getElapsedTimeF32() > 0.1) + { + mAllowMouseDragging = TRUE; + mMouseDownTimer.stop(); + } + } + if(mAllowMouseDragging || !LLToolCamera::getInstance()->hasMouseCapture()) + { + handleMouseMove(window, pos, mask); + } +} + void LLViewerWindow::handleMouseLeave(LLWindow *window) { // Note: we won't get this if we have captured the mouse. @@ -1617,6 +1646,8 @@ LLViewerWindow::LLViewerWindow(const Params& p) mMiddleMouseDown(FALSE), mRightMouseDown(FALSE), mMouseInWindow( FALSE ), + mAllowMouseDragging(TRUE), + mMouseDownTimer(), mLastMask( MASK_NONE ), mToolStored( NULL ), mHideCursorPermanent( FALSE ), diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index d34e76f6f6..ad06f00234 100755 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -193,6 +193,7 @@ public: /*virtual*/ BOOL handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask); /*virtual*/ LLWindowCallbacks::DragNDropResult handleDragNDrop(LLWindow *window, LLCoordGL pos, MASK mask, LLWindowCallbacks::DragNDropAction action, std::string data); void handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask); + void handleMouseDragged(LLWindow *window, LLCoordGL pos, MASK mask); /*virtual*/ void handleMouseLeave(LLWindow *window); /*virtual*/ void handleResize(LLWindow *window, S32 x, S32 y); /*virtual*/ void handleFocus(LLWindow *window); @@ -463,6 +464,8 @@ private: BOOL mMouseInWindow; // True if the mouse is over our window or if we have captured the mouse. BOOL mFocusCycleMode; + BOOL mAllowMouseDragging; + LLFrameTimer mMouseDownTimer; typedef std::set > view_handle_set_t; view_handle_set_t mMouseHoverViews; From 9412e79698c004ead460d4295933fd039ddb796e Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Mon, 21 Mar 2016 18:51:26 +0200 Subject: [PATCH 11/62] MAINT-6130 FIXED Resizing "Picks" floater breaks formatting in list items --- indra/newview/llexpandabletextbox.cpp | 22 +++++++++++++++------- indra/newview/llexpandabletextbox.h | 1 + 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/indra/newview/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp index 4dbed114bb..f0331f20d8 100755 --- a/indra/newview/llexpandabletextbox.cpp +++ b/indra/newview/llexpandabletextbox.cpp @@ -122,8 +122,6 @@ LLExpandableTextBox::LLTextBoxEx::LLTextBoxEx(const Params& p) void LLExpandableTextBox::LLTextBoxEx::reshape(S32 width, S32 height, BOOL called_from_parent) { LLTextEditor::reshape(width, height, called_from_parent); - - hideOrShowExpandTextAsNeeded(); } void LLExpandableTextBox::LLTextBoxEx::setText(const LLStringExplicit& text,const LLStyle::Params& input_params) @@ -298,6 +296,12 @@ void LLExpandableTextBox::updateTextBoxRect() mTextBox->reshape(rc.getWidth(), rc.getHeight()); mTextBox->setRect(rc); + // *HACK + // hideExpandText brakes text styles (replaces hyper-links with plain text), see ticket EXT-3290 + // Also text segments are not removed properly. Same issue at expandTextBox(). + // So set text again to make text box re-apply styles and clear segments. + // *TODO Find a solution that does not involve text segment. + mTextBox->setText(mText); } S32 LLExpandableTextBox::recalculateTextDelta(S32 text_delta) @@ -403,8 +407,6 @@ void LLExpandableTextBox::collapseTextBox() setRect(mCollapsedRect); updateTextBoxRect(); - - gViewerWindow->removePopup(this); } void LLExpandableTextBox::onFocusLost() @@ -423,13 +425,19 @@ void LLExpandableTextBox::onTopLost() void LLExpandableTextBox::updateTextShape() { - // I guess this should be done on every reshape(), - // but adding this code to reshape() currently triggers bug VWR-26455, - // which makes the text virtually unreadable. llassert(!mExpanded); updateTextBoxRect(); } +void LLExpandableTextBox::reshape(S32 width, S32 height, BOOL called_from_parent) +{ + mExpanded = false; + LLUICtrl::reshape(width, height, called_from_parent); + updateTextBoxRect(); + + gViewerWindow->removePopup(this); +} + void LLExpandableTextBox::setValue(const LLSD& value) { collapseTextBox(); diff --git a/indra/newview/llexpandabletextbox.h b/indra/newview/llexpandabletextbox.h index 90d46ab262..aaf393277f 100755 --- a/indra/newview/llexpandabletextbox.h +++ b/indra/newview/llexpandabletextbox.h @@ -147,6 +147,7 @@ public: * *HACK: Update the inner textbox shape. */ void updateTextShape(); + virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); /** * Draws text box, collapses text box if its expanded and its parent's position changed From 0e845dc845817dbf71a9a4f1d8072576f973c457 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Thu, 24 Mar 2016 17:09:39 +0200 Subject: [PATCH 12/62] MAINT-6214 Unable to add a space before closing curly brace in chatbar, notecards & scripts. --- indra/llui/lltexteditor.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 926326aaff..3c86b539c4 100755 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -1716,7 +1716,20 @@ void LLTextEditor::unindentLineBeforeCloseBrace() LLWString text = getWText(); if( ' ' == text[ mCursorPos - 1 ] ) { - removeCharOrTab(); + S32 line = getLineNumFromDocIndex(mCursorPos, false); + S32 line_start = getLineStart(line); + + // Jump over spaces in the current line + while ((' ' == text[line_start]) && (line_start < mCursorPos)) + { + line_start++; + } + + // Make sure there is nothing but ' ' before the Brace we are unindenting + if (line_start == mCursorPos) + { + removeCharOrTab(); + } } } } @@ -1800,7 +1813,7 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char) // Handle most keys only if the text editor is writeable. if( !mReadOnly ) { - if( '}' == uni_char ) + if( mAutoIndent && '}' == uni_char ) { unindentLineBeforeCloseBrace(); } From 107b6687184814e8fdf8946c897355655eb0ce84 Mon Sep 17 00:00:00 2001 From: Mnikolenko ProductEngine Date: Fri, 25 Mar 2016 16:25:53 +0200 Subject: [PATCH 13/62] MAINT-6224 Notifications Update "When I spend or get L$" split into two options. --- indra/newview/app_settings/settings.xml | 22 +++++++++++++++++++ indra/newview/llviewermessage.cpp | 8 +++++++ .../xui/en/panel_preferences_alerts.xml | 22 +++++++++++++------ 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 0ac2dcc86c..aef2438dc7 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -6993,6 +6993,28 @@ Value 1 + NotifyMoneySpend + + Comment + Pop up notifications when spending L$ + Persist + 1 + Type + Boolean + Value + 1 + + NotifyMoneyReceived + + Comment + Pop up notifications when receiving L$ + Persist + 1 + Type + Boolean + Value + 1 + NotifyTipDuration Comment diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 05e00ea987..810cf60f81 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -5637,6 +5637,10 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg) bool you_paid_someone = (source_id == gAgentID); if (you_paid_someone) { + if(!gSavedSettings.getBOOL("NotifyMoneySpend")) + { + return; + } args["NAME"] = dest_slurl; is_name_group = is_dest_group; name_id = dest_id; @@ -5674,6 +5678,10 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg) } else { // ...someone paid you + if(!gSavedSettings.getBOOL("NotifyMoneyReceived")) + { + return; + } args["NAME"] = source_slurl; is_name_group = is_source_group; name_id = source_id; diff --git a/indra/newview/skins/default/xui/en/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/en/panel_preferences_alerts.xml index 714dca7fac..93c97ded25 100755 --- a/indra/newview/skins/default/xui/en/panel_preferences_alerts.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_alerts.xml @@ -21,12 +21,12 @@ Tell me: + left_delta="150" + name="friends_online_notify_checkbox" + width="300" /> + Date: Fri, 25 Mar 2016 17:24:06 +0200 Subject: [PATCH 14/62] MAINT-6257 Particle textures loading issues. --- indra/newview/llviewertexturelist.cpp | 6 +++++- indra/newview/llvoavatar.cpp | 9 +++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index e580ecaba1..00338cb884 100755 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -183,7 +183,11 @@ void LLViewerTextureList::doPreloadImages() image->setAddressMode(LLTexUnit::TAM_WRAP); mImagePreloads.insert(image); } - + image = LLViewerTextureManager::getFetchedTextureFromFile("cloud-particle.j2c", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_CLOUDS); + if (image) + { + mImagePreloads.insert(image); + } } static std::string get_texture_list_name() diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index a26b5e0a98..cb2d3de873 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2526,8 +2526,13 @@ void LLVOAvatar::idleUpdateLoadingEffect() particle_parameters.mPartData.mStartColor = LLColor4(1, 1, 1, 0.5f); particle_parameters.mPartData.mEndColor = LLColor4(1, 1, 1, 0.0f); particle_parameters.mPartData.mStartScale.mV[VX] = 0.8f; - LLViewerTexture* cloud = LLViewerTextureManager::getFetchedTextureFromFile("cloud-particle.j2c"); - particle_parameters.mPartImageID = cloud->getID(); + static LLUUID cloud_id = LLUUID::null; + if (cloud_id == LLUUID::null) + { + LLViewerTexture* cloud = LLViewerTextureManager::getFetchedTextureFromFile("cloud-particle.j2c"); + cloud_id = cloud->getID(); + } + particle_parameters.mPartImageID = cloud_id; particle_parameters.mMaxAge = 0.f; particle_parameters.mPattern = LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE; particle_parameters.mInnerAngle = F_PI; From 272d40a0892108de5e54f8b440f95e4c270686a7 Mon Sep 17 00:00:00 2001 From: Mnikolenko ProductEngine Date: Tue, 29 Mar 2016 13:30:00 +0300 Subject: [PATCH 15/62] MAINT-6239 [Mac] Computer cursor appears attached to crosshair after using modifier keys in mouselook --- indra/llwindow/llwindowmacosx-objc.h | 1 + indra/llwindow/llwindowmacosx-objc.mm | 5 +++++ indra/llwindow/llwindowmacosx.cpp | 12 ++++++++++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h index ce74fc83cc..507d1239be 100755 --- a/indra/llwindow/llwindowmacosx-objc.h +++ b/indra/llwindow/llwindowmacosx-objc.h @@ -92,6 +92,7 @@ void setCrossCursor(); void setNotAllowedCursor(); void hideNSCursor(); void showNSCursor(); +bool isCGCursorVisible(); void hideNSCursorTillMove(bool hide); void requestUserAttention(); long showAlert(std::string title, std::string text, int type); diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm index 1a21bf8430..43ce9a2255 100755 --- a/indra/llwindow/llwindowmacosx-objc.mm +++ b/indra/llwindow/llwindowmacosx-objc.mm @@ -163,6 +163,11 @@ void showNSCursor() [NSCursor unhide]; } +bool isCGCursorVisible() +{ + return CGCursorIsVisible(); +} + void hideNSCursorTillMove(bool hide) { [NSCursor setHiddenUntilMouseMoves:hide]; diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 8cbf5a31fb..c6bf93507a 100755 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -1457,8 +1457,16 @@ void LLWindowMacOSX::updateCursor() mNextCursor = UI_CURSOR_WORKING; } - if(mCurrentCursor == mNextCursor) - return; + if(mCurrentCursor == mNextCursor) + { + if(mCursorHidden && isCGCursorVisible()) + { + hideNSCursor(); + mHideCursorPermanent = TRUE; + adjustCursorDecouple(); + } + return; + } // RN: replace multi-drag cursors with single versions if (mNextCursor == UI_CURSOR_ARROWDRAGMULTI) From 783cc9756ad6cc07d27bf985171c922aa20b0fc8 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Tue, 29 Mar 2016 15:17:15 +0300 Subject: [PATCH 16/62] Backed out changeset: ca5d40144cc2 --- indra/newview/llviewertexturelist.cpp | 6 +----- indra/newview/llvoavatar.cpp | 9 ++------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 00338cb884..e580ecaba1 100755 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -183,11 +183,7 @@ void LLViewerTextureList::doPreloadImages() image->setAddressMode(LLTexUnit::TAM_WRAP); mImagePreloads.insert(image); } - image = LLViewerTextureManager::getFetchedTextureFromFile("cloud-particle.j2c", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_CLOUDS); - if (image) - { - mImagePreloads.insert(image); - } + } static std::string get_texture_list_name() diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index cb2d3de873..a26b5e0a98 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2526,13 +2526,8 @@ void LLVOAvatar::idleUpdateLoadingEffect() particle_parameters.mPartData.mStartColor = LLColor4(1, 1, 1, 0.5f); particle_parameters.mPartData.mEndColor = LLColor4(1, 1, 1, 0.0f); particle_parameters.mPartData.mStartScale.mV[VX] = 0.8f; - static LLUUID cloud_id = LLUUID::null; - if (cloud_id == LLUUID::null) - { - LLViewerTexture* cloud = LLViewerTextureManager::getFetchedTextureFromFile("cloud-particle.j2c"); - cloud_id = cloud->getID(); - } - particle_parameters.mPartImageID = cloud_id; + LLViewerTexture* cloud = LLViewerTextureManager::getFetchedTextureFromFile("cloud-particle.j2c"); + particle_parameters.mPartImageID = cloud->getID(); particle_parameters.mMaxAge = 0.f; particle_parameters.mPattern = LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE; particle_parameters.mInnerAngle = F_PI; From 0e155c51a95f092dda4f1ee71b4de46c7e98c10d Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Tue, 29 Mar 2016 18:52:54 +0300 Subject: [PATCH 17/62] MAINT-6257 Textures loading issues. --- indra/llui/lliconctrl.cpp | 11 ++++++++--- indra/llui/lliconctrl.h | 2 ++ indra/newview/llavatariconctrl.cpp | 6 +++--- indra/newview/llgroupiconctrl.cpp | 12 +++++++++--- indra/newview/llgroupiconctrl.h | 2 ++ indra/newview/llgrouplist.cpp | 6 +++--- indra/newview/llgrouplist.h | 4 ++-- indra/newview/lllocalbitmaps.cpp | 10 +++++----- indra/newview/llpanelface.cpp | 2 +- indra/newview/lltexturectrl.cpp | 2 +- indra/newview/lltexturefetch.cpp | 2 +- indra/newview/lltoastgroupnotifypanel.cpp | 8 +++++--- indra/newview/llviewertexture.cpp | 14 +++++++------- indra/newview/llviewertexturelist.cpp | 16 +++++----------- indra/newview/llviewertexturelist.h | 4 ++-- indra/newview/llvoavatar.cpp | 8 ++++---- .../default/xui/en/panel_group_list_item.xml | 2 +- .../skins/default/xui/en/panel_group_notify.xml | 2 +- 18 files changed, 62 insertions(+), 51 deletions(-) diff --git a/indra/llui/lliconctrl.cpp b/indra/llui/lliconctrl.cpp index f841901801..82b01e705d 100755 --- a/indra/llui/lliconctrl.cpp +++ b/indra/llui/lliconctrl.cpp @@ -83,7 +83,12 @@ void LLIconCtrl::draw() // virtual // value might be a string or a UUID -void LLIconCtrl::setValue(const LLSD& value ) +void LLIconCtrl::setValue(const LLSD& value) +{ + setValue(value, mPriority); +} + +void LLIconCtrl::setValue(const LLSD& value, S32 priority) { LLSD tvalue(value); if (value.isString() && LLUUID::validate(value.asString())) @@ -94,11 +99,11 @@ void LLIconCtrl::setValue(const LLSD& value ) LLUICtrl::setValue(tvalue); if (tvalue.isUUID()) { - mImagep = LLUI::getUIImageByID(tvalue.asUUID(), mPriority); + mImagep = LLUI::getUIImageByID(tvalue.asUUID(), priority); } else { - mImagep = LLUI::getUIImage(tvalue.asString(), mPriority); + mImagep = LLUI::getUIImage(tvalue.asString(), priority); } if(mImagep.notNull() diff --git a/indra/llui/lliconctrl.h b/indra/llui/lliconctrl.h index 7971cd44d3..dd83e78fd3 100755 --- a/indra/llui/lliconctrl.h +++ b/indra/llui/lliconctrl.h @@ -59,6 +59,8 @@ protected: LLIconCtrl(const Params&); friend class LLUICtrlFactory; + void setValue(const LLSD& value, S32 priority); + public: virtual ~LLIconCtrl(); diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp index 932326acae..c131dc641b 100755 --- a/indra/newview/llavatariconctrl.cpp +++ b/indra/newview/llavatariconctrl.cpp @@ -196,7 +196,7 @@ LLAvatarIconCtrl::LLAvatarIconCtrl(const LLAvatarIconCtrl::Params& p) } else { - LLIconCtrl::setValue(mDefaultIconName); + LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI); } } @@ -243,7 +243,7 @@ void LLAvatarIconCtrl::setValue(const LLSD& value) // *TODO: Consider getting avatar icon/badge directly from // People API, rather than sending AvatarPropertyRequest // messages. People API already hits the user table. - LLIconCtrl::setValue(mDefaultIconName); + LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI); app->addObserver(mAvatarId, this); app->sendAvatarPropertiesRequest(mAvatarId); } @@ -284,7 +284,7 @@ bool LLAvatarIconCtrl::updateFromCache() } else { - LLIconCtrl::setValue(mDefaultIconName); + LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI); return false; } diff --git a/indra/newview/llgroupiconctrl.cpp b/indra/newview/llgroupiconctrl.cpp index 1974a073dd..271dd44c1f 100755 --- a/indra/newview/llgroupiconctrl.cpp +++ b/indra/newview/llgroupiconctrl.cpp @@ -64,7 +64,8 @@ LLGroupIconCtrl::LLGroupIconCtrl(const LLGroupIconCtrl::Params& p) } else { - LLIconCtrl::setValue(mDefaultIconName); + //TODO: Consider implementing dedicated setDefault() function instead of passing priority for local file + LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI); } } @@ -73,6 +74,11 @@ LLGroupIconCtrl::~LLGroupIconCtrl() LLGroupMgr::getInstance()->removeObserver(this); } +void LLGroupIconCtrl::setIconId(const LLSD& value) +{ + LLIconCtrl::setValue(value); +} + void LLGroupIconCtrl::setValue(const LLSD& value) { if (value.isUUID()) @@ -91,7 +97,7 @@ void LLGroupIconCtrl::setValue(const LLSD& value) // Check if cache already contains image_id for that group if (!updateFromCache()) { - LLIconCtrl::setValue(mDefaultIconName); + LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI); gm->addObserver(this); gm->sendGroupPropertiesRequest(mGroupId); } @@ -122,7 +128,7 @@ bool LLGroupIconCtrl::updateFromCache() } else { - LLIconCtrl::setValue(mDefaultIconName); + LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI); } if (mDrawTooltip && !group_data->mName.empty()) diff --git a/indra/newview/llgroupiconctrl.h b/indra/newview/llgroupiconctrl.h index f42593c9e1..f8b22cf581 100755 --- a/indra/newview/llgroupiconctrl.h +++ b/indra/newview/llgroupiconctrl.h @@ -66,6 +66,8 @@ public: */ virtual void setValue(const LLSD& value); + void setIconId(const LLSD& value); + // LLGroupMgrObserver observer trigger virtual void changed(LLGroupChange gc); diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp index ef238cefe3..6126db2988 100755 --- a/indra/newview/llgrouplist.cpp +++ b/indra/newview/llgrouplist.cpp @@ -30,7 +30,7 @@ // libs #include "llbutton.h" -#include "lliconctrl.h" +#include "llgroupiconctrl.h" #include "llmenugl.h" #include "lltextbox.h" #include "lltextutil.h" @@ -319,7 +319,7 @@ LLGroupListItem::~LLGroupListItem() //virtual BOOL LLGroupListItem::postBuild() { - mGroupIcon = getChild("group_icon"); + mGroupIcon = getChild("group_icon"); mGroupNameBox = getChild("group_name"); mInfoBtn = getChild("info_btn"); @@ -381,7 +381,7 @@ void LLGroupListItem::setGroupIconID(const LLUUID& group_icon_id) { if (group_icon_id.notNull()) { - mGroupIcon->setValue(group_icon_id); + mGroupIcon->setIconId(group_icon_id); } } diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h index e96a720886..171b77fb00 100755 --- a/indra/newview/llgrouplist.h +++ b/indra/newview/llgrouplist.h @@ -83,7 +83,7 @@ private: }; class LLButton; -class LLIconCtrl; +class LLGroupIconCtrl; class LLTextBox; class LLGroupListItem : public LLPanel @@ -113,7 +113,7 @@ private: LLTextBox* mGroupNameBox; LLUUID mGroupID; - LLIconCtrl* mGroupIcon; + LLGroupIconCtrl* mGroupIcon; LLButton* mInfoBtn; std::string mGroupName; diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 366b9ac034..aa934f95a1 100755 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -135,7 +135,7 @@ LLLocalBitmap::~LLLocalBitmap() } // delete self from gimagelist - LLViewerFetchedTexture* image = gTextureList.findImage(mWorldID, TEX_LIST_DISCARD); + LLViewerFetchedTexture* image = gTextureList.findImage(mWorldID, TEX_LIST_STANDARD); gTextureList.deleteImage(image); if (image) @@ -207,7 +207,7 @@ bool LLLocalBitmap::updateSelf(EUpdateType optional_firstupdate) texture->setCachedRawImage(LL_LOCAL_DISCARD_LEVEL, raw_image); texture->ref(); - gTextureList.addImage(texture, TEX_LIST_DISCARD); + gTextureList.addImage(texture, TEX_LIST_STANDARD); if (optional_firstupdate != UT_FIRSTUSE) { @@ -215,7 +215,7 @@ bool LLLocalBitmap::updateSelf(EUpdateType optional_firstupdate) replaceIDs(old_id, mWorldID); // remove old_id from gimagelist - LLViewerFetchedTexture* image = gTextureList.findImage(old_id, TEX_LIST_DISCARD); + LLViewerFetchedTexture* image = gTextureList.findImage(old_id, TEX_LIST_STANDARD); if (image != NULL) { gTextureList.deleteImage(image); @@ -384,7 +384,7 @@ void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id) std::vector LLLocalBitmap::prepUpdateObjects(LLUUID old_id, U32 channel) { std::vector obj_list; - LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id, TEX_LIST_DISCARD); + LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id, TEX_LIST_STANDARD); for(U32 face_iterator = 0; face_iterator < old_texture->getNumFaces(channel); face_iterator++) { @@ -502,7 +502,7 @@ void LLLocalBitmap::updateUserPrims(LLUUID old_id, LLUUID new_id, U32 channel) void LLLocalBitmap::updateUserSculpts(LLUUID old_id, LLUUID new_id) { - LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id, TEX_LIST_DISCARD); + LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id, TEX_LIST_STANDARD); for(U32 volume_iter = 0; volume_iter < old_texture->getNumVolumes(); volume_iter++) { LLVOVolume* volume_to_object = (*old_texture->getVolumeList())[volume_iter]; diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 551495c6ad..ec2d37c30d 100755 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -2214,7 +2214,7 @@ void LLPanelFace::LLSelectedTE::getTexId(LLUUID& id, bool& identical) LLTextureEntry *te = object->getTE(te_index); if (te) { - LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID(), TEX_LIST_DISCARD) : NULL; + LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID(), TEX_LIST_STANDARD) : NULL; if(!tex) { tex = LLViewerFetchedTexture::sDefaultImagep; diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 980810835e..e5aa740a33 100755 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -1393,7 +1393,7 @@ void LLTextureCtrl::setOnTextureSelectedCallback(texture_selected_callback cb) void LLTextureCtrl::setImageAssetName(const std::string& name) { - LLPointer imagep = LLUI::getUIImage(name); + LLPointer imagep = LLUI::getUIImage(name, LLGLTexture::BOOST_PREVIEW); if(imagep) { LLViewerFetchedTexture* pTexture = dynamic_cast(imagep->getImage().get()); diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 27d754bed2..bb93597651 100755 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -4460,7 +4460,7 @@ void LLTextureFetchDebugger::addHistoryEntry(LLTextureFetchWorker* worker) mRefetchedAllData += worker->mFormattedImage->getDataSize(); // refetch list only requests/creates normal images, so requesting ui='false' - LLViewerFetchedTexture* tex = LLViewerTextureManager::findFetchedTexture(worker->mID, TEX_LIST_DISCARD); + LLViewerFetchedTexture* tex = LLViewerTextureManager::findFetchedTexture(worker->mID, TEX_LIST_STANDARD); if(tex && mRefetchList[tex].begin() != mRefetchList[tex].end()) { if(worker->mDecodedDiscard == mFetchingHistory[mRefetchList[tex][0]].mDecodedLevel) diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp index cafe757c1a..f6ca0bc9d7 100755 --- a/indra/newview/lltoastgroupnotifypanel.cpp +++ b/indra/newview/lltoastgroupnotifypanel.cpp @@ -31,7 +31,7 @@ #include "llfocusmgr.h" #include "llbutton.h" -#include "lliconctrl.h" +#include "llgroupiconctrl.h" #include "llinventoryfunctions.h" #include "llinventoryicon.h" #include "llnotifications.h" @@ -65,8 +65,10 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(const LLNotificationPtr& notifi } //group icon - LLIconCtrl* pGroupIcon = getChild("group_icon", TRUE); - pGroupIcon->setValue(groupData.mInsigniaID); + LLGroupIconCtrl* pGroupIcon = getChild("group_icon", TRUE); + + // We should already have this data preloaded, so no sense in setting icon through setValue(group_id) + pGroupIcon->setIconId(groupData.mInsigniaID); //header title std::string from_name = payload["sender_name"].asString(); diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 3e059f3b68..c5e07f009f 100755 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -3323,7 +3323,7 @@ LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LL setCategory(LLGLTexture::MEDIA); - LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_DISCARD); + LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_STANDARD); if(tex) //this media is a parcel media for tex. { tex->setParcelMedia(this); @@ -3333,7 +3333,7 @@ LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LL //virtual LLViewerMediaTexture::~LLViewerMediaTexture() { - LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_DISCARD); + LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_STANDARD); if(tex) //this media is a parcel media for tex. { tex->setParcelMedia(NULL); @@ -3388,7 +3388,7 @@ BOOL LLViewerMediaTexture::findFaces() BOOL ret = TRUE; - LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_DISCARD); + LLViewerTexture* tex = gTextureList.findImage(mID, TEX_LIST_STANDARD); if(tex) //this media is a parcel media for tex. { for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch) @@ -3497,7 +3497,7 @@ void LLViewerMediaTexture::addFace(U32 ch, LLFace* facep) const LLTextureEntry* te = facep->getTextureEntry(); if(te && te->getID().notNull()) { - LLViewerTexture* tex = gTextureList.findImage(te->getID(), TEX_LIST_DISCARD); + LLViewerTexture* tex = gTextureList.findImage(te->getID(), TEX_LIST_STANDARD); if(tex) { mTextureList.push_back(tex);//increase the reference number by one for tex to avoid deleting it. @@ -3526,7 +3526,7 @@ void LLViewerMediaTexture::removeFace(U32 ch, LLFace* facep) const LLTextureEntry* te = facep->getTextureEntry(); if(te && te->getID().notNull()) { - LLViewerTexture* tex = gTextureList.findImage(te->getID(), TEX_LIST_DISCARD); + LLViewerTexture* tex = gTextureList.findImage(te->getID(), TEX_LIST_STANDARD); if(tex) { for(std::list< LLPointer >::iterator iter = mTextureList.begin(); @@ -3635,10 +3635,10 @@ void LLViewerMediaTexture::switchTexture(U32 ch, LLFace* facep) const LLTextureEntry* te = facep->getTextureEntry(); if(te) { - LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID(), TEX_LIST_DISCARD) : NULL; + LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID(), TEX_LIST_STANDARD) : NULL; if(!tex && te->getID() != mID)//try parcel media. { - tex = gTextureList.findImage(mID, TEX_LIST_DISCARD); + tex = gTextureList.findImage(mID, TEX_LIST_STANDARD); } if(!tex) { diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index e580ecaba1..4eeb1ca377 100755 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -72,20 +72,14 @@ static LLTrace::BlockTimerStatHandle FTM_PROCESS_IMAGES("Process Images"); ETexListType get_element_type(S32 priority) { - // don't discard flag can be used in some cases, but it usually is not set yet - if (priority == LLViewerFetchedTexture::BOOST_ICON - || priority == LLViewerFetchedTexture::BOOST_UI) - { - return TEX_LIST_UI; - } - return TEX_LIST_DISCARD; + return (priority == LLViewerFetchedTexture::BOOST_ICON) ? TEX_LIST_SCALE : TEX_LIST_STANDARD; } /////////////////////////////////////////////////////////////////////////////// LLTextureKey::LLTextureKey() : textureId(LLUUID::null), -textureType(TEX_LIST_DISCARD) +textureType(TEX_LIST_STANDARD) { } @@ -591,7 +585,7 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id, void LLViewerTextureList::findTexturesByID(const LLUUID &image_id, std::vector &output) { - LLTextureKey search_key(image_id, TEX_LIST_DISCARD); + LLTextureKey search_key(image_id, TEX_LIST_STANDARD); uuid_map_t::iterator iter = mUUIDMap.lower_bound(search_key); while (iter != mUUIDMap.end() && iter->first.textureId == image_id) { @@ -1597,14 +1591,14 @@ void LLViewerTextureList::processImageNotInDatabase(LLMessageSystem *msg,void ** LLUUID image_id; msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, image_id); - LLViewerFetchedTexture* image = gTextureList.findImage( image_id, TEX_LIST_DISCARD); + LLViewerFetchedTexture* image = gTextureList.findImage( image_id, TEX_LIST_STANDARD); if( image ) { LL_WARNS() << "Image not in db" << LL_ENDL; image->setIsMissingAsset(); } - image = gTextureList.findImage(image_id, TEX_LIST_UI); + image = gTextureList.findImage(image_id, TEX_LIST_SCALE); if (image) { LL_WARNS() << "Icon not in db" << LL_ENDL; diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index 9f94f2f1bc..ba76770838 100755 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -61,8 +61,8 @@ typedef void (*LLImageCallback)(BOOL success, enum ETexListType { - TEX_LIST_DISCARD = 0, - TEX_LIST_UI + TEX_LIST_STANDARD = 0, + TEX_LIST_SCALE }; struct LLTextureKey diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index a26b5e0a98..6f96eb9772 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1992,7 +1992,7 @@ LLViewerFetchedTexture *LLVOAvatar::getBakedTextureImage(const U8 te, const LLUU uuid == IMG_INVISIBLE) { // Should already exist, don't need to find it on sim or baked-texture host. - result = gTextureList.findImage(uuid, TEX_LIST_DISCARD); + result = gTextureList.findImage(uuid, TEX_LIST_STANDARD); } if (!result) { @@ -4313,7 +4313,7 @@ bool LLVOAvatar::allTexturesCompletelyDownloaded(std::set& ids) const { for (std::set::const_iterator it = ids.begin(); it != ids.end(); ++it) { - LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_DISCARD); + LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_STANDARD); if (imagep && imagep->getDiscardLevel()!=0) { return false; @@ -4385,7 +4385,7 @@ S32Bytes LLVOAvatar::totalTextureMemForUUIDS(std::set& ids) S32Bytes result(0); for (std::set::const_iterator it = ids.begin(); it != ids.end(); ++it) { - LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_DISCARD); + LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_STANDARD); if (imagep) { result += imagep->getTextureMemory(); @@ -4473,7 +4473,7 @@ void LLVOAvatar::releaseOldTextures() { if (new_texture_ids.find(*it) == new_texture_ids.end()) { - LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_DISCARD); + LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_STANDARD); if (imagep) { current_texture_mem += imagep->getTextureMemory(); diff --git a/indra/newview/skins/default/xui/en/panel_group_list_item.xml b/indra/newview/skins/default/xui/en/panel_group_list_item.xml index cfe3aeb7c9..e758a8ce30 100755 --- a/indra/newview/skins/default/xui/en/panel_group_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_group_list_item.xml @@ -27,7 +27,7 @@ top="0" visible="false" width="320" /> - - Date: Thu, 31 Mar 2016 18:08:31 +0300 Subject: [PATCH 18/62] MAINT-6238 Warn user if Trash is overflowing --- indra/newview/app_settings/settings.xml | 11 +++++++ indra/newview/llinventorybridge.cpp | 1 + indra/newview/llinventorymodel.cpp | 29 +++++++++++++++++++ indra/newview/llinventorymodel.h | 5 ++++ .../skins/default/xui/en/notifications.xml | 12 ++++++++ 5 files changed, 58 insertions(+) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index aef2438dc7..d5de494434 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -4845,6 +4845,17 @@ Value 7 + InventoryTrashMaxCapacity + + Comment + Maximum capacity of the Trash folder. User will ve offered to clean it up when exceeded. + Persist + 1 + Type + U32 + Value + 5000 + MarketplaceListingsSortOrder Comment diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 9782c792c9..907491a390 100755 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -2065,6 +2065,7 @@ BOOL LLItemBridge::removeItem() } LLNotifications::instance().forceResponse(params, 0); + model->checkTrashOverflow(); return TRUE; } diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 1ae8fc418f..1554940a25 100755 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -771,6 +771,22 @@ void LLInventoryModel::collectDescendentsIf(const LLUUID& id, } } +U32 LLInventoryModel::getDescendentsCountRecursive(const LLUUID& id, U32 max_item_limit) +{ + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + gInventory.collectDescendents(id, cats, items, LLInventoryModel::INCLUDE_TRASH); + + U32 items_found = items.size() + cats.size(); + + for (U32 i = 0; i < cats.size() && items_found <= max_item_limit; ++i) + { + items_found += getDescendentsCountRecursive(cats[i]->getUUID(), max_item_limit - items_found); + } + + return items_found; +} + void LLInventoryModel::addChangedMaskForLinks(const LLUUID& object_id, U32 mask) { const LLInventoryObject *obj = getObject(object_id); @@ -3333,6 +3349,7 @@ void LLInventoryModel::processMoveInventoryItem(LLMessageSystem* msg, void**) //---------------------------------------------------------------------------- // Trash: LLFolderType::FT_TRASH, "ConfirmEmptyTrash" +// Trash: LLFolderType::FT_TRASH, "TrashIsFull" when trash exceeds maximum capacity // Lost&Found: LLFolderType::FT_LOST_AND_FOUND, "ConfirmEmptyLostAndFound" bool LLInventoryModel::callbackEmptyFolderType(const LLSD& notification, const LLSD& response, LLFolderType::EType preferred_type) @@ -3414,6 +3431,8 @@ void LLInventoryModel::removeCategory(const LLUUID& category_id) changeCategoryParent(cat, trash_id, TRUE); } } + + checkTrashOverflow(); } void LLInventoryModel::removeObject(const LLUUID& object_id) @@ -3444,6 +3463,16 @@ void LLInventoryModel::removeObject(const LLUUID& object_id) } } +void LLInventoryModel::checkTrashOverflow() +{ + static const U32 trash_max_capacity = gSavedSettings.getU32("InventoryTrashMaxCapacity"); + const LLUUID trash_id = findCategoryUUIDForType(LLFolderType::FT_TRASH); + if (getDescendentsCountRecursive(trash_id, trash_max_capacity) >= trash_max_capacity) + { + gInventory.emptyFolderType("TrashIsFull", LLFolderType::FT_TRASH); + } +} + const LLUUID &LLInventoryModel::getRootFolderID() const { return mRootFolderID; diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index ac336e347c..0782ec5255 100755 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -258,6 +258,9 @@ public: // Follow parent chain to the top. bool getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const; + +private: + U32 getDescendentsCountRecursive(const LLUUID& id, U32 max_item_limit); //-------------------------------------------------------------------- // Find @@ -399,6 +402,8 @@ public: /// removeItem() or removeCategory(), whichever is appropriate void removeObject(const LLUUID& object_id); + void checkTrashOverflow(); + protected: void updateLinkedObjectsFromPurge(const LLUUID& baseobj_id); diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 3831b52c2c..f8d76eff58 100755 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -5990,6 +5990,18 @@ Are you sure you want to permanently delete the contents of your Trash? yestext="OK"/> + +Your trash is overflowing. This may cause problems logging in. + confirm + + + Date: Fri, 1 Apr 2016 14:31:46 +0300 Subject: [PATCH 19/62] MAINT-6274 FIXED Mouse pointer incorrectly appears on the edge of the screen after dragging World map --- indra/llmath/llrect.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/indra/llmath/llrect.h b/indra/llmath/llrect.h index c51e0e0ae6..58f02d4d2b 100755 --- a/indra/llmath/llrect.h +++ b/indra/llmath/llrect.h @@ -118,8 +118,10 @@ public: if (end_y < mBottom) clip_y = end_y - mBottom; // clip_? and delta_? should have same sign, since starting point is in rect // so ratios will be positive - F32 ratio_x = ((F32)clip_x / (F32)delta_x); - F32 ratio_y = ((F32)clip_y / (F32)delta_y); + F32 ratio_x = 0; + F32 ratio_y = 0; + if (delta_x != 0) ratio_x = ((F32)clip_x / (F32)delta_x); + if (delta_y != 0) ratio_y = ((F32)clip_y / (F32)delta_y); if (ratio_x > ratio_y) { // clip along x direction From a9f001f276b9f828cb02a19b7c6256b198a0b387 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Tue, 5 Apr 2016 16:58:12 +0300 Subject: [PATCH 20/62] Backed out changeset: a481e543cc74 --- indra/newview/llpanelpermissions.cpp | 44 +++++++++++++--------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index 0088163fee..263c73dc0e 100755 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -1080,30 +1080,28 @@ void LLPanelPermissions::setAllSaleInfo() LLSaleInfo new_sale_info(sale_type, price); LLSelectMgr::getInstance()->selectionSetObjectSaleInfo(new_sale_info); + + U8 old_click_action = 0; + LLSelectMgr::getInstance()->selectionGetClickAction(&old_click_action); - bool selection_set_for_sale = new_sale_info.isForSale(); - bool selection_was_for_sale = old_sale_info.isForSale(); - if (selection_was_for_sale != selection_set_for_sale) - { - // sale state changed, switch click-actions - // but don't touch user changed actions - U8 old_action = selection_set_for_sale ? CLICK_ACTION_TOUCH : CLICK_ACTION_BUY; - U8 new_action = selection_set_for_sale ? CLICK_ACTION_BUY : CLICK_ACTION_TOUCH; - struct f : public LLSelectedObjectFunctor - { - U8 mActionOld, mActionNew; - f(const U8& t_old, const U8& t_new) : mActionOld(t_old), mActionNew(t_new) {} - virtual bool apply(LLViewerObject* object) - { - if (object->getClickAction() == mActionOld) - { - object->setClickAction(mActionNew); - } - return true; - } - } func(old_action, new_action); - LLSelectMgr::getInstance()->getSelection()->applyToObjects(&func); - } + if (old_sale_info.isForSale() + && !new_sale_info.isForSale() + && old_click_action == CLICK_ACTION_BUY) + { + // If turned off for-sale, make sure click-action buy is turned + // off as well + LLSelectMgr::getInstance()-> + selectionSetClickAction(CLICK_ACTION_TOUCH); + } + else if (new_sale_info.isForSale() + && !old_sale_info.isForSale() + && old_click_action == CLICK_ACTION_TOUCH) + { + // If just turning on for-sale, preemptively turn on one-click buy + // unless user have a different click action set + LLSelectMgr::getInstance()-> + selectionSetClickAction(CLICK_ACTION_BUY); + } } struct LLSelectionPayable : public LLSelectedObjectFunctor From afcea0b8dc6ad6729ce18f4e051b230d17b98c09 Mon Sep 17 00:00:00 2001 From: AndreyL ProductEngine Date: Wed, 6 Apr 2016 01:34:21 +0300 Subject: [PATCH 21/62] MAINT-6304 FIXED Push-to-talk triggered with keyboard doesn't close the mic --- indra/newview/llvoiceclient.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 56c0910983..5c125a236a 100755 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -657,19 +657,25 @@ void LLVoiceClient::keyDown(KEY key, MASK mask) return; } - if(!mPTTIsMiddleMouse && LLAgent::isActionAllowed("speak")) + if (!mPTTIsMiddleMouse && LLAgent::isActionAllowed("speak") && (key == mPTTKey)) { - bool down = (mPTTKey != KEY_NONE) && gKeyboard->getKeyDown(mPTTKey); - if (down) { inputUserControlState(down); } + bool down = gKeyboard->getKeyDown(mPTTKey); + if (down) + { + inputUserControlState(down); + } } } void LLVoiceClient::keyUp(KEY key, MASK mask) { - if(!mPTTIsMiddleMouse) + if (!mPTTIsMiddleMouse && (key == mPTTKey)) { - bool down = (mPTTKey != KEY_NONE) && gKeyboard->getKeyDown(mPTTKey); - if (down) { inputUserControlState(down); } + bool down = gKeyboard->getKeyDown(mPTTKey); + if (!down) + { + inputUserControlState(down); + } } } void LLVoiceClient::middleMouseState(bool down) From 56f251fb4422e77c856e3968434ff736fda5a43f Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Wed, 6 Apr 2016 18:42:43 +0300 Subject: [PATCH 22/62] MAINT-1539 'L$' indicator doesn't disappear when object is not for sale --- indra/newview/llpanelpermissions.cpp | 39 +++++++++++++--------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index 263c73dc0e..6e677bbce5 100755 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -1080,28 +1080,25 @@ void LLPanelPermissions::setAllSaleInfo() LLSaleInfo new_sale_info(sale_type, price); LLSelectMgr::getInstance()->selectionSetObjectSaleInfo(new_sale_info); - - U8 old_click_action = 0; - LLSelectMgr::getInstance()->selectionGetClickAction(&old_click_action); - if (old_sale_info.isForSale() - && !new_sale_info.isForSale() - && old_click_action == CLICK_ACTION_BUY) - { - // If turned off for-sale, make sure click-action buy is turned - // off as well - LLSelectMgr::getInstance()-> - selectionSetClickAction(CLICK_ACTION_TOUCH); - } - else if (new_sale_info.isForSale() - && !old_sale_info.isForSale() - && old_click_action == CLICK_ACTION_TOUCH) - { - // If just turning on for-sale, preemptively turn on one-click buy - // unless user have a different click action set - LLSelectMgr::getInstance()-> - selectionSetClickAction(CLICK_ACTION_BUY); - } + struct f : public LLSelectedObjectFunctor + { + virtual bool apply(LLViewerObject* object) + { + return object->getClickAction() == CLICK_ACTION_BUY + || object->getClickAction() == CLICK_ACTION_TOUCH; + } + } check_actions; + + // Selection should only contain objects that are of target + // action already or of action we are aiming to remove. + bool default_actions = LLSelectMgr::getInstance()->getSelection()->applyToObjects(&check_actions); + + if (default_actions && old_sale_info.isForSale() != new_sale_info.isForSale()) + { + U8 new_click_action = new_sale_info.isForSale() ? CLICK_ACTION_BUY : CLICK_ACTION_TOUCH; + LLSelectMgr::getInstance()->selectionSetClickAction(new_click_action); + } } struct LLSelectionPayable : public LLSelectedObjectFunctor From 352403b0e28ff545099fe234a02f507388477704 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Fri, 1 Apr 2016 21:16:07 +0300 Subject: [PATCH 23/62] MAINT-6272 Viewer inventory cache bug --- indra/newview/llinventorymodel.cpp | 39 +++++++++++++++++++++--------- indra/newview/llinventorymodel.h | 4 ++- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 908f7125df..cada2d7cf2 100755 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -44,6 +44,7 @@ #include "llmarketplacefunctions.h" #include "llwindow.h" #include "llviewercontrol.h" +#include "llviewernetwork.h" #include "llpreview.h" #include "llviewermessage.h" #include "llviewerfoldertype.h" @@ -73,7 +74,8 @@ BOOL LLInventoryModel::sFirstTimeInViewer2 = TRUE; ///---------------------------------------------------------------------------- //BOOL decompress_file(const char* src_filename, const char* dst_filename); -static const char CACHE_FORMAT_STRING[] = "%s.inv"; +static const char PRODUCTION_CACHE_FORMAT_STRING[] = "%s.inv"; +static const char GRID_CACHE_FORMAT_STRING[] = "%s.%s.inv"; static const char * const LOG_INV("Inventory"); struct InventoryIDPtrLess @@ -1623,6 +1625,29 @@ bool LLInventoryModel::fetchDescendentsOf(const LLUUID& folder_id) const return cat->fetch(); } +//static +std::string LLInventoryModel::getInvCacheAddres(const LLUUID& owner_id) +{ + std::string inventory_addr; + std::string owner_id_str; + owner_id.toString(owner_id_str); + std::string path(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, owner_id_str)); + if (LLGridManager::getInstance()->isInProductionGrid()) + { + inventory_addr = llformat(PRODUCTION_CACHE_FORMAT_STRING, path.c_str()); + } + else + { + // NOTE: The inventory cache filenames now include the grid name. + // Add controls against directory traversal or problematic pathname lengths + // if your viewer uses grid names from an untrusted source. + const std::string& grid_id_str = LLGridManager::getInstance()->getGridId(); + const std::string& grid_id_lower = utf8str_tolower(grid_id_str); + inventory_addr = llformat(GRID_CACHE_FORMAT_STRING, path.c_str(), grid_id_lower.c_str()); + } + return inventory_addr; +} + void LLInventoryModel::cache( const LLUUID& parent_folder_id, const LLUUID& agent_id) @@ -1643,11 +1668,7 @@ void LLInventoryModel::cache( items, INCLUDE_TRASH, can_cache); - std::string agent_id_str; - std::string inventory_filename; - agent_id.toString(agent_id_str); - std::string path(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, agent_id_str)); - inventory_filename = llformat(CACHE_FORMAT_STRING, path.c_str()); + std::string inventory_filename = getInvCacheAddres(agent_id); saveToFile(inventory_filename, categories, items); std::string gzip_filename(inventory_filename); gzip_filename.append(".gz"); @@ -1951,11 +1972,7 @@ bool LLInventoryModel::loadSkeleton( item_array_t items; item_array_t possible_broken_links; cat_set_t invalid_categories; // Used to mark categories that weren't successfully loaded. - std::string owner_id_str; - owner_id.toString(owner_id_str); - std::string path(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, owner_id_str)); - std::string inventory_filename; - inventory_filename = llformat(CACHE_FORMAT_STRING, path.c_str()); + std::string inventory_filename = getInvCacheAddres(owner_id); const S32 NO_VERSION = LLViewerInventoryCategory::VERSION_UNKNOWN; std::string gzip_filename(inventory_filename); gzip_filename.append(".gz"); diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 86c6df3323..3004eaf7c1 100755 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -164,7 +164,9 @@ public: bool loadSkeleton(const LLSD& options, const LLUUID& owner_id); void buildParentChildMap(); // brute force method to rebuild the entire parent-child relations void createCommonSystemCategories(); - + + static std::string getInvCacheAddres(const LLUUID& owner_id); + // Call on logout to save a terse representation. void cache(const LLUUID& parent_folder_id, const LLUUID& agent_id); private: From 9ce18dddc7c810bdc6e3ecb9209ffadda96e635d Mon Sep 17 00:00:00 2001 From: Ansariel Date: Sat, 2 Apr 2016 03:58:40 +0200 Subject: [PATCH 24/62] Apply changes for MAINT-6257 to all skins --- indra/newview/skins/ansastorm/xui/en/panel_group_notify.xml | 2 +- indra/newview/skins/firestorm/xui/en/panel_group_notify.xml | 2 +- indra/newview/skins/latency/xui/en/panel_group_list_item.xml | 2 +- indra/newview/skins/latency/xui/en/panel_group_notify.xml | 2 +- indra/newview/skins/metaharper/xui/en/panel_group_notify.xml | 2 +- indra/newview/skins/starlight/xui/en/panel_group_notify.xml | 2 +- indra/newview/skins/starlightcui/xui/en/panel_group_notify.xml | 2 +- indra/newview/skins/vintage/xui/en/panel_group_list_item.xml | 2 +- indra/newview/skins/vintage/xui/en/panel_group_notify.xml | 2 +- indra/newview/skins/vintage/xui/ja/panel_group_notify.xml | 1 - 10 files changed, 9 insertions(+), 10 deletions(-) diff --git a/indra/newview/skins/ansastorm/xui/en/panel_group_notify.xml b/indra/newview/skins/ansastorm/xui/en/panel_group_notify.xml index 26dcc67c70..1bf873d7f2 100644 --- a/indra/newview/skins/ansastorm/xui/en/panel_group_notify.xml +++ b/indra/newview/skins/ansastorm/xui/en/panel_group_notify.xml @@ -42,7 +42,7 @@ use_ellipses="true" width="380" value="Sent by Sender Name, Group Name"/> - - - - - - - - - - From 65c95cd65648321b0684b6a14e04ab104d95bad6 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Sat, 2 Apr 2016 04:02:24 +0200 Subject: [PATCH 25/62] Update German translation --- indra/newview/skins/default/xui/de/notifications.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml index 66fc02be03..ca97d967a9 100755 --- a/indra/newview/skins/default/xui/de/notifications.xml +++ b/indra/newview/skins/default/xui/de/notifications.xml @@ -2489,6 +2489,10 @@ Möchten Sie den Nicht-stören-Modus deaktivieren, bevor Sie diese Transaktion a Sind Sie sicher, dass Sie den Inhalt Ihres Papierkorbs löschen möchten? + + Ihr Papierkorb läuft über. Dies kann zu Problemen beim Login führen. + + Sind Sie sicher, dass Sie Ihren Reise-, Internet- und Suchverlauf löschen möchten? From fce97c4aae6a6b21fb89961cdbb84dbbeee8fcf7 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Sat, 2 Apr 2016 04:37:21 +0200 Subject: [PATCH 26/62] Build fix --- indra/newview/daeexport.cpp | 2 +- indra/newview/llvoavatar.cpp | 2 +- indra/newview/llworldmap.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/indra/newview/daeexport.cpp b/indra/newview/daeexport.cpp index 87d576951e..c9f3a9f7f3 100644 --- a/indra/newview/daeexport.cpp +++ b/indra/newview/daeexport.cpp @@ -486,7 +486,7 @@ void ColladaExportFloater::CacheReadResponder::saveTexturesWorker(void* data) } LLUUID id = me->mTexturesToSave.begin()->first; - LLViewerTexture* imagep = LLViewerTextureManager::findFetchedTexture(id, TEX_LIST_DISCARD); + LLViewerTexture* imagep = LLViewerTextureManager::findFetchedTexture(id, TEX_LIST_STANDARD); if (!imagep) { me->mTexturesToSave.erase(id); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index f6e269bb60..eea4a96209 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -9384,7 +9384,7 @@ void LLVOAvatar::bakedTextureOriginCounts(S32 &sb_count, // server-bake, has ori collectBakedTextureUUIDs(baked_ids); for (std::set::const_iterator it = baked_ids.begin(); it != baked_ids.end(); ++it) { - LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_DISCARD); + LLViewerFetchedTexture *imagep = gTextureList.findImage(*it, TEX_LIST_STANDARD); bool has_url = false, has_host = false; if (!imagep->getUrl().empty()) { diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp index 7ccf03f7f4..02589c1b34 100755 --- a/indra/newview/llworldmap.cpp +++ b/indra/newview/llworldmap.cpp @@ -87,7 +87,7 @@ void LLSimInfo::setLandForSaleImage (LLUUID image_id) // Aurora Sim if (mMapImageID.isNull() && image_id.notNull()) { - mOverlayImage = LLViewerTextureManager::findFetchedTexture(image_id, TEX_LIST_DISCARD); + mOverlayImage = LLViewerTextureManager::findFetchedTexture(image_id, TEX_LIST_STANDARD); if(mOverlayImage.notNull()) { LLAppViewer::getTextureCache()->removeFromCache(image_id); From 7620380018dde38c9376c33bbd45531472cfb256 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Sat, 2 Apr 2016 04:38:52 +0200 Subject: [PATCH 27/62] Re-add fix for MAINT-5938 after coroutine merge --- indra/newview/llmarketplacefunctions.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index 3270186f0b..2c881bf816 100755 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -796,6 +796,15 @@ void LLMarketplaceData::getMerchantStatusCoro() log_SLM_infos("Get /merchant", httpCode, std::string("Merchant is not migrated")); setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MIGRATED_MERCHANT); } + else if (httpCode == HTTP_INTERNAL_ERROR) + { + // 499 includes timeout and ssl error - marketplace is down or having issues, we do not show it in this request according to MAINT-5938 + LL_WARNS("SLM") << "SLM Merchant Request failed with status: " << httpCode + << ", reason : " << status.toString() + << ", code : " << result["error_code"].asString() + << ", description : " << result["error_description"].asString() << LL_ENDL; + LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE); + } else { std::string err_code = result["error_code"].asString(); From c7e2c496ab413d4d9823845fedba82e67e5ed51c Mon Sep 17 00:00:00 2001 From: Mnikolenko ProductEngine Date: Thu, 7 Apr 2016 11:28:37 +0300 Subject: [PATCH 28/62] MAINT-6294 FIXED Cursor became invisible after typing in any input field (OS X) --- indra/llwindow/llwindowmacosx.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index c6bf93507a..754306b5d2 100755 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -1459,10 +1459,9 @@ void LLWindowMacOSX::updateCursor() if(mCurrentCursor == mNextCursor) { - if(mCursorHidden && isCGCursorVisible()) + if(mCursorHidden && mHideCursorPermanent && isCGCursorVisible()) { - hideNSCursor(); - mHideCursorPermanent = TRUE; + hideNSCursor(); adjustCursorDecouple(); } return; From 48016ff54bced607ba11bb02825974b5133ada34 Mon Sep 17 00:00:00 2001 From: ruslantproductengine Date: Tue, 12 Apr 2016 19:29:35 +0300 Subject: [PATCH 29/62] MAINT-6286 Viewer 4.0.3.312680 ignores settings for Shaders in Graphics Preferences for ATI Radeon HD 3800 Series graphics card --- indra/llrender/llglslshader.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 750e35a71a..b30bc1aed6 100755 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -348,6 +348,7 @@ void LLGLSLShader::unloadInternal() glGetAttachedObjectsARB(mProgramObject, sizeof(obj)/sizeof(obj[0]), &count, obj); for (GLsizei i = 0; i < count; i++) { + glDetachObjectARB(mProgramObject, obj[i]); glDeleteObjectARB(obj[i]); } From 0ca3c5c7fdd6790d98259fc6d8459633896ce7a0 Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Tue, 12 Apr 2016 12:08:59 -0700 Subject: [PATCH 30/62] Added exponential timeout to retry, protect against attempting to downgrade the COF version in the bake request. --- indra/newview/llappearancemgr.cpp | 139 ++++++++++++++++++------------ indra/newview/llappearancemgr.h | 2 + 2 files changed, 87 insertions(+), 54 deletions(-) diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 99dcb80a4a..df56d7403c 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -65,7 +65,12 @@ #pragma warning (disable:4702) #endif -#if 1 +namespace +{ + const S32 BAKE_RETRY_MAX_COUNT = 5; + const F32 BAKE_RETRY_TIMEOUT = 2.0F; +} + // *TODO$: LLInventoryCallback should be deprecated to conform to the new boost::bind/coroutine model. // temp code in transition void doAppearanceCb(LLPointer cb, LLUUID id) @@ -73,8 +78,6 @@ void doAppearanceCb(LLPointer cb, LLUUID id) if (cb.notNull()) cb->fire(id); } -#endif - std::string self_av_string() { @@ -3354,12 +3357,21 @@ LLSD LLAppearanceMgr::dumpCOF() const void LLAppearanceMgr::requestServerAppearanceUpdate() { - LLCoprocedureManager::CoProcedure_t proc = boost::bind(&LLAppearanceMgr::serverAppearanceUpdateCoro, this, _1); - LLCoprocedureManager::instance().enqueueCoprocedure("AIS", "LLAppearanceMgr::serverAppearanceUpdateCoro", proc); + if (!mOutstandingAppearanceBakeRequest) + { + mRerequestAppearanceBake = false; + LLCoprocedureManager::CoProcedure_t proc = boost::bind(&LLAppearanceMgr::serverAppearanceUpdateCoro, this, _1); + LLCoprocedureManager::instance().enqueueCoprocedure("AIS", "LLAppearanceMgr::serverAppearanceUpdateCoro", proc); + } + else + { + mRerequestAppearanceBake = true; + } } void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter) { + mRerequestAppearanceBake = false; if (!gAgent.getRegion()) { LL_WARNS("Avatar") << "Region not set, cannot request server appearance update" << LL_ENDL; @@ -3386,57 +3398,57 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd return; } -#if 0 - static int reqcount = 0; - int r_count = ++reqcount; - LL_WARNS("Avatar") << "START: Server Bake request #" << r_count << "!" << LL_ENDL; -#endif - - // If we have already received an update for this or higher cof version, - // put a warning in the log but request anyway. - S32 cofVersion = getCOFVersion(); - S32 lastRcv = gAgentAvatarp->mLastUpdateReceivedCOFVersion; - S32 lastReq = gAgentAvatarp->mLastUpdateRequestCOFVersion; - - LL_INFOS("Avatar") << "Requesting COF version " << cofVersion << - " (Last Received:" << lastRcv << ")" << - " (Last Requested:" << lastReq << ")" << LL_ENDL; - - if ((cofVersion != LLViewerInventoryCategory::VERSION_UNKNOWN)) - { - if (cofVersion < lastRcv) - { - LL_WARNS("Avatar") << "Have already received update for cof version " << lastRcv - << " but requesting for " << cofVersion << LL_ENDL; - } - if (lastReq > cofVersion) - { - LL_WARNS("Avatar") << "Request already in flight for cof version " << lastReq - << " but requesting for " << cofVersion << LL_ENDL; - } - } - - // Actually send the request. - LL_DEBUGS("Avatar") << "Will send request for cof_version " << cofVersion << LL_ENDL; - -// LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter( -// "UpdateAvatarAppearance", gAgent.getAgentPolicy())); - + llcoro::suspend(); + S32 retryCount(0); bool bRetry; do { + BoolSetter outstanding(mOutstandingAppearanceBakeRequest); + + // If we have already received an update for this or higher cof version, + // put a warning in the log and cancel the request. + S32 cofVersion = getCOFVersion(); + S32 lastRcv = gAgentAvatarp->mLastUpdateReceivedCOFVersion; + S32 lastReq = gAgentAvatarp->mLastUpdateRequestCOFVersion; + + LL_INFOS("Avatar") << "Requesting COF version " << cofVersion << + " (Last Received:" << lastRcv << ")" << + " (Last Requested:" << lastReq << ")" << LL_ENDL; + + if (cofVersion == LLViewerInventoryCategory::VERSION_UNKNOWN) + { + LL_WARNS("AVatar") << "COF version is unknown... not requesting until COF version is known." << LL_ENDL; + return; + } + else + { + if (cofVersion < lastRcv) + { + LL_WARNS("Avatar") << "Have already received update for cof version " << lastRcv + << " but requesting for " << cofVersion << LL_ENDL; + return; + } + if (lastReq > cofVersion) + { + LL_WARNS("Avatar") << "Request already in flight for cof version " << lastReq + << " but requesting for " << cofVersion << LL_ENDL; + return; + } + } + + // Actually send the request. + LL_DEBUGS("Avatar") << "Will send request for cof_version " << cofVersion << LL_ENDL; + bRetry = false; LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest()); - S32 reqCofVersion = getCOFVersion(); // Treat COF version (gets set by AISAPI as authoritative, - // not what the bake request tells us to use). if (gSavedSettings.getBOOL("DebugForceAppearanceRequestFailure")) { - reqCofVersion += 999; + cofVersion += 999; LL_WARNS("Avatar") << "Forcing version failure on COF Baking" << LL_ENDL; } - LL_INFOS() << "Requesting bake for COF version " << reqCofVersion << LL_ENDL; + LL_INFOS() << "Requesting bake for COF version " << cofVersion << LL_ENDL; LLSD postData; if (gSavedSettings.getBOOL("DebugAvatarExperimentalServerAppearanceUpdate")) @@ -3445,10 +3457,10 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd } else { - postData["cof_version"] = reqCofVersion; + postData["cof_version"] = cofVersion; } - gAgentAvatarp->mLastUpdateRequestCOFVersion = reqCofVersion; + gAgentAvatarp->mLastUpdateRequestCOFVersion = cofVersion; LLSD result = httpAdapter->postAndSuspend(httpRequest, url, postData); @@ -3466,14 +3478,30 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd // on multiple machines. if (result.has("expected")) { + S32 expectedCofVersion = result["expected"].asInteger(); + LL_WARNS("Avatar") << "Server expected " << expectedCofVersion << " as COF version" << LL_ENDL; + bRetry = true; // Wait for a 1/2 second before trying again. Just to keep from asking too quickly. - llcoro::suspendUntilTimeout(0.5); + if (++retryCount > BAKE_RETRY_MAX_COUNT) + { + LL_WARNS("Avatar") << "Bake retry count exceeded!" << LL_ENDL; + break; + } + F32 timeout = pow(BAKE_RETRY_TIMEOUT, static_cast(retryCount)) - 1.0; - LL_WARNS("Avatar") << "Server expected " << expectedCofVersion << " as COF version" << LL_ENDL; + LL_WARNS("Avatar") << "Bake retry #" << retryCount << " in " << timeout << " seconds." << LL_ENDL; + + llcoro::suspendUntilTimeout(timeout); + bRetry = true; continue; } + else + { + LL_WARNS("Avatar") << "No retry attempted." << LL_ENDL; + break; + } } LL_DEBUGS("Avatar") << "succeeded" << LL_ENDL; @@ -3484,10 +3512,11 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd } while (bRetry); -#if 0 - LL_WARNS("Avatar") << "END: Server Bake request #" << r_count << "!" << LL_ENDL; -#endif - + if (mRerequestAppearanceBake) + { // A bake request came in while this one was still outstanding. + // Requeue ourself for a later request. + requestServerAppearanceUpdate(); + } } /*static*/ @@ -3855,7 +3884,9 @@ LLAppearanceMgr::LLAppearanceMgr(): mOutfitLocked(false), mInFlightCounter(0), mInFlightTimer(), - mIsInUpdateAppearanceFromCOF(false) + mIsInUpdateAppearanceFromCOF(false), + mOutstandingAppearanceBakeRequest(false), + mRerequestAppearanceBake(false) { LLOutfitObserver& outfit_observer = LLOutfitObserver::instance(); // unlock outfit on save operation completed diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index b97f9018c0..74024abf67 100755 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -255,6 +255,8 @@ private: bool mAttachmentInvLinkEnabled; bool mOutfitIsDirty; bool mIsInUpdateAppearanceFromCOF; // to detect recursive calls. + bool mOutstandingAppearanceBakeRequest; // A bake request is outstanding. Do not overlap. + bool mRerequestAppearanceBake; /** * Lock for blocking operations on outfit until server reply or timeout exceed From 94d1a54e33845e1488ed52961416526ed232ddb1 Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Tue, 12 Apr 2016 13:56:49 -0700 Subject: [PATCH 31/62] Shift of negative is undefined. --- indra/llkdu/llimagej2ckdu.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 6a8959517d..282c859e9e 100755 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -1034,7 +1034,7 @@ all necessary level shifting, type conversion, rounding and truncation. */ val = (kdu_int32)(sp->fval*scale16); val = (val+128)>>8; // May be faster than true rounding val += 128; - if (val & ((-1)<<8)) + if (val & ((0xffffffffU)<<8)) { val = (val < 0 ? 0 : 255); } @@ -1052,7 +1052,7 @@ all necessary level shifting, type conversion, rounding and truncation. */ val = sp->ival; val = (val+offset)>>downshift; val += 128; - if (val & ((-1)<<8)) + if (val & ((0xffffffffU)<<8)) { val = (val < 0 ? 0 : 255); } @@ -1075,7 +1075,7 @@ all necessary level shifting, type conversion, rounding and truncation. */ val += (1<<(KDU_FIX_POINT-8))>>1; val >>= (KDU_FIX_POINT-8); val += 128; - if (val & ((-1)<<8)) + if (val & ((0xffffffffU)<<8)) { val = (val < 0 ? 0 : 255); } @@ -1094,7 +1094,7 @@ all necessary level shifting, type conversion, rounding and truncation. */ val = (val+offset)>>downshift; val <<= upshift; val += 128; - if (val & ((-1)<<8)) + if (val & ((0xffffffffU)<<8)) { val = (val < 0 ? 0 : 256 - (1<ival; val = (val+offset)>>downshift; val += 128; - if (val & ((-1)<<8)) + if (val & ((0xffffffffU)<<8)) { val = (val < 0 ? 0 : 255); } @@ -1132,7 +1132,7 @@ all necessary level shifting, type conversion, rounding and truncation. */ val = sp->ival; val <<= upshift; val += 128; - if (val & ((-1)<<8)) + if (val & ((0xffffffffU)<<8)) { val = (val < 0 ? 0 : 256 - (1< Date: Tue, 12 Apr 2016 16:51:16 -0700 Subject: [PATCH 32/62] MAINT-6305: Just bumping a warning level so I can track for debugging. --- indra/newview/llvoavatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 21c38e9bc1..f11e69bae6 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -7396,7 +7396,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) if( isSelf() ) { - LL_DEBUGS("Avatar") << "this_update_cof_version " << this_update_cof_version + LL_WARNS("Avatar") << "this_update_cof_version " << this_update_cof_version << " last_update_request_cof_version " << last_update_request_cof_version << " my_cof_version " << LLAppearanceMgr::instance().getCOFVersion() << LL_ENDL; From 118e82e4775c88ace273d6012b5def8b9f19d08f Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Wed, 13 Apr 2016 22:40:49 +0100 Subject: [PATCH 33/62] MAINT-6305: Serialize the AIS calls by reducing the queue size to 1, move the bake request out of the AIS queue. --- indra/llmessage/llcoproceduremanager.cpp | 3 ++- indra/newview/app_settings/settings.xml | 2 +- indra/newview/llappearancemgr.cpp | 14 ++++++++++++++ indra/newview/llappearancemgr.h | 5 +++++ indra/newview/llvoavatar.cpp | 2 +- 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp index f0fe1ab01b..d4c0788b7d 100644 --- a/indra/llmessage/llcoproceduremanager.cpp +++ b/indra/llmessage/llcoproceduremanager.cpp @@ -36,7 +36,8 @@ static std::map DefaultPoolSizes = boost::assign::map_list_of (std::string("Upload"), 1) - (std::string("AIS"), 25); + (std::string("AIS"), 1); + // *TODO: Rider for the moment keep AIS calls serialized otherwise the COF will tend to get out of sync. #define DEFAULT_POOL_SIZE 5 diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index c4a8fe3532..07569aaaac 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -14446,7 +14446,7 @@ Type U32 Value - 25 + 1 PoolSizeUpload diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index df56d7403c..be538b3c4c 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -3359,9 +3359,14 @@ void LLAppearanceMgr::requestServerAppearanceUpdate() { if (!mOutstandingAppearanceBakeRequest) { +#ifdef APPEARANCEBAKE_AS_IN_AIS_QUEUE mRerequestAppearanceBake = false; LLCoprocedureManager::CoProcedure_t proc = boost::bind(&LLAppearanceMgr::serverAppearanceUpdateCoro, this, _1); LLCoprocedureManager::instance().enqueueCoprocedure("AIS", "LLAppearanceMgr::serverAppearanceUpdateCoro", proc); +#else + LLCoros::instance().launch("", boost::bind(&LLAppearanceMgr::serverAppearanceUpdateCoro, this)); + +#endif } else { @@ -3369,8 +3374,17 @@ void LLAppearanceMgr::requestServerAppearanceUpdate() } } +#ifdef APPEARANCEBAKE_AS_IN_AIS_QUEUE void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter) +#else +void LLAppearanceMgr::serverAppearanceUpdateCoro() +#endif { +#ifndef APPEARANCEBAKE_AS_IN_AIS_QUEUE + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter( + new LLCoreHttpUtil::HttpCoroutineAdapter("serverAppearanceUpdateCoro", LLCore::HttpRequest::DEFAULT_POLICY_ID)); +#endif + mRerequestAppearanceBake = false; if (!gAgent.getRegion()) { diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 74024abf67..bf181cb4ad 100755 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -228,7 +228,12 @@ public: private: +#ifdef APPEARANCEBAKE_AS_IN_AIS_QUEUE void serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter); +#else + void serverAppearanceUpdateCoro(); +#endif + static void debugAppearanceUpdateCOF(const LLSD& content); std::string mAppearanceServiceURL; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index f11e69bae6..21c38e9bc1 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -7396,7 +7396,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) if( isSelf() ) { - LL_WARNS("Avatar") << "this_update_cof_version " << this_update_cof_version + LL_DEBUGS("Avatar") << "this_update_cof_version " << this_update_cof_version << " last_update_request_cof_version " << last_update_request_cof_version << " my_cof_version " << LLAppearanceMgr::instance().getCOFVersion() << LL_ENDL; From 9418e8b876a5193dea2ef2d583259909e595bbfe Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Wed, 13 Apr 2016 14:45:36 -0700 Subject: [PATCH 34/62] MAINT-6305: Forgot to add the coro name. --- indra/newview/llappearancemgr.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index be538b3c4c..772c4684ca 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -3364,7 +3364,8 @@ void LLAppearanceMgr::requestServerAppearanceUpdate() LLCoprocedureManager::CoProcedure_t proc = boost::bind(&LLAppearanceMgr::serverAppearanceUpdateCoro, this, _1); LLCoprocedureManager::instance().enqueueCoprocedure("AIS", "LLAppearanceMgr::serverAppearanceUpdateCoro", proc); #else - LLCoros::instance().launch("", boost::bind(&LLAppearanceMgr::serverAppearanceUpdateCoro, this)); + LLCoros::instance().launch("serverAppearanceUpdateCoro", + boost::bind(&LLAppearanceMgr::serverAppearanceUpdateCoro, this)); #endif } From 1b6a0f64dbdf5fefbed63816f55191a04dabc1cb Mon Sep 17 00:00:00 2001 From: Ansariel Date: Thu, 14 Apr 2016 16:06:38 +0200 Subject: [PATCH 35/62] Adjust MAINT-6272 for OpenSim --- indra/newview/llinventorymodel.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 2db9cc10f6..f81c2d1380 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1773,7 +1773,10 @@ std::string LLInventoryModel::getInvCacheAddres(const LLUUID& owner_id) std::string owner_id_str; owner_id.toString(owner_id_str); std::string path(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, owner_id_str)); - if (LLGridManager::getInstance()->isInProductionGrid()) + // OpenSim fix + //if (LLGridManager::getInstance()->isInProductionGrid()) + if (LLGridManager::getInstance()->isInSLMain()) + // { inventory_addr = llformat(PRODUCTION_CACHE_FORMAT_STRING, path.c_str()); } From 09ab4b7cdd7336fa1bb8ccbeb11968fa141abcde Mon Sep 17 00:00:00 2001 From: callum_linden Date: Thu, 14 Apr 2016 11:31:07 -0700 Subject: [PATCH 36/62] maint-5711 (fix) profiles and marketplace are asking for a login each session --- indra/newview/llviewermedia.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 3e027e3d05..a7ad7c80d9 100755 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -1312,6 +1312,13 @@ void LLViewerMedia::getOpenIDCookieCoro(std::string url) if (parseRawCookie(sOpenIDCookie, cookie_name, cookie_value, cookie_path, httponly, secure) && media_instance->getMediaPlugin()) { + // MAINT-5711 - inexplicably, the CEF setCookie function will no longer set the cookie if the + // url and domain are not the same. This used to be my.sl.com and id.sl.com respectively and worked. + // For now, we use the URL for the OpenID POST request since it will have the same authority + // as the domain field. + // (Feels like there must be a less dirty way to construct a URL from component LLURL parts) + url = std::string(sOpenIDURL.mURI) + "://" + std::string(sOpenIDURL.mAuthority); + media_instance->getMediaPlugin()->setCookie(url, cookie_name, cookie_value, cookie_host, cookie_path, httponly, secure); } } From 2f964c3ef770d4ac532e26caa4fee30cb31e640c Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Thu, 14 Apr 2016 21:57:40 +0300 Subject: [PATCH 37/62] Build fix for 'undefined behavior' error --- indra/llkdu/llimagej2ckdu.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 6a8959517d..282c859e9e 100755 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -1034,7 +1034,7 @@ all necessary level shifting, type conversion, rounding and truncation. */ val = (kdu_int32)(sp->fval*scale16); val = (val+128)>>8; // May be faster than true rounding val += 128; - if (val & ((-1)<<8)) + if (val & ((0xffffffffU)<<8)) { val = (val < 0 ? 0 : 255); } @@ -1052,7 +1052,7 @@ all necessary level shifting, type conversion, rounding and truncation. */ val = sp->ival; val = (val+offset)>>downshift; val += 128; - if (val & ((-1)<<8)) + if (val & ((0xffffffffU)<<8)) { val = (val < 0 ? 0 : 255); } @@ -1075,7 +1075,7 @@ all necessary level shifting, type conversion, rounding and truncation. */ val += (1<<(KDU_FIX_POINT-8))>>1; val >>= (KDU_FIX_POINT-8); val += 128; - if (val & ((-1)<<8)) + if (val & ((0xffffffffU)<<8)) { val = (val < 0 ? 0 : 255); } @@ -1094,7 +1094,7 @@ all necessary level shifting, type conversion, rounding and truncation. */ val = (val+offset)>>downshift; val <<= upshift; val += 128; - if (val & ((-1)<<8)) + if (val & ((0xffffffffU)<<8)) { val = (val < 0 ? 0 : 256 - (1<ival; val = (val+offset)>>downshift; val += 128; - if (val & ((-1)<<8)) + if (val & ((0xffffffffU)<<8)) { val = (val < 0 ? 0 : 255); } @@ -1132,7 +1132,7 @@ all necessary level shifting, type conversion, rounding and truncation. */ val = sp->ival; val <<= upshift; val += 128; - if (val & ((-1)<<8)) + if (val & ((0xffffffffU)<<8)) { val = (val < 0 ? 0 : 256 - (1< Date: Thu, 14 Apr 2016 22:27:54 +0200 Subject: [PATCH 38/62] Sync llappearancemgr.cpp with upstream --- indra/newview/llappearancemgr.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 00463602aa..b3eb680171 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -2081,8 +2081,6 @@ void LLAppearanceMgr::filterWearableItems( } } -//void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append) -// [RLVa:KB] - Checked: 2010-03-05 (RLVa-1.2.0) void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append) { LLViewerInventoryCategory *pcat = gInventory.getCategory(category); @@ -3330,9 +3328,7 @@ void LLAppearanceMgr::updateIsDirty() if(outfit_items.size() != cof_items.size()) { - // Change log tag for easier debugging - //LL_DEBUGS("Avatar") << "item count different - base " << outfit_items.size() << " cof " << cof_items.size() << LL_ENDL; - LL_DEBUGS("Outfit") << "item count different - base " << outfit_items.size() << " cof " << cof_items.size() << LL_ENDL; + LL_DEBUGS("Avatar") << "item count different - base " << outfit_items.size() << " cof " << cof_items.size() << LL_ENDL; // Current outfit folder should have one more item than the outfit folder. // this one item is the link back to the outfit folder itself. mOutfitIsDirty = true; @@ -4122,7 +4118,7 @@ void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove, LLP return; } // [RLVa:KB] - Checked: 2013-02-12 (RLVa-1.4.8) -// LLPointer cb = NULL; +// LLPointer cb = new LLUpdateAppearanceOnDestroy; for (uuid_vec_t::const_iterator it = ids_to_remove.begin(); it != ids_to_remove.end(); ++it) { const LLUUID& id_to_remove = *it; From 88a0cda0670dd9f59bda01cb2d6062dc9d96f40f Mon Sep 17 00:00:00 2001 From: Ansariel Date: Thu, 14 Apr 2016 22:37:29 +0200 Subject: [PATCH 39/62] Protect from using illegal filename characters for inventory cache --- indra/newview/llinventorymodel.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index f81c2d1380..2adf2f1d28 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1785,7 +1785,10 @@ std::string LLInventoryModel::getInvCacheAddres(const LLUUID& owner_id) // NOTE: The inventory cache filenames now include the grid name. // Add controls against directory traversal or problematic pathname lengths // if your viewer uses grid names from an untrusted source. - const std::string& grid_id_str = LLGridManager::getInstance()->getGridId(); + // Replace illegal filename characters + //const std::string& grid_id_str = LLGridManager::getInstance()->getGridId(); + const std::string grid_id_str = LLDir::getScrubbedFileName(LLGridManager::getInstance()->getGridId()); + // const std::string& grid_id_lower = utf8str_tolower(grid_id_str); inventory_addr = llformat(GRID_CACHE_FORMAT_STRING, path.c_str(), grid_id_lower.c_str()); } From e7f03a77bfe4173cd33b5242eb27aa9469c4702c Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Mon, 18 Apr 2016 14:31:14 -0700 Subject: [PATCH 40/62] MAINT-6336: Better retry and timeout logic when logging in to the vivox server and connecting to a session. --- indra/newview/llvoicevivox.cpp | 123 +++++++++++++++++++++------------ 1 file changed, 78 insertions(+), 45 deletions(-) diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index c9661dfb11..e015d4fa5e 100755 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -80,39 +80,49 @@ extern LLMenuBarGL* gMenuBarView; extern void handle_voice_morphing_subscribe(); -const F32 VOLUME_SCALE_VIVOX = 0.01f; +namespace { + const F32 VOLUME_SCALE_VIVOX = 0.01f; -const F32 SPEAKING_TIMEOUT = 1.f; + const F32 SPEAKING_TIMEOUT = 1.f; -static const std::string VOICE_SERVER_TYPE = "Vivox"; + static const std::string VOICE_SERVER_TYPE = "Vivox"; -// Don't retry connecting to the daemon more frequently than this: -const F32 CONNECT_THROTTLE_SECONDS = 1.0f; + // Don't retry connecting to the daemon more frequently than this: + const F32 CONNECT_THROTTLE_SECONDS = 1.0f; -// Don't send positional updates more frequently than this: -const F32 UPDATE_THROTTLE_SECONDS = 0.5f; + // Don't send positional updates more frequently than this: + const F32 UPDATE_THROTTLE_SECONDS = 0.5f; -const F32 LOGIN_RETRY_SECONDS = 10.0f; -const int MAX_LOGIN_RETRIES = 12; + const F32 LOGIN_ATTEMPT_TIMEOUT = 5.0f; + const int LOGIN_RETRY_MAX = 5; + const F32 LOGIN_RETRY_TIMEOUT = 4.0f; -// Cosine of a "trivially" small angle -const F32 MINUSCULE_ANGLE_COS = 0.999f; + const int PROVISION_RETRY_MAX = 5; + const F32 PROVISION_RETRY_TIMEOUT = 2.0; -// Defines the maximum number of times(in a row) "stateJoiningSession" case for spatial channel is reached in stateMachine() -// which is treated as normal. The is the number of frames to wait for a channel join before giving up. This was changed -// from the original count of 50 for two reason. Modern PCs have higher frame rates and sometimes the SLVoice process -// backs up processing join requests. There is a log statement that records when channel joins take longer than 100 frames. -const int MAX_NORMAL_JOINING_SPATIAL_NUM = 1500; + // Cosine of a "trivially" small angle + const F32 MINUSCULE_ANGLE_COS = 0.999f; -// How often to check for expired voice fonts in seconds -const F32 VOICE_FONT_EXPIRY_INTERVAL = 10.f; -// Time of day at which Vivox expires voice font subscriptions. -// Used to replace the time portion of received expiry timestamps. -static const std::string VOICE_FONT_EXPIRY_TIME = "T05:00:00Z"; + const F32 SESSION_JOIN_TIMEOUT = 10.0f; -// Maximum length of capture buffer recordings in seconds. -const F32 CAPTURE_BUFFER_MAX_TIME = 10.f; + // Defines the maximum number of times(in a row) "stateJoiningSession" case for spatial channel is reached in stateMachine() + // which is treated as normal. The is the number of frames to wait for a channel join before giving up. This was changed + // from the original count of 50 for two reason. Modern PCs have higher frame rates and sometimes the SLVoice process + // backs up processing join requests. There is a log statement that records when channel joins take longer than 100 frames. + const int MAX_NORMAL_JOINING_SPATIAL_NUM = 1500; + // How often to check for expired voice fonts in seconds + const F32 VOICE_FONT_EXPIRY_INTERVAL = 10.f; + // Time of day at which Vivox expires voice font subscriptions. + // Used to replace the time portion of received expiry timestamps. + static const std::string VOICE_FONT_EXPIRY_TIME = "T05:00:00Z"; + + // Maximum length of capture buffer recordings in seconds. + const F32 CAPTURE_BUFFER_MAX_TIME = 10.f; + + const int ERROR_VIVOX_OBJECT_NOT_FOUND = 1001; + const int ERROR_VIVOX_NOT_LOGGED_IN = 1007; +} static int scale_mic_volume(float volume) { @@ -129,8 +139,6 @@ static int scale_speaker_volume(float volume) } -const int ERROR_VIVOX_OBJECT_NOT_FOUND = 1001; -const int ERROR_VIVOX_NOT_LOGGED_IN = 1007; /////////////////////////////////////////////////////////////////////////////////////////////// @@ -546,7 +554,7 @@ void LLVivoxVoiceClient::voiceControlCoro() // if we hit this and mRelogRequested is true, that indicates // that we attempted to relog into Vivox and were rejected. // Rather than just quit out of voice, we will tear it down (above) - // and then reconstruct the voice connecino from scratch. + // and then reconstruct the voice connecion from scratch. if (mRelogRequested) { while (isGatewayRunning()) @@ -784,13 +792,15 @@ bool LLVivoxVoiceClient::provisionVoiceAccount() if (status == LLCore::HttpStatus(404)) { - if (++retryCount > 5) + if (++retryCount > PROVISION_RETRY_MAX) { - LL_WARNS("Voice") << "Could not access voice provision cap after 5 attempts." << LL_ENDL; + LL_WARNS("Voice") << "Could not access voice provision cap after " << PROVISION_RETRY_MAX << " attempts." << LL_ENDL; return false; } - LL_WARNS("Voice") << "Provision CAP 404. Retrying in 1.0" << LL_ENDL; - llcoro::suspendUntilTimeout(1.0); + + F32 timeout = pow(PROVISION_RETRY_TIMEOUT, static_cast(retryCount)); + LL_WARNS("Voice") << "Provision CAP 404. Retrying in " << timeout << " seconds." << LL_ENDL; + llcoro::suspendUntilTimeout(timeout); continue; } @@ -888,21 +898,29 @@ bool LLVivoxVoiceClient::breakVoiceConnection(bool corowait) bool LLVivoxVoiceClient::loginToVivox() { - int loginRetryCount(0); LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump"); + LLSD timeoutResult; + timeoutResult["login"] = LLSD::String("timeout"); + + LLEventTimeout voicePumpTimeout(voicePump); + + int loginRetryCount(0); + bool response_ok(false); bool account_login(false); bool send_login(true); do { + mIsLoggingIn = true; if (send_login) loginSendMessage(); send_login = false; + voicePumpTimeout.eventAfter(LOGIN_ATTEMPT_TIMEOUT, timeoutResult); LLSD result = llcoro::suspendUntilEventOn(voicePump); LL_DEBUGS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL; @@ -910,16 +928,16 @@ bool LLVivoxVoiceClient::loginToVivox() { std::string loginresp = result["login"]; - if (loginresp == "retry") + if ((loginresp == "retry") || (loginresp == "timeout")) { - if (!loginRetryCount) + if ((!loginRetryCount) && (loginresp != "timeout")) { // on first retry notify user notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LOGIN_RETRY); } - if ((++loginRetryCount > MAX_LOGIN_RETRIES) || (!result["login_retry"])) + if ((++loginRetryCount > LOGIN_RETRY_MAX) || (loginresp == "timeout")) { - LL_WARNS("Voice") << "too many login retries, giving up." << LL_ENDL; + LL_WARNS("Voice") << "too many login retries or timeout connecting, giving up." << LL_ENDL; LLSD args; std::stringstream errs; errs << mVoiceAccountServerURI << "\n:UDP: 3478, 3479, 5060, 5062, 12000-17000"; @@ -942,8 +960,10 @@ bool LLVivoxVoiceClient::loginToVivox() account_login = false; send_login = true; - LL_INFOS("Voice") << "will retry login in " << LOGIN_RETRY_SECONDS << " seconds." << LL_ENDL; - llcoro::suspendUntilTimeout(LOGIN_RETRY_SECONDS); + F32 timeout = pow(LOGIN_RETRY_TIMEOUT, static_cast(loginRetryCount)) - 1.0f; + + LL_INFOS("Voice") << "will retry login in " << timeout << " seconds." << LL_ENDL; + llcoro::suspendUntilTimeout(timeout); } else if (loginresp == "failed") { @@ -982,7 +1002,6 @@ bool LLVivoxVoiceClient::loginToVivox() void LLVivoxVoiceClient::logoutOfVivox(bool wait) { - LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump"); if (!mIsLoggedIn) return; @@ -995,7 +1014,14 @@ void LLVivoxVoiceClient::logoutOfVivox(bool wait) if (wait) { - LLSD result = llcoro::suspendUntilEventOn(voicePump); + LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump"); + LLSD timeoutResult; + timeoutResult["logout"] = LLSD::String("timeout"); + + LLEventTimeout voicePumpTimeout(voicePump); + + voicePumpTimeout.eventAfter(LOGIN_ATTEMPT_TIMEOUT, timeoutResult); + LLSD result = llcoro::suspendUntilEventOn(voicePumpTimeout); LL_DEBUGS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL; @@ -1194,13 +1220,20 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession) bool added(true); bool joined(false); + LLSD timeoutResult; + timeoutResult["session"] = LLSD::String("timeout"); + + LLEventTimeout voicePumpTimeout(voicePump); + + // It appears that I need to wait for BOTH the SessionGroup.AddSession response and the SessionStateChangeEvent with state 4 // before continuing from this state. They can happen in either order, and if I don't wait for both, things can get stuck. // For now, the SessionGroup.AddSession response handler sets mSessionHandle and the SessionStateChangeEvent handler transitions to stateSessionJoined. // This is a cheap way to make sure both have happened before proceeding. do { - result = llcoro::suspendUntilEventOn(voicePump); + voicePumpTimeout.eventAfter(SESSION_JOIN_TIMEOUT, timeoutResult); + result = llcoro::suspendUntilEventOn(voicePumpTimeout); LL_DEBUGS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL; if (result.has("session")) @@ -1219,10 +1252,10 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession) added = true; else if (message == "joined") joined = true; - else if ((message == "failed") || (message == "removed")) + else if ((message == "failed") || (message == "removed") || (message == "timeout")) { // we will get a removed message if a voice call is declined. - if (message == "failed") + if (message == "failed") { int reason = result["reason"].asInteger(); LL_WARNS("Voice") << "Add and join failed for reason " << reason << LL_ENDL; @@ -1638,8 +1671,8 @@ int LLVivoxVoiceClient::voiceRecordBuffer() LLSD result; captureBufferRecordStartSendMessage(); - notifyVoiceFontObservers(); + do { result = llcoro::suspendUntilEventOn(voicePump); @@ -1667,11 +1700,11 @@ int LLVivoxVoiceClient::voicePlaybackBuffer() LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump"); LLEventTimeout timeout(voicePump); - timeout.eventAfter(CAPTURE_BUFFER_MAX_TIME, timeoutResult); LLSD result; do { + timeout.eventAfter(CAPTURE_BUFFER_MAX_TIME, timeoutResult); captureBufferPlayStartSendMessage(mPreviewVoiceFont); // Store the voice font being previewed, so that we know to restart if it changes. @@ -1682,7 +1715,7 @@ int LLVivoxVoiceClient::voicePlaybackBuffer() // Update UI, should really use a separate callback. notifyVoiceFontObservers(); - result = llcoro::suspendUntilEventOn(voicePump); + result = llcoro::suspendUntilEventOn(timeout); LL_DEBUGS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL; } while (!result.has("recplay")); From 86a3e1a3dc59c964d78c509e99a59d52eea32b34 Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Tue, 19 Apr 2016 14:10:57 -0700 Subject: [PATCH 41/62] MAINT-6336: Crasher on disconnect in DDoS. --- indra/newview/llvoicevivox.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index e015d4fa5e..518b5bdc65 100755 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -1223,15 +1223,14 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession) LLSD timeoutResult; timeoutResult["session"] = LLSD::String("timeout"); - LLEventTimeout voicePumpTimeout(voicePump); - - // It appears that I need to wait for BOTH the SessionGroup.AddSession response and the SessionStateChangeEvent with state 4 // before continuing from this state. They can happen in either order, and if I don't wait for both, things can get stuck. // For now, the SessionGroup.AddSession response handler sets mSessionHandle and the SessionStateChangeEvent handler transitions to stateSessionJoined. // This is a cheap way to make sure both have happened before proceeding. do { + LLEventTimeout voicePumpTimeout(voicePump); + voicePumpTimeout.eventAfter(SESSION_JOIN_TIMEOUT, timeoutResult); result = llcoro::suspendUntilEventOn(voicePumpTimeout); From 16e06b4b50af3f4f4e3c91f8db1e4f59a44d8422 Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Tue, 19 Apr 2016 14:17:28 -0700 Subject: [PATCH 42/62] MAINT-6336: more loging for test build. --- indra/newview/llvoicevivox.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 518b5bdc65..17e538fcfa 100755 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -1161,6 +1161,8 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession) // The old session may now need to be deleted. reapSession(oldSession); + LL_INFOS("Voice") << "Done reap test." << LL_ENDL; + if (!mAudioSession->mHandle.empty()) { // Connect to a session by session handle @@ -1175,6 +1177,7 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession) notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_JOINING); + LL_INFOS("Voice") << "suspend after notify STATUS_JOINING." << LL_ENDL; llcoro::suspend(); LLSD result; @@ -1195,6 +1198,7 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession) if (!mVoiceEnabled && mIsInitialized) { + LL_INFOS("Voice") << "Voice no longer enabled. Exiting." << LL_ENDL; mIsJoiningSession = false; // User bailed out during connect -- jump straight to teardown. terminateAudioSession(true); @@ -1203,6 +1207,7 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession) } else if (mSessionTerminateRequested) { + LL_INFOS("Voice") << "Terminate requested" << LL_ENDL; if (mAudioSession && !mAudioSession->mHandle.empty()) { // Only allow direct exits from this state in p2p calls (for cancelling an invite). @@ -1229,12 +1234,13 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession) // This is a cheap way to make sure both have happened before proceeding. do { + LL_INFOS("Voice") << "Top of add join loop." << LL_ENDL; LLEventTimeout voicePumpTimeout(voicePump); voicePumpTimeout.eventAfter(SESSION_JOIN_TIMEOUT, timeoutResult); result = llcoro::suspendUntilEventOn(voicePumpTimeout); - LL_DEBUGS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL; + LL_INFOS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL; if (result.has("session")) { if (result.has("handle")) @@ -1275,6 +1281,9 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession) } } while (!added || !joined); + + LL_INFOS("Voice") << "Left voice loop." << LL_ENDL; + mIsJoiningSession = false; if (mSpatialJoiningNum > 100) From d96004e4af162a6338029db8ea2bbc914c072c19 Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Wed, 20 Apr 2016 10:21:35 -0700 Subject: [PATCH 43/62] MAINT-6336: Crasher showing up in voice was a Bound Listener that should have been a Temp Bound listener. --- indra/llcommon/lleventfilter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/llcommon/lleventfilter.h b/indra/llcommon/lleventfilter.h index e822a664f5..8e01326823 100755 --- a/indra/llcommon/lleventfilter.h +++ b/indra/llcommon/lleventfilter.h @@ -181,7 +181,7 @@ protected: private: bool tick(const LLSD&); - LLBoundListener mMainloop; + LLTempBoundListener mMainloop; Action mAction; }; From c2c0c537bbf9edcbfcfa54a98c74745e5fff695a Mon Sep 17 00:00:00 2001 From: Cinder Date: Wed, 20 Apr 2016 16:13:17 -0600 Subject: [PATCH 44/62] STORM-2127 - Fix NSException when assigning values that don't exist in cocoa modifier key event. --- indra/llwindow/llopenglview-objc.mm | 119 ++++++++++++++------------- indra/llwindow/llwindowmacosx-objc.h | 14 ++-- 2 files changed, 68 insertions(+), 65 deletions(-) diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index 406bc9cf47..8a77c645ce 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -25,13 +25,69 @@ */ #import "llopenglview-objc.h" -#include "llwindowmacosx-objc.h" +#import "llwindowmacosx-objc.h" #import "llappdelegate-objc.h" +#pragma mark local functions +NativeKeyEventData extractKeyDataFromKeyEvent(NSEvent* theEvent) +{ + NativeKeyEventData eventData; + eventData.mKeyEvent = NativeKeyEventData::KEYUNKNOWN; + eventData.mEventType = [theEvent type]; + eventData.mEventModifiers = [theEvent modifierFlags]; + eventData.mEventKeyCode = [theEvent keyCode]; + NSString *strEventChars = [theEvent characters]; + eventData.mEventChars = (strEventChars.length) ? [strEventChars characterAtIndex:0] : 0; + NSString *strEventUChars = [theEvent charactersIgnoringModifiers]; + eventData.mEventUnmodChars = (strEventUChars.length) ? [strEventUChars characterAtIndex:0] : 0; + eventData.mEventRepeat = [theEvent isARepeat]; + return eventData; +} +NativeKeyEventData extractKeyDataFromModifierEvent(NSEvent* theEvent) +{ + NativeKeyEventData eventData; + eventData.mKeyEvent = NativeKeyEventData::KEYUNKNOWN; + eventData.mEventType = [theEvent type]; + eventData.mEventModifiers = [theEvent modifierFlags]; + eventData.mEventKeyCode = [theEvent keyCode]; + return eventData; +} -//--------------------------- +attributedStringInfo getSegments(NSAttributedString *str) +{ + attributedStringInfo segments; + segment_lengths seg_lengths; + segment_standouts seg_standouts; + NSRange effectiveRange; + NSRange limitRange = NSMakeRange(0, [str length]); + + while (limitRange.length > 0) { + NSNumber *attr = [str attribute:NSUnderlineStyleAttributeName atIndex:limitRange.location longestEffectiveRange:&effectiveRange inRange:limitRange]; + limitRange = NSMakeRange(NSMaxRange(effectiveRange), NSMaxRange(limitRange) - NSMaxRange(effectiveRange)); + + if (effectiveRange.length <= 0) + { + effectiveRange.length = 1; + } + + if ([attr integerValue] == 2) + { + seg_lengths.push_back(effectiveRange.length); + seg_standouts.push_back(true); + } else + { + seg_lengths.push_back(effectiveRange.length); + seg_standouts.push_back(false); + } + } + segments.seg_lengths = seg_lengths; + segments.seg_standouts = seg_standouts; + return segments; +} + +#pragma mark class implementations @implementation NSScreen (PointConversion) @@ -63,53 +119,6 @@ @end -void extractKeyDataFromEvent (NSEvent *theEvent, NativeKeyEventData * eventData) -{ - eventData->mKeyEvent = NativeKeyEventData::KEYUNKNOWN; - eventData->mEventType = [theEvent type]; - eventData->mEventModifiers = [theEvent modifierFlags]; - eventData->mEventKeyCode = [theEvent keyCode]; - NSString *strEventChars = [theEvent characters]; - eventData->mEventChars = (strEventChars.length) ? [strEventChars characterAtIndex:0] : 0; - NSString *strEventUChars = [theEvent charactersIgnoringModifiers]; - eventData->mEventUnmodChars = (strEventUChars.length) ? [strEventUChars characterAtIndex:0] : 0; - eventData->mEventRepeat = [theEvent isARepeat]; - -} - - -attributedStringInfo getSegments(NSAttributedString *str) -{ - attributedStringInfo segments; - segment_lengths seg_lengths; - segment_standouts seg_standouts; - NSRange effectiveRange; - NSRange limitRange = NSMakeRange(0, [str length]); - - while (limitRange.length > 0) { - NSNumber *attr = [str attribute:NSUnderlineStyleAttributeName atIndex:limitRange.location longestEffectiveRange:&effectiveRange inRange:limitRange]; - limitRange = NSMakeRange(NSMaxRange(effectiveRange), NSMaxRange(limitRange) - NSMaxRange(effectiveRange)); - - if (effectiveRange.length <= 0) - { - effectiveRange.length = 1; - } - - if ([attr integerValue] == 2) - { - seg_lengths.push_back(effectiveRange.length); - seg_standouts.push_back(true); - } else - { - seg_lengths.push_back(effectiveRange.length); - seg_standouts.push_back(false); - } - } - segments.seg_lengths = seg_lengths; - segments.seg_standouts = seg_standouts; - return segments; -} - @implementation LLOpenGLView // Force a high quality update after live resizing @@ -423,18 +432,14 @@ attributedStringInfo getSegments(NSAttributedString *str) - (void) keyUp:(NSEvent *)theEvent { - NativeKeyEventData eventData; - - extractKeyDataFromEvent( theEvent, &eventData ); + NativeKeyEventData eventData = extractKeyDataFromKeyEvent(theEvent); eventData.mKeyEvent = NativeKeyEventData::KEYUP; callKeyUp(&eventData, [theEvent keyCode], [theEvent modifierFlags]); } - (void) keyDown:(NSEvent *)theEvent { - NativeKeyEventData eventData; - - extractKeyDataFromEvent( theEvent, &eventData ); + NativeKeyEventData eventData = extractKeyDataFromKeyEvent(theEvent); eventData.mKeyEvent = NativeKeyEventData::KEYDOWN; uint keycode = [theEvent keyCode]; @@ -472,9 +477,7 @@ attributedStringInfo getSegments(NSAttributedString *str) - (void)flagsChanged:(NSEvent *)theEvent { - NativeKeyEventData eventData; - - extractKeyDataFromEvent( theEvent, &eventData ); + NativeKeyEventData eventData = extractKeyDataFromModifierEvent(theEvent); mModifiers = [theEvent modifierFlags]; callModifier([theEvent modifierFlags]); diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h index dc184b91fb..3f55aa587e 100755 --- a/indra/llwindow/llwindowmacosx-objc.h +++ b/indra/llwindow/llwindowmacosx-objc.h @@ -55,13 +55,13 @@ struct NativeKeyEventData { KEYCHAR }; - EventType mKeyEvent; - uint32_t mEventType; - uint32_t mEventModifiers; - uint32_t mEventKeyCode; - uint32_t mEventChars; - uint32_t mEventUnmodChars; - bool mEventRepeat; + EventType mKeyEvent = KEYUNKNOWN; + uint32_t mEventType = 0; + uint32_t mEventModifiers = 0; + uint32_t mEventKeyCode = 0; + uint32_t mEventChars = 0; + uint32_t mEventUnmodChars = 0; + bool mEventRepeat = false; }; typedef const NativeKeyEventData * NSKeyEventRef; From a07897bf9c8377a0557c9baed2f0debff949bc16 Mon Sep 17 00:00:00 2001 From: Cinder Biscuits Date: Thu, 21 Apr 2016 01:27:52 +0000 Subject: [PATCH 45/62] contributions.txt edited online with Bitbucket --- doc/contributions.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/contributions.txt b/doc/contributions.txt index 00f70d7ca4..3d8da14029 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -331,6 +331,7 @@ Cinder Roxley STORM-2037 STORM-2053 STORM-2113 + STORM-2127 Clara Young Coaldust Numbers VWR-1095 From 8f4be8bb869e3cde034607cbe0cb8272005f08b8 Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Thu, 21 Apr 2016 09:16:50 -0700 Subject: [PATCH 46/62] MAINT-6336: Removed or demoted some of the chatty log messages I was using to track progress. --- indra/newview/llvoicevivox.cpp | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 17e538fcfa..ca0509c524 100755 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -1161,8 +1161,6 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession) // The old session may now need to be deleted. reapSession(oldSession); - LL_INFOS("Voice") << "Done reap test." << LL_ENDL; - if (!mAudioSession->mHandle.empty()) { // Connect to a session by session handle @@ -1177,7 +1175,6 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession) notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_JOINING); - LL_INFOS("Voice") << "suspend after notify STATUS_JOINING." << LL_ENDL; llcoro::suspend(); LLSD result; @@ -1198,7 +1195,7 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession) if (!mVoiceEnabled && mIsInitialized) { - LL_INFOS("Voice") << "Voice no longer enabled. Exiting." << LL_ENDL; + LL_DEBUGS("Voice") << "Voice no longer enabled. Exiting." << LL_ENDL; mIsJoiningSession = false; // User bailed out during connect -- jump straight to teardown. terminateAudioSession(true); @@ -1207,7 +1204,7 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession) } else if (mSessionTerminateRequested) { - LL_INFOS("Voice") << "Terminate requested" << LL_ENDL; + LL_DEBUGS("Voice") << "Terminate requested" << LL_ENDL; if (mAudioSession && !mAudioSession->mHandle.empty()) { // Only allow direct exits from this state in p2p calls (for cancelling an invite). @@ -1234,13 +1231,12 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession) // This is a cheap way to make sure both have happened before proceeding. do { - LL_INFOS("Voice") << "Top of add join loop." << LL_ENDL; LLEventTimeout voicePumpTimeout(voicePump); voicePumpTimeout.eventAfter(SESSION_JOIN_TIMEOUT, timeoutResult); result = llcoro::suspendUntilEventOn(voicePumpTimeout); - LL_INFOS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL; + LL_DEBUGS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL; if (result.has("session")) { if (result.has("handle")) @@ -1268,7 +1264,7 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession) if ((reason == ERROR_VIVOX_NOT_LOGGED_IN) || (reason == ERROR_VIVOX_OBJECT_NOT_FOUND)) { - LL_INFOS("Voice") << "Requesting reprovision and login." << LL_ENDL; + LL_DEBUGS("Voice") << "Requesting reprovision and login." << LL_ENDL; requestRelog(); } @@ -1281,9 +1277,6 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession) } } while (!added || !joined); - - LL_INFOS("Voice") << "Left voice loop." << LL_ENDL; - mIsJoiningSession = false; if (mSpatialJoiningNum > 100) From 899489ae0a4bc4eb187e7813e338b937384a1866 Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Fri, 22 Apr 2016 12:07:27 -0700 Subject: [PATCH 47/62] MAINT-6336: Centralize waiting on event pump with a timeout. Shorten the lifespan of a timeout event pump lifespan to be no longer than necessary. Change all references to the LLEventTimer to instead uses the centralized version. --- indra/llcommon/lleventcoro.cpp | 9 +++++++++ indra/llcommon/lleventcoro.h | 2 ++ indra/llcommon/lleventfilter.cpp | 4 ++-- indra/llcommon/lleventfilter.h | 3 +++ indra/newview/llvoicevivox.cpp | 32 ++++++++++---------------------- 5 files changed, 26 insertions(+), 24 deletions(-) diff --git a/indra/llcommon/lleventcoro.cpp b/indra/llcommon/lleventcoro.cpp index 578a2b62c8..44291eb711 100755 --- a/indra/llcommon/lleventcoro.cpp +++ b/indra/llcommon/lleventcoro.cpp @@ -229,6 +229,15 @@ LLSD llcoro::postAndSuspend(const LLSD& event, const LLEventPumpOrPumpName& requ return value; } +LLSD llcoro::suspendUntilEventOnWithTimeout(const LLEventPumpOrPumpName& pump, F32 timeoutin, const LLSD &timeoutResult) +{ + LLEventTimeout timeoutPump(pump); + + timeoutPump.eventAfter(timeoutin, timeoutResult); + return llcoro::suspendUntilEventOn(timeoutPump); + +} + namespace { diff --git a/indra/llcommon/lleventcoro.h b/indra/llcommon/lleventcoro.h index 2105faf861..19c68e1f35 100755 --- a/indra/llcommon/lleventcoro.h +++ b/indra/llcommon/lleventcoro.h @@ -147,6 +147,8 @@ LLSD suspendUntilEventOn(const LLEventPumpOrPumpName& pump) return postAndSuspend(LLSD(), LLEventPumpOrPumpName(), pump); } +LLSD suspendUntilEventOnWithTimeout(const LLEventPumpOrPumpName& pump, F32 timeoutin, const LLSD &timeoutResult); + } // namespace llcoro /// return type for two-pump variant of suspendUntilEventOn() diff --git a/indra/llcommon/lleventfilter.cpp b/indra/llcommon/lleventfilter.cpp index d36a107254..64ab58adcd 100755 --- a/indra/llcommon/lleventfilter.cpp +++ b/indra/llcommon/lleventfilter.cpp @@ -39,9 +39,9 @@ #include "llsdutil.h" // llsd_matches() LLEventFilter::LLEventFilter(LLEventPump& source, const std::string& name, bool tweak): - LLEventStream(name, tweak) + LLEventStream(name, tweak), + mSource(source.listen(getName(), boost::bind(&LLEventFilter::post, this, _1))) { - source.listen(getName(), boost::bind(&LLEventFilter::post, this, _1)); } LLEventMatching::LLEventMatching(const LLSD& pattern): diff --git a/indra/llcommon/lleventfilter.h b/indra/llcommon/lleventfilter.h index 8e01326823..15bac5fd73 100755 --- a/indra/llcommon/lleventfilter.h +++ b/indra/llcommon/lleventfilter.h @@ -49,6 +49,9 @@ public: /// Post an event to all listeners virtual bool post(const LLSD& event) = 0; + +private: + LLTempBoundListener mSource; }; /** diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index ca0509c524..043ddc904b 100755 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -903,8 +903,6 @@ bool LLVivoxVoiceClient::loginToVivox() LLSD timeoutResult; timeoutResult["login"] = LLSD::String("timeout"); - LLEventTimeout voicePumpTimeout(voicePump); - int loginRetryCount(0); bool response_ok(false); @@ -920,8 +918,7 @@ bool LLVivoxVoiceClient::loginToVivox() send_login = false; - voicePumpTimeout.eventAfter(LOGIN_ATTEMPT_TIMEOUT, timeoutResult); - LLSD result = llcoro::suspendUntilEventOn(voicePump); + LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGIN_ATTEMPT_TIMEOUT, timeoutResult); LL_DEBUGS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL; if (result.has("login")) @@ -1018,10 +1015,7 @@ void LLVivoxVoiceClient::logoutOfVivox(bool wait) LLSD timeoutResult; timeoutResult["logout"] = LLSD::String("timeout"); - LLEventTimeout voicePumpTimeout(voicePump); - - voicePumpTimeout.eventAfter(LOGIN_ATTEMPT_TIMEOUT, timeoutResult); - LLSD result = llcoro::suspendUntilEventOn(voicePumpTimeout); + LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGIN_ATTEMPT_TIMEOUT, timeoutResult); LL_DEBUGS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL; @@ -1231,12 +1225,9 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession) // This is a cheap way to make sure both have happened before proceeding. do { - LLEventTimeout voicePumpTimeout(voicePump); + result = llcoro::suspendUntilEventOnWithTimeout(voicePump, SESSION_JOIN_TIMEOUT, timeoutResult); - voicePumpTimeout.eventAfter(SESSION_JOIN_TIMEOUT, timeoutResult); - result = llcoro::suspendUntilEventOn(voicePumpTimeout); - - LL_DEBUGS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL; + LL_INFOS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL; if (result.has("session")) { if (result.has("handle")) @@ -1249,6 +1240,9 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession) } std::string message = result["session"].asString(); +// if (message == "joined") +// message = "removed"; + if ((message == "added") || (message == "created")) added = true; else if (message == "joined") @@ -1510,7 +1504,6 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session) timeoutEvent["timeout"] = LLSD::Boolean(true); LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump"); - LLEventTimeout timeout(voicePump); mIsInChannel = true; mMuteMicDirty = true; @@ -1562,8 +1555,7 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session) sendLocalAudioUpdates(); mIsInitialized = true; - timeout.eventAfter(UPDATE_THROTTLE_SECONDS, timeoutEvent); - LLSD result = llcoro::suspendUntilEventOn(timeout); + LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, UPDATE_THROTTLE_SECONDS, timeoutEvent); if (!result.has("timeout")) // logging the timeout event spams the log LL_DEBUGS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL; if (result.has("session")) @@ -1667,8 +1659,6 @@ int LLVivoxVoiceClient::voiceRecordBuffer() LL_INFOS("Voice") << "Recording voice buffer" << LL_ENDL; LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump"); - LLEventTimeout timeout(voicePump); - timeout.eventAfter(CAPTURE_BUFFER_MAX_TIME, timeoutResult); LLSD result; captureBufferRecordStartSendMessage(); @@ -1676,7 +1666,7 @@ int LLVivoxVoiceClient::voiceRecordBuffer() do { - result = llcoro::suspendUntilEventOn(voicePump); + result = llcoro::suspendUntilEventOnWithTimeout(voicePump, CAPTURE_BUFFER_MAX_TIME, timeoutResult); LL_DEBUGS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL; } while (!result.has("recplay")); @@ -1700,12 +1690,10 @@ int LLVivoxVoiceClient::voicePlaybackBuffer() LL_INFOS("Voice") << "Playing voice buffer" << LL_ENDL; LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump"); - LLEventTimeout timeout(voicePump); LLSD result; do { - timeout.eventAfter(CAPTURE_BUFFER_MAX_TIME, timeoutResult); captureBufferPlayStartSendMessage(mPreviewVoiceFont); // Store the voice font being previewed, so that we know to restart if it changes. @@ -1716,7 +1704,7 @@ int LLVivoxVoiceClient::voicePlaybackBuffer() // Update UI, should really use a separate callback. notifyVoiceFontObservers(); - result = llcoro::suspendUntilEventOn(timeout); + result = llcoro::suspendUntilEventOnWithTimeout(voicePump, CAPTURE_BUFFER_MAX_TIME, timeoutResult); LL_DEBUGS("Voice") << "event=" << ll_pretty_print_sd(result) << LL_ENDL; } while (!result.has("recplay")); From 1fa27575113a552ded77bf9f19989c77b677bb7f Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Fri, 22 Apr 2016 15:14:30 -0700 Subject: [PATCH 48/62] Debug code snuck in. --- indra/newview/llvoicevivox.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 043ddc904b..4316db115e 100755 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -1240,8 +1240,6 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession) } std::string message = result["session"].asString(); -// if (message == "joined") -// message = "removed"; if ((message == "added") || (message == "created")) added = true; From 4d9dd3271b1a015d9afd21767e579a4cd71982ed Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Mon, 25 Apr 2016 12:06:33 -0700 Subject: [PATCH 49/62] MAINT-6338: Add methods for getting and setting boolean properties from gSavedSettings in the HTTPCore. Use those methods to access new key HTTPLogBodyOnError. Dump body of HTTP message to log in case of error if this key is true. --- indra/llmessage/llcorehttputil.cpp | 38 ++++++++++++++++++++++++++---- indra/llmessage/llcorehttputil.h | 9 ++++++- indra/newview/llappcorehttp.cpp | 5 ++++ 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp index 9a23ede81b..7742cbc182 100644 --- a/indra/llmessage/llcorehttputil.cpp +++ b/indra/llmessage/llcorehttputil.cpp @@ -41,14 +41,41 @@ #include "message.h" // for getting the port -using namespace LLCore; +using namespace LLCore; namespace LLCoreHttpUtil { const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f; +namespace +{ + const std::string HTTP_LOGBODY_KEY("HTTPLogBodyOnError"); + + BoolSettingQuery_t mBoolSettingGet; + BoolSettingUpdate_t mBoolSettingPut; + + inline bool getBoolSetting(const std::string &keyname) + { + if (!mBoolSettingGet || mBoolSettingGet.empty()) + return(false); + return mBoolSettingGet(HTTP_LOGBODY_KEY); + } + +} + +void setPropertyMethods(BoolSettingQuery_t queryfn, BoolSettingUpdate_t updatefn) +{ + mBoolSettingGet = queryfn; + mBoolSettingPut = updatefn; + + if (mBoolSettingPut && !mBoolSettingPut.empty()) + { + mBoolSettingPut(HTTP_LOGBODY_KEY, false, "Log the entire HTTP body in the case of an HTTP error."); + } +} + void logMessageSuccess(std::string logAuth, std::string url, std::string message) { @@ -293,10 +320,11 @@ void HttpCoroHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespons bas >> std::noskipws; bodyData.assign(std::istream_iterator(bas), std::istream_iterator()); httpStatus["error_body"] = LLSD(bodyData); -#if 1 - // commenting out, but keeping since this can be useful for debugging - LL_WARNS() << "Returned body=" << std::endl << httpStatus["error_body"].asString() << LL_ENDL; -#endif + if (getBoolSetting(HTTP_LOGBODY_KEY)) + { + // commenting out, but keeping since this can be useful for debugging + LL_WARNS() << "Returned body=" << std::endl << httpStatus["error_body"].asString() << LL_ENDL; + } } mReplyPump.post(result); diff --git a/indra/llmessage/llcorehttputil.h b/indra/llmessage/llcorehttputil.h index d21f5ff45c..6f0b865f83 100644 --- a/indra/llmessage/llcorehttputil.h +++ b/indra/llmessage/llcorehttputil.h @@ -57,7 +57,14 @@ /// namespace LLCoreHttpUtil { - extern const F32 HTTP_REQUEST_EXPIRY_SECS; +/// Allow access to to the property settings methods. +typedef boost::function BoolSettingQuery_t; +typedef boost::function BoolSettingUpdate_t; + +void setPropertyMethods(BoolSettingQuery_t queryfn, BoolSettingUpdate_t updatefn); + + +extern const F32 HTTP_REQUEST_EXPIRY_SECS; /// Attempt to convert a response object's contents to LLSD. /// It is expected that the response body will be of non-zero diff --git a/indra/newview/llappcorehttp.cpp b/indra/newview/llappcorehttp.cpp index 7dee309a62..49291ea564 100755 --- a/indra/newview/llappcorehttp.cpp +++ b/indra/newview/llappcorehttp.cpp @@ -36,6 +36,8 @@ #include "llsecapi.h" #include +#include "llcorehttputil.h" + // Here is where we begin to get our connection usage under control. // This establishes llcorehttp policy classes that, among other // things, limit the maximum number of connections to outside @@ -138,6 +140,9 @@ LLAppCoreHttp::~LLAppCoreHttp() void LLAppCoreHttp::init() { + LLCoreHttpUtil::setPropertyMethods( + boost::bind(&LLControlGroup::getBOOL, boost::ref(gSavedSettings), _1), + boost::bind(&LLControlGroup::declareBOOL, boost::ref(gSavedSettings), _1, _2, _3, LLControlVariable::PERSIST_NONDFT)); LLCore::LLHttp::initialize(); From dd2311b993d137c538ca57b4360669db6d7fbfa0 Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Tue, 26 Apr 2016 11:56:25 -0700 Subject: [PATCH 50/62] MAINT-6336: Put the timeout upstream of the suspending pump and fire the timeout it. Also some cleanup on LLSD construction in vivox. --- indra/llcommon/lleventcoro.cpp | 21 ++++++++-- indra/llcommon/lleventcoro.h | 5 ++- indra/llcommon/lleventfilter.h | 14 ++++++- indra/llcommon/llevents.h | 6 +++ indra/newview/llvoicevivox.cpp | 77 +++++++++++----------------------- 5 files changed, 65 insertions(+), 58 deletions(-) diff --git a/indra/llcommon/lleventcoro.cpp b/indra/llcommon/lleventcoro.cpp index 44291eb711..c8c43dc334 100755 --- a/indra/llcommon/lleventcoro.cpp +++ b/indra/llcommon/lleventcoro.cpp @@ -229,13 +229,26 @@ LLSD llcoro::postAndSuspend(const LLSD& event, const LLEventPumpOrPumpName& requ return value; } -LLSD llcoro::suspendUntilEventOnWithTimeout(const LLEventPumpOrPumpName& pump, F32 timeoutin, const LLSD &timeoutResult) +LLSD llcoro::suspendUntilEventOnWithTimeout(const LLEventPumpOrPumpName& suspendPumpOrName, + F32 timeoutin, const LLSD &timeoutResult) { - LLEventTimeout timeoutPump(pump); + /** + * The timeout pump is attached upstream of of the waiting pump and will + * pass the timeout event through it. We CAN NOT attach downstream since + * doing so will cause the suspendPump to fire any waiting events immediately + * and they will be lost. This becomes especially problematic with the + * LLEventTimeout(pump) constructor which will also attempt to fire those + * events using the virtual listen_impl method in the not yet fully constructed + * timeoutPump. + */ + LLEventTimeout timeoutPump; + LLEventPump &suspendPump = suspendPumpOrName.getPump(); + + LLTempBoundListener timeoutListener = timeoutPump.listen(suspendPump.getName(), + boost::bind(&LLEventPump::post, &suspendPump, _1)); timeoutPump.eventAfter(timeoutin, timeoutResult); - return llcoro::suspendUntilEventOn(timeoutPump); - + return llcoro::suspendUntilEventOn(suspendPump); } namespace diff --git a/indra/llcommon/lleventcoro.h b/indra/llcommon/lleventcoro.h index 19c68e1f35..87926c692d 100755 --- a/indra/llcommon/lleventcoro.h +++ b/indra/llcommon/lleventcoro.h @@ -147,7 +147,10 @@ LLSD suspendUntilEventOn(const LLEventPumpOrPumpName& pump) return postAndSuspend(LLSD(), LLEventPumpOrPumpName(), pump); } -LLSD suspendUntilEventOnWithTimeout(const LLEventPumpOrPumpName& pump, F32 timeoutin, const LLSD &timeoutResult); +/// Suspend the coroutine until an event is fired on the identified pump +/// or the timeout duration has elapsed. If the timeout duration +/// elapses the specified LLSD is returned. +LLSD suspendUntilEventOnWithTimeout(const LLEventPumpOrPumpName& suspendPumpOrName, F32 timeoutin, const LLSD &timeoutResult); } // namespace llcoro diff --git a/indra/llcommon/lleventfilter.h b/indra/llcommon/lleventfilter.h index 15bac5fd73..66f3c14869 100755 --- a/indra/llcommon/lleventfilter.h +++ b/indra/llcommon/lleventfilter.h @@ -188,7 +188,19 @@ private: Action mAction; }; -/// Production implementation of LLEventTimoutBase +/** + * Production implementation of LLEventTimoutBase. + * + * @NOTE: Caution should be taken when using the LLEventTimeout(LLEventPump &) + * constructor to ensure that the upstream event pump is not an LLEventMaildrop + * or any other kind of store and forward pump which may have events outstanding. + * Using this constructor will cause the upstream event pump to fire any pending + * events and could result in the invocation of a virtual method before the timeout + * has been fully constructed. The timeout should instead be connected upstream + * from the event pump and attached using the listen method. + * See llcoro::suspendUntilEventOnWithTimeout() for an example. + */ + class LL_COMMON_API LLEventTimeout: public LLEventTimeoutBase { public: diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h index 6175329a9d..ba4fcd766e 100755 --- a/indra/llcommon/llevents.h +++ b/indra/llcommon/llevents.h @@ -616,6 +616,12 @@ public: * a queue. Subsequent attaching listeners will receive stored events from the queue * until a listener indicates that the event has been handled. In order to receive * multiple events from a mail drop the listener must disconnect and reconnect. + * + * @NOTE: When using an LLEventMailDrop (or LLEventQueue) with a LLEventTimeout or + * LLEventFilter attaching the filter downstream using Timeout's constructor will + * cause the MailDrop to discharge any of it's stored events. The timeout should + * instead be connected upstream using its listen() method. + * See llcoro::suspendUntilEventOnWithTimeout() for an example. */ class LL_COMMON_API LLEventMailDrop : public LLEventStream { diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 043ddc904b..2654666993 100755 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -900,8 +900,7 @@ bool LLVivoxVoiceClient::loginToVivox() { LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump"); - LLSD timeoutResult; - timeoutResult["login"] = LLSD::String("timeout"); + LLSD timeoutResult(LLSDMap("login", "timeout")); int loginRetryCount(0); @@ -1012,8 +1011,7 @@ void LLVivoxVoiceClient::logoutOfVivox(bool wait) if (wait) { LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump"); - LLSD timeoutResult; - timeoutResult["logout"] = LLSD::String("timeout"); + LLSD timeoutResult(LLSDMap("lougout", "timeout")); LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGIN_ATTEMPT_TIMEOUT, timeoutResult); @@ -1216,8 +1214,7 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession) bool added(true); bool joined(false); - LLSD timeoutResult; - timeoutResult["session"] = LLSD::String("timeout"); + LLSD timeoutResult(LLSDMap("session", "timeout")); // It appears that I need to wait for BOTH the SessionGroup.AddSession response and the SessionStateChangeEvent with state 4 // before continuing from this state. They can happen in either order, and if I don't wait for both, things can get stuck. @@ -1500,8 +1497,7 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session) notifyParticipantObservers(); notifyVoiceFontObservers(); - LLSD timeoutEvent = LLSD::emptyMap(); - timeoutEvent["timeout"] = LLSD::Boolean(true); + LLSD timeoutEvent(LLSDMap("timeout", LLSD::Boolean(true))); LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump"); mIsInChannel = true; @@ -1653,8 +1649,7 @@ void LLVivoxVoiceClient::recordingAndPlaybackMode() int LLVivoxVoiceClient::voiceRecordBuffer() { - LLSD timeoutResult; - timeoutResult["recplay"] = LLSD::String("stop"); + LLSD timeoutResult(LLSDMap("recplay", "stop")); LL_INFOS("Voice") << "Recording voice buffer" << LL_ENDL; @@ -1684,8 +1679,7 @@ int LLVivoxVoiceClient::voiceRecordBuffer() int LLVivoxVoiceClient::voicePlaybackBuffer() { - LLSD timeoutResult; - timeoutResult["recplay"] = LLSD::String("stop"); + LLSD timeoutResult(LLSDMap("recplay", "stop")); LL_INFOS("Voice") << "Playing voice buffer" << LL_ENDL; @@ -2924,11 +2918,9 @@ void LLVivoxVoiceClient::sessionCreateResponse(std::string &requestId, int statu session->mErrorStatusString = statusString; if(session == mAudioSession) { - LLSD vivoxevent = LLSD::emptyMap(); - - vivoxevent["handle"] = LLSD::String(sessionHandle); - vivoxevent["session"] = LLSD::String("failed"); - vivoxevent["reason"] = LLSD::Integer(statusCode); + LLSD vivoxevent(LLSDMap("handle", LLSD::String(sessionHandle)) + ("session", "failed") + ("reason", LLSD::Integer(statusCode))); LLEventPumps::instance().post("vivoxClientPump", vivoxevent); } @@ -2945,10 +2937,8 @@ void LLVivoxVoiceClient::sessionCreateResponse(std::string &requestId, int statu { setSessionHandle(session, sessionHandle); } - LLSD vivoxevent = LLSD::emptyMap(); - - vivoxevent["handle"] = LLSD::String(sessionHandle); - vivoxevent["session"] = LLSD::String("created"); + LLSD vivoxevent(LLSDMap("handle", LLSD::String(sessionHandle)) + ("session", "created")); LLEventPumps::instance().post("vivoxClientPump", vivoxevent); } @@ -2972,10 +2962,8 @@ void LLVivoxVoiceClient::sessionGroupAddSessionResponse(std::string &requestId, session->mErrorStatusString = statusString; if(session == mAudioSession) { - LLSD vivoxevent = LLSD::emptyMap(); - - vivoxevent["handle"] = LLSD::String(sessionHandle); - vivoxevent["session"] = LLSD::String("failed"); + LLSD vivoxevent(LLSDMap("handle", LLSD::String(sessionHandle)) + ("session", "failed")); LLEventPumps::instance().post("vivoxClientPump", vivoxevent); } @@ -2993,10 +2981,8 @@ void LLVivoxVoiceClient::sessionGroupAddSessionResponse(std::string &requestId, setSessionHandle(session, sessionHandle); } - LLSD vivoxevent = LLSD::emptyMap(); - - vivoxevent["handle"] = LLSD::String(sessionHandle); - vivoxevent["session"] = LLSD::String("added"); + LLSD vivoxevent(LLSDMap("handle", LLSD::String(sessionHandle)) + ("session", "added")); LLEventPumps::instance().post("vivoxClientPump", vivoxevent); @@ -3041,9 +3027,7 @@ void LLVivoxVoiceClient::logoutResponse(int statusCode, std::string &statusStrin LL_WARNS("Voice") << "Account.Logout response failure: " << statusString << LL_ENDL; // Should this ever fail? do we care if it does? } - LLSD vivoxevent = LLSD::emptyMap(); - - vivoxevent["logout"] = LLSD::Boolean(true); + LLSD vivoxevent(LLSDMap("logout", LLSD::Boolean(true))); LLEventPumps::instance().post("vivoxClientPump", vivoxevent); } @@ -3058,9 +3042,7 @@ void LLVivoxVoiceClient::connectorShutdownResponse(int statusCode, std::string & mConnected = false; - LLSD vivoxevent = LLSD::emptyMap(); - - vivoxevent["connector"] = LLSD::Boolean(false); + LLSD vivoxevent(LLSDMap("connector", LLSD::Boolean(false))); LLEventPumps::instance().post("vivoxClientPump", vivoxevent); } @@ -3168,10 +3150,8 @@ void LLVivoxVoiceClient::joinedAudioSession(const sessionStatePtr_t &session) // This is the session we're joining. if(mIsJoiningSession) { - LLSD vivoxevent = LLSD::emptyMap(); - - vivoxevent["handle"] = LLSD::String(session->mHandle); - vivoxevent["session"] = LLSD::String("joined"); + LLSD vivoxevent(LLSDMap("handle", LLSD::String(session->mHandle)) + ("session", "joined")); LLEventPumps::instance().post("vivoxClientPump", vivoxevent); @@ -3314,10 +3294,8 @@ void LLVivoxVoiceClient::leftAudioSession(const sessionStatePtr_t &session) { if (mAudioSession == session) { - LLSD vivoxevent = LLSD::emptyMap(); - - vivoxevent["handle"] = LLSD::String(session->mHandle); - vivoxevent["session"] = LLSD::String("removed"); + LLSD vivoxevent(LLSDMap("handle", LLSD::String(session->mHandle)) + ("session", "removed")); LLEventPumps::instance().post("vivoxClientPump", vivoxevent); } @@ -6172,9 +6150,7 @@ void LLVivoxVoiceClient::accountGetSessionFontsResponse(int statusCode, const st { // *TODO: We seem to get multiple events of this type. Should figure a way to advance only after // receiving the last one. - LLSD result = LLSD::emptyMap(); - - result["voice_fonts"] = LLSD::Boolean(true); + LLSD result(LLSDMap("voice_fonts", LLSD::Boolean(true))); LLEventPumps::instance().post("vivoxClientPump", result); } @@ -6347,8 +6323,7 @@ void LLVivoxVoiceClient::recordPreviewBuffer() mCaptureBufferRecording = true; - LLSD result; - result["recplay"] = "record"; + LLSD result(LLSDMap("recplay", "record")); LLEventPumps::instance().post("vivoxClientPump", result); } @@ -6371,8 +6346,7 @@ void LLVivoxVoiceClient::playPreviewBuffer(const LLUUID& effect_id) mPreviewVoiceFont = effect_id; mCaptureBufferPlaying = true; - LLSD result; - result["recplay"] = "playback"; + LLSD result(LLSDMap("recplay", "playback")); LLEventPumps::instance().post("vivoxClientPump", result); } @@ -6381,8 +6355,7 @@ void LLVivoxVoiceClient::stopPreviewBuffer() mCaptureBufferRecording = false; mCaptureBufferPlaying = false; - LLSD result; - result["recplay"] = "quit"; + LLSD result(LLSDMap("recplay", "quit")); LLEventPumps::instance().post("vivoxClientPump", result); } From 66dd72459ae5ad17bfab622c71b2122233707dd4 Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Tue, 26 Apr 2016 13:44:44 -0700 Subject: [PATCH 51/62] MAINT-6336: Initialize TempBoundListener with constructor --- indra/llcommon/lleventcoro.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/llcommon/lleventcoro.cpp b/indra/llcommon/lleventcoro.cpp index c8c43dc334..2d5f964deb 100755 --- a/indra/llcommon/lleventcoro.cpp +++ b/indra/llcommon/lleventcoro.cpp @@ -244,8 +244,8 @@ LLSD llcoro::suspendUntilEventOnWithTimeout(const LLEventPumpOrPumpName& suspend LLEventTimeout timeoutPump; LLEventPump &suspendPump = suspendPumpOrName.getPump(); - LLTempBoundListener timeoutListener = timeoutPump.listen(suspendPump.getName(), - boost::bind(&LLEventPump::post, &suspendPump, _1)); + LLTempBoundListener timeoutListener(timeoutPump.listen(suspendPump.getName(), + boost::bind(&LLEventPump::post, &suspendPump, _1))); timeoutPump.eventAfter(timeoutin, timeoutResult); return llcoro::suspendUntilEventOn(suspendPump); From 8124810406585d3fa3209c36a15673043e67b580 Mon Sep 17 00:00:00 2001 From: Kadah_Coba Date: Mon, 2 May 2016 21:54:58 -0700 Subject: [PATCH 52/62] FIRE-18247: Reset chat log location to default when set folder is non-existent --- indra/newview/llstartup.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index f9e3ee4c72..c5305bebed 100755 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1324,6 +1324,13 @@ bool idle_startup() { gDirUtilp->setChatLogsDir(gSavedPerAccountSettings.getString("InstantMessageLogPath")); } + // FIRE-18247: Handle non-existent chat log location + if (!gDirUtilp->fileExists(gSavedPerAccountSettings.getString("InstantMessageLogPath"))) + { + gDirUtilp->setChatLogsDir(gDirUtilp->getOSUserAppDir()); + gSavedPerAccountSettings.setString("InstantMessageLogPath", gDirUtilp->getChatLogsDir()); + } + // // Seperate user directories per grid on OS build #ifdef OPENSIM gDirUtilp->setPerAccountChatLogsDir(userid, gridlabel); From dea7baedb4fa9d51c53cdb9072c8855cffe07a56 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Tue, 3 May 2016 09:17:58 +0200 Subject: [PATCH 53/62] FIRE-18234: Japanese translation update by Hiroshi Kumaki --- .../default/xui/ja/floater_fs_im_session.xml | 7 + .../xui/ja/floater_fs_money_tracker.xml | 3 + .../default/xui/ja/floater_fs_nearby_chat.xml | 5 +- .../xui/ja/floater_notifications_tabbed.xml | 49 +++++++ .../skins/default/xui/ja/floater_tools.xml | 2 + .../default/xui/ja/menu_conversation.xml | 1 + .../default/xui/ja/menu_fs_chat_options.xml | 21 +++ .../default/xui/ja/menu_fs_im_teleport.xml | 5 + .../skins/default/xui/ja/menu_fs_radar.xml | 13 ++ .../skins/default/xui/ja/menu_viewer.xml | 5 +- .../skins/default/xui/ja/notifications.xml | 136 +++++++++++++++++- .../xui/ja/panel_notification_list_item.xml | 114 +++++++++++++++ .../default/xui/ja/panel_preferences_UI.xml | 12 +- .../xui/ja/panel_preferences_backup.xml | 12 +- .../default/xui/ja/panel_preferences_chat.xml | 7 +- .../xui/ja/panel_preferences_firestorm.xml | 4 + .../xui/ja/panel_preferences_general.xml | 2 + .../default/xui/ja/panel_preferences_move.xml | 2 + .../xui/ja/panel_preferences_privacy.xml | 7 +- .../xui/ja/panel_preferences_setup.xml | 4 +- .../xui/ja/panel_preferences_skins.xml | 1 + .../default/xui/ja/panel_tools_texture.xml | 10 +- .../newview/skins/default/xui/ja/strings.xml | 52 ++++++- 23 files changed, 458 insertions(+), 16 deletions(-) create mode 100644 indra/newview/skins/default/xui/ja/floater_notifications_tabbed.xml create mode 100644 indra/newview/skins/default/xui/ja/menu_fs_chat_options.xml create mode 100644 indra/newview/skins/default/xui/ja/menu_fs_im_teleport.xml create mode 100644 indra/newview/skins/default/xui/ja/panel_notification_list_item.xml diff --git a/indra/newview/skins/default/xui/ja/floater_fs_im_session.xml b/indra/newview/skins/default/xui/ja/floater_fs_im_session.xml index c5707fa684..8838230d11 100644 --- a/indra/newview/skins/default/xui/ja/floater_fs_im_session.xml +++ b/indra/newview/skins/default/xui/ja/floater_fs_im_session.xml @@ -55,6 +55,10 @@