diff options
67 files changed, 1011 insertions, 575 deletions
diff --git a/autobuild.xml b/autobuild.xml index bb7cc27233..8166a44525 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -800,9 +800,9 @@ <key>archive</key> <map> <key>hash</key> - <string>d5528538e67c710387ae0c061a90cb23</string> + <string>c36808a58384a52672d81593de61f7ff</string> <key>url</key> - <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/76868/730756/fmodstudio-2.01.07.555883-darwin64-555883.tar.bz2</string> + <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/89681/818422/fmodstudio-2.02.03.565082-darwin64-565082.tar.bz2</string> </map> <key>name</key> <string>darwin64</string> @@ -812,9 +812,9 @@ <key>archive</key> <map> <key>hash</key> - <string>5283050c22d31877cd9e0afbe6feb9fc</string> + <string>24b86630ccdfb5b3221f90ca7a9704f6</string> <key>url</key> - <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/65398/612630/fmodstudio-2.00.11.546392-linux-546392.tar.bz2</string> + <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/89682/818423/fmodstudio-2.02.03.565082-linux-565082.tar.bz2</string> </map> <key>name</key> <string>linux</string> @@ -824,9 +824,9 @@ <key>archive</key> <map> <key>hash</key> - <string>5a3c78f4a77ae6477986e33836725e8b</string> + <string>24b86630ccdfb5b3221f90ca7a9704f6</string> <key>url</key> - <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/65399/612631/fmodstudio-2.00.11.546392-linux64-546392.tar.bz2</string> + <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/89682/818423/fmodstudio-2.02.03.565082-linux-565082.tar.bz2</string> </map> <key>name</key> <string>linux64</string> @@ -836,9 +836,9 @@ <key>archive</key> <map> <key>hash</key> - <string>a2bb6eaf51f933993b26a5fe7503a761</string> + <string>96853d91ce4da14e14ea322122629551</string> <key>url</key> - <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/76869/730763/fmodstudio-2.01.07.555883-windows-555883.tar.bz2</string> + <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/89683/818438/fmodstudio-2.02.03.565082-windows-565082.tar.bz2</string> </map> <key>name</key> <string>windows</string> @@ -848,16 +848,16 @@ <key>archive</key> <map> <key>hash</key> - <string>138d07dd516a9ad5b9787192fe6134dd</string> + <string>58d0cc28a1d90bacefbda48fcd8d379c</string> <key>url</key> - <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/76867/730751/fmodstudio-2.01.07.555883-windows64-555883.tar.bz2</string> + <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/89684/818439/fmodstudio-2.02.03.565082-windows64-565082.tar.bz2</string> </map> <key>name</key> <string>windows64</string> </map> </map> <key>version</key> - <string>2.01.07.555883</string> + <string>2.02.03.565082</string> </map> <key>fontconfig</key> <map> diff --git a/indra/cmake/GLOD.cmake b/indra/cmake/GLOD.cmake index a347eb6fee..6f42b44ab8 100644 --- a/indra/cmake/GLOD.cmake +++ b/indra/cmake/GLOD.cmake @@ -5,5 +5,7 @@ if (NOT USESYSTEMLIBS) use_prebuilt_binary(glod) endif (NOT USESYSTEMLIBS) +set(GLODLIB ON CACHE BOOL "Using GLOD library") + set(GLOD_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include) set(GLOD_LIBRARIES GLOD) diff --git a/indra/llaudio/llstreamingaudio_fmodstudio.cpp b/indra/llaudio/llstreamingaudio_fmodstudio.cpp index 08d19209aa..1ad29a3f59 100644 --- a/indra/llaudio/llstreamingaudio_fmodstudio.cpp +++ b/indra/llaudio/llstreamingaudio_fmodstudio.cpp @@ -63,7 +63,8 @@ LLStreamingAudio_FMODSTUDIO::LLStreamingAudio_FMODSTUDIO(FMOD::System *system) : mSystem(system), mCurrentInternetStreamp(NULL), mFMODInternetStreamChannelp(NULL), -mGain(1.0f) +mGain(1.0f), +mRetryCount(0) { // Number of milliseconds of audio to buffer for the audio card. // Must be larger than the usual Second Life frame stutter time. @@ -83,9 +84,64 @@ mGain(1.0f) LLStreamingAudio_FMODSTUDIO::~LLStreamingAudio_FMODSTUDIO() { - // nothing interesting/safe to do. + if (mCurrentInternetStreamp) + { + // Isn't supposed to hapen, stream should be clear by now, + // and if it does, we are likely going to crash. + LL_WARNS("FMOD") << "mCurrentInternetStreamp not null on shutdown!" << LL_ENDL; + stop(); + } + + // Kill dead internet streams, if possible + killDeadStreams(); + + if (!mDeadStreams.empty()) + { + // LLStreamingAudio_FMODSTUDIO was inited on startup + // and should be destroyed on shutdown, it should + // wait for streams to die to not cause crashes or + // leaks. + // Ideally we need to wait on some kind of callback + // to release() streams correctly, but 200 ms should + // be enough and we can't wait forever. + LL_INFOS("FMOD") << "Waiting for " << (S32)mDeadStreams.size() << " streams to stop" << LL_ENDL; + for (S32 i = 0; i < 20; i++) + { + const U32 ms_delay = 10; + ms_sleep(ms_delay); // rude, but not many options here + killDeadStreams(); + if (mDeadStreams.empty()) + { + LL_INFOS("FMOD") << "All streams stopped after " << (S32)((i + 1) * ms_delay) << "ms" << LL_ENDL; + break; + } + } + } + + if (!mDeadStreams.empty()) + { + LL_WARNS("FMOD") << "Failed to kill some audio streams" << LL_ENDL; + } } +void LLStreamingAudio_FMODSTUDIO::killDeadStreams() +{ + std::list<LLAudioStreamManagerFMODSTUDIO *>::iterator iter; + for (iter = mDeadStreams.begin(); iter != mDeadStreams.end();) + { + LLAudioStreamManagerFMODSTUDIO *streamp = *iter; + if (streamp->stopStream()) + { + LL_INFOS("FMOD") << "Closed dead stream" << LL_ENDL; + delete streamp; + mDeadStreams.erase(iter++); + } + else + { + iter++; + } + } +} void LLStreamingAudio_FMODSTUDIO::start(const std::string& url) { @@ -100,36 +156,24 @@ void LLStreamingAudio_FMODSTUDIO::start(const std::string& url) if (!url.empty()) { - LL_INFOS() << "Starting internet stream: " << url << LL_ENDL; + LL_INFOS("FMOD") << "Starting internet stream: " << url << LL_ENDL; mCurrentInternetStreamp = new LLAudioStreamManagerFMODSTUDIO(mSystem, url); mURL = url; } else { - LL_INFOS() << "Set internet stream to null" << LL_ENDL; + LL_INFOS("FMOD") << "Set internet stream to null" << LL_ENDL; mURL.clear(); } + + mRetryCount = 0; } void LLStreamingAudio_FMODSTUDIO::update() { // Kill dead internet streams, if possible - std::list<LLAudioStreamManagerFMODSTUDIO *>::iterator iter; - for (iter = mDeadStreams.begin(); iter != mDeadStreams.end();) - { - LLAudioStreamManagerFMODSTUDIO *streamp = *iter; - if (streamp->stopStream()) - { - LL_INFOS() << "Closed dead stream" << LL_ENDL; - delete streamp; - mDeadStreams.erase(iter++); - } - else - { - iter++; - } - } + killDeadStreams(); // Don't do anything if there are no streams playing if (!mCurrentInternetStreamp) @@ -154,10 +198,33 @@ void LLStreamingAudio_FMODSTUDIO::update() setGain(getGain()); mFMODInternetStreamChannelp->setPaused(false); } + mRetryCount = 0; } else if (open_state == FMOD_OPENSTATE_ERROR) { - stop(); + LL_INFOS("FMOD") << "State: FMOD_OPENSTATE_ERROR" + << " Progress: " << U32(progress) + << " Starving: " << S32(starving) + << " Diskbusy: " << S32(diskbusy) << LL_ENDL; + if (mRetryCount < 2) + { + // Retry + std::string url = mURL; + stop(); // might drop mURL, drops mCurrentInternetStreamp + + mRetryCount++; + + if (!url.empty()) + { + LL_INFOS("FMOD") << "Restarting internet stream: " << url << ", attempt " << (mRetryCount + 1) << LL_ENDL; + mCurrentInternetStreamp = new LLAudioStreamManagerFMODSTUDIO(mSystem, url); + mURL = url; + } + } + else + { + stop(); + } return; } @@ -181,7 +248,7 @@ void LLStreamingAudio_FMODSTUDIO::update() { if (!strcmp(tag.name, "Sample Rate Change")) { - LL_INFOS() << "Stream forced changing sample rate to " << *((float *)tag.data) << LL_ENDL; + LL_INFOS("FMOD") << "Stream forced changing sample rate to " << *((float *)tag.data) << LL_ENDL; mFMODInternetStreamChannelp->setFrequency(*((float *)tag.data)); } continue; @@ -195,9 +262,9 @@ void LLStreamingAudio_FMODSTUDIO::update() mFMODInternetStreamChannelp->getPaused(&paused); if (!paused) { - LL_INFOS() << "Stream starvation detected! Pausing stream until buffer nearly full." << LL_ENDL; - LL_INFOS() << " (diskbusy=" << diskbusy << ")" << LL_ENDL; - LL_INFOS() << " (progress=" << progress << ")" << LL_ENDL; + LL_INFOS("FMOD") << "Stream starvation detected! Pausing stream until buffer nearly full." << LL_ENDL; + LL_INFOS("FMOD") << " (diskbusy=" << diskbusy << ")" << LL_ENDL; + LL_INFOS("FMOD") << " (progress=" << progress << ")" << LL_ENDL; mFMODInternetStreamChannelp->setPaused(true); } } @@ -220,14 +287,14 @@ void LLStreamingAudio_FMODSTUDIO::stop() if (mCurrentInternetStreamp) { - LL_INFOS() << "Stopping internet stream: " << mCurrentInternetStreamp->getURL() << LL_ENDL; + LL_INFOS("FMOD") << "Stopping internet stream: " << mCurrentInternetStreamp->getURL() << LL_ENDL; if (mCurrentInternetStreamp->stopStream()) { delete mCurrentInternetStreamp; } else { - LL_WARNS() << "Pushing stream to dead list: " << mCurrentInternetStreamp->getURL() << LL_ENDL; + LL_WARNS("FMOD") << "Pushing stream to dead list: " << mCurrentInternetStreamp->getURL() << LL_ENDL; mDeadStreams.push_back(mCurrentInternetStreamp); } mCurrentInternetStreamp = NULL; @@ -246,6 +313,7 @@ void LLStreamingAudio_FMODSTUDIO::pause(int pauseopt) { if (mCurrentInternetStreamp) { + LL_INFOS("FMOD") << "Pausing internet stream" << LL_ENDL; stop(); } } @@ -314,7 +382,7 @@ mReady(false) if (result != FMOD_OK) { - LL_WARNS() << "Couldn't open fmod stream, error " + LL_WARNS("FMOD") << "Couldn't open fmod stream, error " << FMOD_ErrorString(result) << LL_ENDL; mReady = false; @@ -329,7 +397,7 @@ FMOD::Channel *LLAudioStreamManagerFMODSTUDIO::startStream() // We need a live and opened stream before we try and play it. if (!mInternetStream || getOpenState() != FMOD_OPENSTATE_READY) { - LL_WARNS() << "No internet stream to start playing!" << LL_ENDL; + LL_WARNS("FMOD") << "No internet stream to start playing!" << LL_ENDL; return NULL; } diff --git a/indra/llaudio/llstreamingaudio_fmodstudio.h b/indra/llaudio/llstreamingaudio_fmodstudio.h index 1fc3c54d79..35a7b1226e 100644 --- a/indra/llaudio/llstreamingaudio_fmodstudio.h +++ b/indra/llaudio/llstreamingaudio_fmodstudio.h @@ -59,6 +59,8 @@ public: /*virtual*/ bool supportsAdjustableBufferSizes(){return true;} /*virtual*/ void setBufferSizes(U32 streambuffertime, U32 decodebuffertime); private: + void killDeadStreams(); + FMOD::System *mSystem; LLAudioStreamManagerFMODSTUDIO *mCurrentInternetStreamp; @@ -67,6 +69,7 @@ private: std::string mURL; F32 mGain; + S32 mRetryCount; }; diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index 75fc0fec99..c2d353b0fc 100644 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -249,14 +249,25 @@ std::string LLCoros::launch(const std::string& prefix, const callable_t& callabl // protected_fixedsize_stack sets a guard page past the end of the new // stack so that stack underflow will result in an access violation // instead of weird, subtle, possibly undiagnosed memory stomps. - boost::fibers::fiber newCoro(boost::fibers::launch::dispatch, - std::allocator_arg, - boost::fibers::protected_fixedsize_stack(mStackSize), - [this, &name, &callable](){ toplevel(name, callable); }); - // You have two choices with a fiber instance: you can join() it or you - // can detach() it. If you try to destroy the instance before doing - // either, the program silently terminates. We don't need this handle. - newCoro.detach(); + + try + { + boost::fibers::fiber newCoro(boost::fibers::launch::dispatch, + std::allocator_arg, + boost::fibers::protected_fixedsize_stack(mStackSize), + [this, &name, &callable]() { toplevel(name, callable); }); + + // You have two choices with a fiber instance: you can join() it or you + // can detach() it. If you try to destroy the instance before doing + // either, the program silently terminates. We don't need this handle. + newCoro.detach(); + } + catch (std::bad_alloc&) + { + // Out of memory on stack allocation? + LL_ERRS("LLCoros") << "Bad memory allocation in LLCoros::launch(" << prefix << ")!" << LL_ENDL; + } + return name; } diff --git a/indra/llcommon/lleventcoro.cpp b/indra/llcommon/lleventcoro.cpp index 995356dc52..067b5e6fbc 100644 --- a/indra/llcommon/lleventcoro.cpp +++ b/indra/llcommon/lleventcoro.cpp @@ -101,7 +101,7 @@ void storeToLLSDPath(LLSD& dest, const LLSD& path, const LLSD& value) } // Drill down to where we should store 'value'. - llsd::drill(dest, path) = value; + llsd::drill_ref(dest, path) = value; } } // anonymous diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp index eb3a96b133..fc10fcece3 100644 --- a/indra/llcommon/llsdutil.cpp +++ b/indra/llcommon/llsdutil.cpp @@ -29,6 +29,7 @@ #include "linden_common.h" #include "llsdutil.h" +#include <sstream> #if LL_WINDOWS # define WIN32_LEAN_AND_MEAN @@ -862,7 +863,7 @@ bool llsd_equals(const LLSD& lhs, const LLSD& rhs, int bits) namespace llsd { -LLSD& drill(LLSD& blob, const LLSD& rawPath) +LLSD& drill_ref(LLSD& blob, const LLSD& rawPath) { // Treat rawPath uniformly as an array. If it's not already an array, // store it as the only entry in one. (But let's say Undefined means an @@ -917,9 +918,9 @@ LLSD& drill(LLSD& blob, const LLSD& rawPath) LLSD drill(const LLSD& blob, const LLSD& path) { - // non-const drill() does exactly what we want. Temporarily cast away + // drill_ref() does exactly what we want. Temporarily cast away // const-ness and use that. - return drill(const_cast<LLSD&>(blob), path); + return drill_ref(const_cast<LLSD&>(blob), path); } } // namespace llsd diff --git a/indra/llcommon/llsdutil.h b/indra/llcommon/llsdutil.h index 8678ca97f2..1321615805 100644 --- a/indra/llcommon/llsdutil.h +++ b/indra/llcommon/llsdutil.h @@ -184,10 +184,10 @@ namespace llsd * - Anything else is an error. * * By implication, if path.isUndefined() or otherwise equivalent to an empty - * LLSD::Array, drill() returns 'blob' as is. + * LLSD::Array, drill[_ref]() returns 'blob' as is. */ LLSD drill(const LLSD& blob, const LLSD& path); -LLSD& drill( LLSD& blob, const LLSD& path); +LLSD& drill_ref( LLSD& blob, const LLSD& path); } diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index 2ca15a31c6..67d4ee0969 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -107,7 +107,7 @@ LLOSInfo::LLOSInfo() : #if LL_WINDOWS - if (IsWindowsVersionOrGreater(10, 0, 0)) + if (IsWindows10OrGreater()) { mMajorVer = 10; mMinorVer = 0; @@ -195,18 +195,6 @@ LLOSInfo::LLOSInfo() : GetSystemInfo(&si); //if it fails get regular system info //(Warning: If GetSystemInfo it may result in incorrect information in a WOW64 machine, if the kernel fails to load) - //msdn microsoft finds 32 bit and 64 bit flavors this way.. - //http://msdn.microsoft.com/en-us/library/ms724429(VS.85).aspx (example code that contains quite a few more flavors - //of windows than this code does (in case it is needed for the future) - if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) //check for 64 bit - { - mOSStringSimple += "64-bit "; - } - else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) - { - mOSStringSimple += "32-bit "; - } - // Try calling GetVersionEx using the OSVERSIONINFOEX structure. OSVERSIONINFOEX osvi; ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); @@ -240,7 +228,34 @@ LLOSInfo::LLOSInfo() : ubr = data; } } - } + + if (mBuild >= 22000) + { + // At release Windows 11 version was 10.0.22000.194 + // Windows 10 version was 10.0.19043.1266 + // There is no warranty that Win10 build won't increase, + // so until better solution is found or Microsoft updates + // SDK with IsWindows11OrGreater(), indicate "10/11" + // + // Current alternatives: + // Query WMI's Win32_OperatingSystem for OS string. Slow + // and likely to return 'compatibility' string. + // Check presence of dlls/libs or may be their version. + mOSStringSimple = "Microsoft Windows 10/11 "; + } + } + + //msdn microsoft finds 32 bit and 64 bit flavors this way.. + //http://msdn.microsoft.com/en-us/library/ms724429(VS.85).aspx (example code that contains quite a few more flavors + //of windows than this code does (in case it is needed for the future) + if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) //check for 64 bit + { + mOSStringSimple += "64-bit "; + } + else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) + { + mOSStringSimple += "32-bit "; + } mOSString = mOSStringSimple; if (mBuild > 0) diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index e085fa6ada..a1540840a5 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -5723,7 +5723,16 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) resizeIndices(grid_size*grid_size*6); if (!volume->isMeshAssetLoaded()) { - mEdge.resize(grid_size*grid_size * 6); + S32 size = grid_size * grid_size * 6; + try + { + mEdge.resize(size); + } + catch (std::bad_alloc&) + { + LL_WARNS("LLVOLUME") << "Resize of mEdge to " << size << " failed" << LL_ENDL; + return false; + } } U16* out = mIndices; @@ -6514,7 +6523,15 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) if (!volume->isMeshAssetLoaded()) { - mEdge.resize(num_indices); + try + { + mEdge.resize(num_indices); + } + catch (std::bad_alloc&) + { + LL_WARNS("LLVOLUME") << "Resize of mEdge to " << num_indices << " failed" << LL_ENDL; + return false; + } } } @@ -6742,7 +6759,15 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) LLVector4a* norm = mNormals; static LLAlignedArray<LLVector4a, 64> triangle_normals; - triangle_normals.resize(count); + try + { + triangle_normals.resize(count); + } + catch (std::bad_alloc&) + { + LL_WARNS("LLVOLUME") << "Resize of triangle_normals to " << count << " failed" << LL_ENDL; + return false; + } LLVector4a* output = triangle_normals.mArray; LLVector4a* end_output = output+count; diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 1badd54fca..33037b5001 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -175,6 +175,14 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) mTripleClickTimer.reset(); setText(p.default_text()); + if (p.initial_value.isProvided() + && !p.control_name.isProvided()) + { + // Initial value often is descriptive, like "Type some ID here" + // and can be longer than size limitation, ignore size + setText(p.initial_value.getValue().asString(), false); + } + // Initialize current history line iterator mCurrentHistoryLine = mLineHistory.begin(); @@ -390,6 +398,11 @@ void LLLineEditor::updateTextPadding() void LLLineEditor::setText(const LLStringExplicit &new_text) { + setText(new_text, true); +} + +void LLLineEditor::setText(const LLStringExplicit &new_text, bool use_size_limit) +{ // If new text is identical, don't copy and don't move insertion point if (mText.getString() == new_text) { @@ -407,13 +420,13 @@ void LLLineEditor::setText(const LLStringExplicit &new_text) all_selected = all_selected || (len == 0 && hasFocus() && mSelectAllonFocusReceived); std::string truncated_utf8 = new_text; - if (truncated_utf8.size() > (U32)mMaxLengthBytes) + if (use_size_limit && truncated_utf8.size() > (U32)mMaxLengthBytes) { truncated_utf8 = utf8str_truncate(new_text, mMaxLengthBytes); } mText.assign(truncated_utf8); - if (mMaxLengthChars) + if (use_size_limit && mMaxLengthChars) { mText.assign(utf8str_symbol_truncate(truncated_utf8, mMaxLengthChars)); } diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index f84625bea7..ae4e05c065 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -320,6 +320,8 @@ private: virtual S32 getPreeditFontSize() const; virtual LLWString getPreeditString() const { return getWText(); } + void setText(const LLStringExplicit &new_text, bool use_size_limit); + void setContextMenu(LLContextMenu* new_context_menu); protected: diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index cdaf03ebde..76fd789bec 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -2362,6 +2362,16 @@ void LLMenuGL::arrange( void ) (*item_iter)->setRect( rect ); } } + + + if (getTornOff()) + { + LLTearOffMenu * torn_off_menu = dynamic_cast<LLTearOffMenu*>(getParent()); + if (torn_off_menu) + { + torn_off_menu->updateSize(); + } + } } if (mKeepFixedSize) { @@ -3879,7 +3889,8 @@ void LLMenuHolderGL::setActivatedItem(LLMenuItemGL* item) /// Class LLTearOffMenu ///============================================================================ LLTearOffMenu::LLTearOffMenu(LLMenuGL* menup) : - LLFloater(LLSD()) + LLFloater(LLSD()), + mQuitRequested(false) { S32 floater_header_size = getHeaderHeight(); @@ -3894,7 +3905,7 @@ LLTearOffMenu::LLTearOffMenu(LLMenuGL* menup) : LLRect rect; menup->localRectToOtherView(LLRect(-1, menup->getRect().getHeight(), menup->getRect().getWidth() + 3, 0), &rect, gFloaterView); // make sure this floater is big enough for menu - mTargetHeight = (F32)(rect.getHeight() + floater_header_size); + mTargetHeight = rect.getHeight() + floater_header_size; reshape(rect.getWidth(), rect.getHeight()); setRect(rect); @@ -3926,19 +3937,24 @@ LLTearOffMenu::~LLTearOffMenu() void LLTearOffMenu::draw() { mMenu->setBackgroundVisible(isBackgroundOpaque()); - mMenu->needsArrange(); if (getRect().getHeight() != mTargetHeight) { // animate towards target height - reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), mTargetHeight, LLSmoothInterpolation::getInterpolant(0.05f)))); + reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), (F32)mTargetHeight, LLSmoothInterpolation::getInterpolant(0.05f)))); + mMenu->needsArrange(); } LLFloater::draw(); } void LLTearOffMenu::onFocusReceived() { - // if nothing is highlighted, just highlight first item + if (mQuitRequested) + { + return; + } + + // if nothing is highlighted, just highlight first item if (!mMenu->getHighlightedItem()) { mMenu->highlightNextItem(NULL); @@ -4014,6 +4030,31 @@ LLTearOffMenu* LLTearOffMenu::create(LLMenuGL* menup) return tearoffp; } +void LLTearOffMenu::updateSize() +{ + if (mMenu) + { + S32 floater_header_size = getHeaderHeight(); + const LLRect &floater_rect = getRect(); + LLRect new_rect; + mMenu->localRectToOtherView(LLRect(-1, mMenu->getRect().getHeight() + floater_header_size, mMenu->getRect().getWidth() + 3, 0), &new_rect, gFloaterView); + + if (floater_rect.getWidth() != new_rect.getWidth() + || mTargetHeight != new_rect.getHeight()) + { + // make sure this floater is big enough for menu + mTargetHeight = new_rect.getHeight(); + reshape(new_rect.getWidth(), mTargetHeight); + + // Restore menu position + LLRect menu_rect = mMenu->getRect(); + menu_rect.setOriginAndSize(1, 1, + menu_rect.getWidth(), menu_rect.getHeight()); + mMenu->setRect(menu_rect); + } + } +} + void LLTearOffMenu::closeTearOff() { removeChild(mMenu); @@ -4024,6 +4065,7 @@ void LLTearOffMenu::closeTearOff() mMenu->setVisible(FALSE); mMenu->setTornOff(FALSE); mMenu->setDropShadowed(TRUE); + mQuitRequested = true; } LLContextMenuBranch::LLContextMenuBranch(const LLContextMenuBranch::Params& p) diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 273bd789c4..abbfd9a24a 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -873,6 +873,8 @@ public: virtual BOOL handleKeyHere(KEY key, MASK mask); virtual void translate(S32 x, S32 y); + void updateSize(); + private: LLTearOffMenu(LLMenuGL* menup); @@ -880,7 +882,8 @@ private: LLView* mOldParent; LLMenuGL* mMenu; - F32 mTargetHeight; + S32 mTargetHeight; + bool mQuitRequested; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 38495e1e0b..1547a4ba5c 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -1017,6 +1017,24 @@ std::string LLUrlEntryObjectIM::getLocation(const std::string &url) const return LLUrlEntryBase::getLocation(url); } +// +// LLUrlEntryChat Describes a Second Life chat Url, e.g., +// secondlife:///app/chat/42/This%20Is%20a%20test +// + +LLUrlEntryChat::LLUrlEntryChat() +{ + mPattern = boost::regex("secondlife:///app/chat/\\d+/\\S+", + boost::regex::perl|boost::regex::icase); + mMenuName = "menu_url_slapp.xml"; + mTooltip = LLTrans::getString("TooltipSLAPP"); +} + +std::string LLUrlEntryChat::getLabel(const std::string &url, const LLUrlLabelCallback &cb) +{ + return unescapeUrl(url); +} + // LLUrlEntryParcel statics. LLUUID LLUrlEntryParcel::sAgentID(LLUUID::null); LLUUID LLUrlEntryParcel::sSessionID(LLUUID::null); diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 102e0a4fd9..63a1506731 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -370,6 +370,17 @@ public: private: }; +// +// LLUrlEntryChat Describes a Second Life chat Url, e.g., +// secondlife:///app/chat/42/This%20Is%20a%20test +// +class LLUrlEntryChat : public LLUrlEntryBase +{ +public: + LLUrlEntryChat(); + /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); +}; + /// /// LLUrlEntryParcel Describes a Second Life parcel Url, e.g., /// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index bfcd970529..c9d7013a11 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -63,6 +63,7 @@ LLUrlRegistry::LLUrlRegistry() // LLUrlEntryAgent*Name must appear before LLUrlEntryAgent since // LLUrlEntryAgent is a less specific (catchall for agent urls) registerUrl(new LLUrlEntryAgent()); + registerUrl(new LLUrlEntryChat()); registerUrl(new LLUrlEntryGroup()); registerUrl(new LLUrlEntryParcel()); registerUrl(new LLUrlEntryTeleport()); @@ -71,7 +72,6 @@ LLUrlRegistry::LLUrlRegistry() registerUrl(new LLUrlEntryObjectIM()); registerUrl(new LLUrlEntryPlace()); registerUrl(new LLUrlEntryInventory()); - registerUrl(new LLUrlEntryObjectIM()); registerUrl(new LLUrlEntryExperienceProfile()); //LLUrlEntrySL and LLUrlEntrySLLabel have more common pattern, //so it should be registered in the end of list diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index b2b123f0da..1d6b14e3a0 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -4260,7 +4260,8 @@ BOOL LLWindowWin32::handleImeRequests(WPARAM request, LPARAM param, LRESULT *res S32 context_offset; LLWString context = find_context(wtext, preedit, preedit_length, &context_offset); preedit -= context_offset; - if (preedit_length) + preedit_length = llmin(preedit_length, (S32)context.length() - preedit); + if (preedit_length && preedit >= 0) { // IMR_DOCUMENTFEED may be called when we have an active preedit. // We should pass the context string *excluding* the preedit string. diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 5a06106de3..6e648485fd 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1751,6 +1751,10 @@ endif (HAVOK OR HAVOK_TPV) # progress view disables/enables icons based on available packages set_source_files_properties(llprogressview.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}") +if (GLODLIB) + set_source_files_properties(llfloatermodelpreview.cpp PROPERTIES COMPILE_FLAGS "-DLL_GLOD") +endif (GLODLIB) + list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES}) set_source_files_properties(${viewer_HEADER_FILES} @@ -1918,9 +1922,7 @@ if (WINDOWS) add_dependencies(${VIEWER_BINARY_NAME} copy_win_scripts) endif (EXISTS ${CMAKE_SOURCE_DIR}/copy_win_scripts) - add_dependencies(${VIEWER_BINARY_NAME} - SLPlugin - ) + add_dependencies(${VIEWER_BINARY_NAME} SLPlugin) # sets the 'working directory' for debugging from visual studio. # Condition for version can be moved to requirements once build agents will be updated (see TOOL-3865) @@ -2270,7 +2272,7 @@ endif (INSTALL) # Note that the conventional VIEWER_SYMBOL_FILE is set by ../../build.sh if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIEWER_SYMBOL_FILE) - if (BUGSPLAT_DB) + if (USE_BUGSPLAT) # BugSplat symbol-file generation if (WINDOWS) # Just pack up a tarball containing only the .pdb file for the @@ -2354,7 +2356,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE if (LINUX) # TBD endif (LINUX) - endif (BUGSPLAT_DB) + endif (USE_BUGSPLAT) # for both Bugsplat and Breakpad add_dependencies(llpackage generate_symbols) diff --git a/indra/newview/app_settings/key_bindings.xml b/indra/newview/app_settings/key_bindings.xml index 4f6deb1f98..55babc88bc 100644 --- a/indra/newview/app_settings/key_bindings.xml +++ b/indra/newview/app_settings/key_bindings.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<keys> +<keys xml_version="1"> <first_person> <binding key="A" mask="NONE" command="slide_left"/> <binding key="D" mask="NONE" command="slide_right"/> @@ -17,22 +17,13 @@ <binding key="PGDN" mask="NONE" command="push_down"/> <binding key="HOME" mask="NONE" command="toggle_fly"/> - <binding key="PAD_LEFT" mask="NONE" command="slide_left"/> - <binding key="PAD_RIGHT" mask="NONE" command="slide_right"/> - <binding key="PAD_UP" mask="NONE" command="push_forward"/> - <binding key="PAD_DOWN" mask="NONE" command="push_backward"/> - <binding key="PAD_PGUP" mask="NONE" command="jump"/> - <binding key="PAD_PGDN" mask="NONE" command="push_down"/> - <binding key="PAD_HOME" mask="NONE" command="toggle_fly"/> - <binding key="PAD_CENTER" mask="NONE" command="stop_moving"/> - <binding key="PAD_ENTER" mask="NONE" command="start_chat"/> - <binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/> - <binding key="SPACE" mask="NONE" command="stop_moving"/> <binding key="ENTER" mask="NONE" command="start_chat"/> <binding key="DIVIDE" mask="NONE" command="start_gesture"/> <binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/> + + <binding key="" mask="NONE" mouse="LMB" command="script_trigger_lbutton"/> </first_person> <third_person> <binding key="A" mask="NONE" command="turn_left"/> @@ -60,19 +51,6 @@ <binding key="PGDN" mask="NONE" command="push_down"/> <binding key="HOME" mask="NONE" command="toggle_fly"/> - <binding key="PAD_LEFT" mask="NONE" command="turn_left"/> - <binding key="PAD_LEFT" mask="SHIFT" command="slide_left"/> - <binding key="PAD_RIGHT" mask="NONE" command="turn_right"/> - <binding key="PAD_RIGHT" mask="SHIFT" command="slide_right"/> - <binding key="PAD_UP" mask="NONE" command="push_forward"/> - <binding key="PAD_DOWN" mask="NONE" command="push_backward"/> - <binding key="PAD_PGUP" mask="NONE" command="jump"/> - <binding key="PAD_PGDN" mask="NONE" command="push_down"/> - <binding key="PAD_HOME" mask="NONE" command="toggle_fly"/> - <binding key="PAD_CENTER" mask="NONE" command="stop_moving"/> - <binding key="PAD_ENTER" mask="NONE" command="start_chat"/> - <binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/> - <!--Camera controls in third person on Alt--> <binding key="LEFT" mask="ALT" command="spin_around_cw"/> <binding key="RIGHT" mask="ALT" command="spin_around_ccw"/> @@ -88,15 +66,6 @@ <binding key="E" mask="ALT" command="spin_over"/> <binding key="C" mask="ALT" command="spin_under"/> - <binding key="PAD_LEFT" mask="ALT" command="spin_around_cw"/> - <binding key="PAD_RIGHT" mask="ALT" command="spin_around_ccw"/> - <binding key="PAD_UP" mask="ALT" command="move_forward"/> - <binding key="PAD_DOWN" mask="ALT" command="move_backward"/> - <binding key="PAD_PGUP" mask="ALT" command="spin_over"/> - <binding key="PAD_PGDN" mask="ALT" command="spin_under"/> - <binding key="PAD_ENTER" mask="ALT" command="start_chat"/> - <binding key="PAD_DIVIDE" mask="ALT" command="start_gesture"/> - <!--mimic alt zoom behavior with keyboard only--> <binding key="W" mask="CTL_ALT" command="spin_over"/> <binding key="S" mask="CTL_ALT" command="spin_under"/> @@ -104,9 +73,6 @@ <binding key="UP" mask="CTL_ALT" command="spin_over"/> <binding key="DOWN" mask="CTL_ALT" command="spin_under"/> - <binding key="PAD_UP" mask="CTL_ALT" command="spin_over"/> - <binding key="PAD_DOWN" mask="CTL_ALT" command="spin_under"/> - <!--Therefore pan on Alt-Shift--> <binding key="A" mask="CTL_ALT_SHIFT" command="pan_left"/> <binding key="D" mask="CTL_ALT_SHIFT" command="pan_right"/> @@ -118,15 +84,10 @@ <binding key="UP" mask="CTL_ALT_SHIFT" command="pan_up"/> <binding key="DOWN" mask="CTL_ALT_SHIFT" command="pan_down"/> - <binding key="PAD_LEFT" mask="CTL_ALT_SHIFT" command="pan_left"/> - <binding key="PAD_RIGHT" mask="CTL_ALT_SHIFT" command="pan_right"/> - <binding key="PAD_UP" mask="CTL_ALT_SHIFT" command="pan_up"/> - <binding key="PAD_DOWN" mask="CTL_ALT_SHIFT" command="pan_down"/> - <binding key="PAD_ENTER" mask="CTL_ALT_SHIFT" command="start_chat"/> - <binding key="PAD_DIVIDE" mask="CTL_ALT_SHIFT" command="start_gesture"/> - <binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/> <binding key="" mask="NONE" mouse="LMB" command="walk_to"/> + + <binding key="" mask="NONE" mouse="LMB" command="script_trigger_lbutton"/> </third_person> <sitting> <binding key="A" mask="ALT" command="spin_around_cw"/> @@ -168,16 +129,6 @@ <binding key="PGUP" mask="NONE" command="spin_over_sitting"/> <binding key="PGDN" mask="NONE" command="spin_under_sitting"/> - <binding key="PAD_LEFT" mask="NONE" command="spin_around_cw_sitting"/> - <binding key="PAD_RIGHT" mask="NONE" command="spin_around_ccw_sitting"/> - <binding key="PAD_UP" mask="NONE" command="move_forward_sitting"/> - <binding key="PAD_DOWN" mask="NONE" command="move_backward_sitting"/> - <binding key="PAD_PGUP" mask="NONE" command="spin_over_sitting"/> - <binding key="PAD_PGDN" mask="NONE" command="spin_under_sitting"/> - <binding key="PAD_CENTER" mask="NONE" command="stop_moving"/> - <binding key="PAD_ENTER" mask="NONE" command="start_chat"/> - <binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/> - <!--these are for passing controls when sitting on vehicles--> <binding key="A" mask="SHIFT" command="slide_left"/> <binding key="D" mask="SHIFT" command="slide_right"/> @@ -193,15 +144,6 @@ <binding key="PGUP" mask="SHIFT" command="spin_over_sitting"/> <binding key="PGDN" mask="SHIFT" command="spin_under_sitting"/> - <binding key="PAD_LEFT" mask="SHIFT" command="slide_left"/> - <binding key="PAD_RIGHT" mask="SHIFT" command="slide_right"/> - <binding key="PAD_UP" mask="SHIFT" command="move_forward_sitting"/> - <binding key="PAD_DOWN" mask="SHIFT" command="move_backward_sitting"/> - <binding key="PAD_PGUP" mask="SHIFT" command="spin_over_sitting"/> - <binding key="PAD_PGDN" mask="SHIFT" command="spin_under_sitting"/> - <binding key="PAD_ENTER" mask="SHIFT" command="start_chat"/> - <binding key="PAD_DIVIDE" mask="SHIFT" command="start_gesture"/> - <!--pan on Alt-Shift--> <binding key="A" mask="CTL_ALT_SHIFT" command="pan_left"/> <binding key="D" mask="CTL_ALT_SHIFT" command="pan_right"/> @@ -213,17 +155,12 @@ <binding key="UP" mask="CTL_ALT_SHIFT" command="pan_up"/> <binding key="DOWN" mask="CTL_ALT_SHIFT" command="pan_down"/> - <binding key="PAD_LEFT" mask="CTL_ALT_SHIFT" command="pan_left"/> - <binding key="PAD_RIGHT" mask="CTL_ALT_SHIFT" command="pan_right"/> - <binding key="PAD_UP" mask="CTL_ALT_SHIFT" command="pan_up"/> - <binding key="PAD_DOWN" mask="CTL_ALT_SHIFT" command="pan_down"/> - <binding key="PAD_ENTER" mask="CTL_ALT_SHIFT" command="start_chat"/> - <binding key="PAD_DIVIDE" mask="CTL_ALT_SHIFT" command="start_gesture"/> - <binding key="ENTER" mask="NONE" command="start_chat"/> <binding key="DIVIDE" mask="NONE" command="start_gesture"/> <binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/> + + <binding key="" mask="NONE" mouse="LMB" command="script_trigger_lbutton"/> </sitting> <edit_avatar> <!--Avatar editing camera controls--> @@ -241,15 +178,9 @@ <binding key="PGDN" mask="NONE" command="edit_avatar_spin_under"/> <binding key="ENTER" mask="NONE" command="start_chat"/> <binding key="DIVIDE" mask="NONE" command="start_gesture"/> - <binding key="PAD_LEFT" mask="NONE" command="edit_avatar_spin_cw"/> - <binding key="PAD_RIGHT" mask="NONE" command="edit_avatar_spin_ccw"/> - <binding key="PAD_UP" mask="NONE" command="edit_avatar_move_forward"/> - <binding key="PAD_DOWN" mask="NONE" command="edit_avatar_move_backward"/> - <binding key="PAD_PGUP" mask="NONE" command="edit_avatar_spin_over"/> - <binding key="PAD_PGDN" mask="NONE" command="edit_avatar_spin_under"/> - <binding key="PAD_ENTER" mask="NONE" command="start_chat"/> - <binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/> <binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/> + + <binding key="" mask="NONE" mouse="LMB" command="script_trigger_lbutton"/> </edit_avatar> </keys> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 12f435f931..0e55331cdc 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -4758,7 +4758,7 @@ <key>Type</key> <string>String</string> <key>Value</key> - <string>https://search.[GRID]/viewer/[CATEGORY]/?q=[QUERY]&p=[AUTH_TOKEN]&r=[MATURITY]&lang=[LANGUAGE]&g=[GODLIKE]&sid=[SESSION_ID]&rid=[REGION_ID]&pid=[PARCEL_ID]&channel=[CHANNEL]&version=[VERSION]&major=[VERSION_MAJOR]&minor=[VERSION_MINOR]&patch=[VERSION_PATCH]&build=[VERSION_BUILD]</string> + <string>https://search.[GRID]/viewer/[CATEGORY]/?q=[QUERY]&r=[MATURITY]&lang=[LANGUAGE]&g=[GODLIKE]&sid=[SESSION_ID]&rid=[REGION_ID]&pid=[PARCEL_ID]&channel=[CHANNEL]&version=[VERSION]&major=[VERSION_MAJOR]&minor=[VERSION_MINOR]&patch=[VERSION_PATCH]&build=[VERSION_BUILD]</string> </map> <key>GuidebookURL</key> <map> @@ -5895,17 +5895,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>LoginAsGod</key> - <map> - <key>Comment</key> - <string>Attempt to login with god powers (Linden accounts only)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>LoginLocation</key> <map> <key>Comment</key> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 50e0d1d935..d5d0d044c0 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -1988,7 +1988,8 @@ void LLAgent::propagate(const F32 dt) //----------------------------------------------------------------------------- void LLAgent::updateAgentPosition(const F32 dt, const F32 yaw_radians, const S32 mouse_x, const S32 mouse_y) { - if (mMoveTimer.getStarted() && mMoveTimer.getElapsedTimeF32() > gSavedSettings.getF32("NotMovingHintTimeout")) + static LLCachedControl<F32> hint_timeout(gSavedSettings, "NotMovingHintTimeout"); + if (mMoveTimer.getStarted() && mMoveTimer.getElapsedTimeF32() > hint_timeout) { LLFirstUse::notMoving(); } @@ -2159,7 +2160,8 @@ void LLAgent::endAnimationUpdateUI() LLNavigationBar::getInstance()->setVisible(TRUE && gSavedSettings.getBOOL("ShowNavbarNavigationPanel")); gStatusBar->setVisibleForMouselook(true); - if (gSavedSettings.getBOOL("ShowMiniLocationPanel")) + static LLCachedControl<bool> show_mini_location_panel(gSavedSettings, "ShowMiniLocationPanel"); + if (show_mini_location_panel) { LLPanelTopInfoBar::getInstance()->setVisible(TRUE); } @@ -3901,26 +3903,12 @@ bool LLAgent::teleportCore(bool is_local) // yet if the teleport will succeed. Look in // process_teleport_location_reply - // close the map panel so we can see our destination. - // we don't close search floater, see EXT-5840. - LLFloaterReg::hideInstance("world_map"); - // hide land floater too - it'll be out of date LLFloaterReg::hideInstance("about_land"); // hide the Region/Estate floater LLFloaterReg::hideInstance("region_info"); - // minimize the Search floater (STORM-1474) - { - LLFloater* instance = LLFloaterReg::getInstance("search"); - - if (instance && instance->getVisible()) - { - instance->setMinimized(TRUE); - } - } - LLViewerParcelMgr::getInstance()->deselectLand(); LLViewerMediaFocus::getInstance()->clearFocus(); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index c9d852686e..8d2e274b4c 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1821,6 +1821,8 @@ bool LLAppViewer::cleanup() if (gAudiop) { + LL_INFOS() << "Shutting down audio" << LL_ENDL; + // be sure to stop the internet stream cleanly BEFORE destroying the interface to stop it. gAudiop->stopInternetStream(); // shut down the streaming audio sub-subsystem first, in case it relies on not outliving the general audio subsystem. @@ -4294,120 +4296,6 @@ void LLAppViewer::addOnIdleCallback(const boost::function<void()>& cb) void LLAppViewer::loadKeyBindings() { std::string key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "key_bindings.xml"); -#if 1 - // Legacy support - // Remove #if-#endif section half a year after DRTVWR-501 releases. - // Mouse actions are part of keybinding file since DRTVWR-501 instead of being stored in - // settings.xml. To support legacy viewers that were storing in settings.xml we need to - // transfer old variables to new format. - // Also part of backward compatibility is present in LLKeyConflictHandler to modify - // legacy variables on changes in new system (to make sure we won't enforce - // legacy values again if user dropped to defaults in new system) - if (LLVersionInfo::getInstance()->getChannelAndVersion() != gLastRunVersion - || !gDirUtilp->fileExists(key_bindings_file)) // if file is missing, assume that there were no changes by user yet - { - // copy mouse actions and voice key changes to new file - LL_INFOS("InitInfo") << "Converting legacy mouse bindings to new format" << LL_ENDL; - // Load settings from file - LLKeyConflictHandler third_person_view(LLKeyConflictHandler::MODE_THIRD_PERSON); - LLKeyConflictHandler sitting_view(LLKeyConflictHandler::MODE_SITTING); - - // Since we are only modifying keybindings if personal file doesn't exist yet, - // it should be safe to just overwrite the value - // If key is already in use somewhere by default, LLKeyConflictHandler should resolve it. - BOOL value = gSavedSettings.getBOOL("DoubleClickAutoPilot"); - third_person_view.registerControl("walk_to", - 0, - value ? EMouseClickType::CLICK_DOUBLELEFT : EMouseClickType::CLICK_NONE, - KEY_NONE, - MASK_NONE, - value); - - U32 index = value ? 1 : 0; // we can store multiple combinations per action, so if first is in use by doubleclick, go to second - value = gSavedSettings.getBOOL("ClickToWalk"); - third_person_view.registerControl("walk_to", - index, - value ? EMouseClickType::CLICK_LEFT : EMouseClickType::CLICK_NONE, - KEY_NONE, - MASK_NONE, - value); - - value = gSavedSettings.getBOOL("DoubleClickTeleport"); - third_person_view.registerControl("teleport_to", - 0, - value ? EMouseClickType::CLICK_DOUBLELEFT : EMouseClickType::CLICK_NONE, - KEY_NONE, - MASK_NONE, - value); - - // sitting also supports teleport - sitting_view.registerControl("teleport_to", - 0, - value ? EMouseClickType::CLICK_DOUBLELEFT : EMouseClickType::CLICK_NONE, - KEY_NONE, - MASK_NONE, - value); - - std::string key_string = gSavedSettings.getString("PushToTalkButton"); - EMouseClickType mouse = EMouseClickType::CLICK_NONE; - KEY key = KEY_NONE; - if (key_string == "MiddleMouse") - { - mouse = EMouseClickType::CLICK_MIDDLE; - } - else if (key_string == "MouseButton4") - { - mouse = EMouseClickType::CLICK_BUTTON4; - } - else if (key_string == "MouseButton5") - { - mouse = EMouseClickType::CLICK_BUTTON5; - } - else - { - LLKeyboard::keyFromString(key_string, &key); - } - - value = gSavedSettings.getBOOL("PushToTalkToggle"); - std::string control_name = value ? "toggle_voice" : "voice_follow_key"; - third_person_view.registerControl(control_name, 0, mouse, key, MASK_NONE, true); - sitting_view.registerControl(control_name, 0, mouse, key, MASK_NONE, true); - - if (third_person_view.hasUnsavedChanges()) - { - // calls loadBindingsXML() - third_person_view.saveToSettings(); - } - - if (sitting_view.hasUnsavedChanges()) - { - // calls loadBindingsXML() - sitting_view.saveToSettings(); - } - - // in case of voice we need to repeat this in other modes - - for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i) - { - // edit and first person modes; MODE_SAVED_SETTINGS not in use at the moment - if (i != LLKeyConflictHandler::MODE_THIRD_PERSON && i != LLKeyConflictHandler::MODE_SITTING) - { - LLKeyConflictHandler handler((LLKeyConflictHandler::ESourceMode)i); - - handler.registerControl(control_name, 0, mouse, key, MASK_NONE, true); - - if (handler.hasUnsavedChanges()) - { - // calls loadBindingsXML() - handler.saveToSettings(); - } - } - } - } - // since something might have gone wrong or there might have been nothing to save - // (and because otherwise following code will have to be encased in else{}), - // load everything one last time -#endif if (!gDirUtilp->fileExists(key_bindings_file) || !gViewerInput.loadBindingsXML(key_bindings_file)) { // Failed to load custom bindings, try default ones @@ -5427,14 +5315,18 @@ void LLAppViewer::disconnectViewer() } // save inventory if appropriate - gInventory.cache(gInventory.getRootFolderID(), gAgent.getID()); - if (gInventory.getLibraryRootFolderID().notNull() - && gInventory.getLibraryOwnerID().notNull()) - { - gInventory.cache( - gInventory.getLibraryRootFolderID(), - gInventory.getLibraryOwnerID()); - } + if (gInventory.isInventoryUsable() + && gAgent.getID().notNull()) // Shouldn't be null at this stage + { + gInventory.cache(gInventory.getRootFolderID(), gAgent.getID()); + if (gInventory.getLibraryRootFolderID().notNull() + && gInventory.getLibraryOwnerID().notNull()) + { + gInventory.cache( + gInventory.getLibraryRootFolderID(), + gInventory.getLibraryOwnerID()); + } + } saveNameCache(); if (LLExperienceCache::instanceExists()) diff --git a/indra/newview/llappviewerwin32.h b/indra/newview/llappviewerwin32.h index 82b6b0c77c..ab52bf15f9 100644 --- a/indra/newview/llappviewerwin32.h +++ b/indra/newview/llappviewerwin32.h @@ -51,8 +51,8 @@ protected: bool initHardwareTest() override; // Win32 uses DX9 to test hardware. bool initParseCommandLine(LLCommandLineParser& clp) override; - virtual bool beingDebugged(); - virtual bool restoreErrorTrap(); + bool beingDebugged() override; + bool restoreErrorTrap() override; bool sendURLToOtherInstance(const std::string& url) override; diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp index ca83afb5ab..04dbf03e31 100644 --- a/indra/newview/llavatarrenderinfoaccountant.cpp +++ b/indra/newview/llavatarrenderinfoaccountant.cpp @@ -345,6 +345,8 @@ void LLAvatarRenderInfoAccountant::idle() && regionp->capabilitiesReceived()) { // each of these is further governed by and resets its own timer + // Note: We can have multiple regions, each launches up to two coroutines, + // it likely is expensive sendRenderInfoToRegion(regionp); getRenderInfoFromRegion(regionp); } diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index 6d20b23e9f..43e39d3073 100644 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -645,7 +645,8 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg) { if(mBuddyInfo.find(agent_id) != mBuddyInfo.end()) { - if((mBuddyInfo[agent_id]->getRightsGrantedFrom() ^ new_rights) & LLRelationship::GRANT_MODIFY_OBJECTS) + if (((mBuddyInfo[agent_id]->getRightsGrantedFrom() ^ new_rights) & LLRelationship::GRANT_MODIFY_OBJECTS) + && !gAgent.isDoNotDisturb()) { LLSD args; args["NAME"] = LLSLURL("agent", agent_id, "displayname").getSLURLString(); diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 4ee08e869a..91b0e40aa9 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -615,12 +615,12 @@ void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissi void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) { - BOOL batch_fullbrights = gSavedSettings.getBOOL("RenderAlphaBatchFullbrights"); - BOOL batch_emissives = gSavedSettings.getBOOL("RenderAlphaBatchEmissives"); - BOOL initialized_lighting = FALSE; - BOOL light_enabled = TRUE; + static LLCachedControl<bool> batch_fullbrights(gSavedSettings, "RenderAlphaBatchFullbrights"); + static LLCachedControl<bool> batch_emissives(gSavedSettings, "RenderAlphaBatchEmissives"); + bool initialized_lighting = FALSE; + bool light_enabled = TRUE; - BOOL use_shaders = gPipeline.canUseVertexShaders(); + bool use_shaders = gPipeline.canUseVertexShaders(); for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) { diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index aa426cd785..3d1a292ba2 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -574,18 +574,8 @@ void LLDrawPoolWater::shade2(bool edge, LLGLSLShader* shader, const LLColor3& li shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV); shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV); shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp); - if (LLEnvironment::instance().isCloudScrollPaused()) - { - static const std::array<F32, 2> zerowave{ {0.0f, 0.0f} }; - - shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, zerowave.data()); - shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, zerowave.data()); - } - else - { - shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV); - shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV); - } + shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV); + shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV); shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV); shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, pwater->getNormalScale().mV); diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp index 3b192ff81b..1c69b9d60b 100644 --- a/indra/newview/llfloatercamera.cpp +++ b/indra/newview/llfloatercamera.cpp @@ -453,18 +453,18 @@ void LLFloaterCamera::setMode(ECameraControlMode mode) void LLFloaterCamera::switchMode(ECameraControlMode mode) { - setMode(mode); - switch (mode) { case CAMERA_CTRL_MODE_PRESETS: case CAMERA_CTRL_MODE_PAN: sFreeCamera = false; + setMode(mode); // depends onto sFreeCamera clear_camera_tool(); break; case CAMERA_CTRL_MODE_FREE_CAMERA: sFreeCamera = true; + setMode(mode); activate_camera_tool(); break; diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp index 281d4f68f5..eb0cd28190 100644 --- a/indra/newview/llfloatereditextdaycycle.cpp +++ b/indra/newview/llfloatereditextdaycycle.cpp @@ -98,6 +98,11 @@ namespace { const std::string TABS_SKYS("sky_tabs"); const std::string TABS_WATER("water_tabs"); + // 'Play' buttons + const std::string BTN_PLAY("play_btn"); + const std::string BTN_SKIP_BACK("skip_back_btn"); + const std::string BTN_SKIP_FORWARD("skip_forward_btn"); + const std::string EVNT_DAYTRACK("DayCycle.Track"); const std::string EVNT_PLAY("DayCycle.PlayActions"); @@ -1205,6 +1210,11 @@ void LLFloaterEditExtDayCycle::updateButtons() mDeleteFrameButton->setEnabled(can_manipulate && isRemovingFrameAllowed()); mLoadFrame->setEnabled(can_manipulate); + BOOL enable_play = mEditDay ? TRUE : FALSE; + childSetEnabled(BTN_PLAY, enable_play); + childSetEnabled(BTN_SKIP_BACK, enable_play); + childSetEnabled(BTN_SKIP_FORWARD, enable_play); + // update track buttons bool extended_env = LLEnvironment::instance().isExtendedEnvironmentEnabled(); for (S32 track = 0; track < LLSettingsDay::TRACK_MAX; ++track) @@ -1575,15 +1585,22 @@ void LLFloaterEditExtDayCycle::onIdlePlay(void* user_data) { LLFloaterEditExtDayCycle* self = (LLFloaterEditExtDayCycle*)user_data; - F32 prcnt_played = self->mPlayTimer.getElapsedTimeF32() / DAY_CYCLE_PLAY_TIME_SECONDS; - F32 new_frame = fmod(self->mPlayStartFrame + prcnt_played, 1.f); + if (self->mSkyBlender == nullptr || self->mWaterBlender == nullptr) + { + self->stopPlay(); + } + else + { + + F32 prcnt_played = self->mPlayTimer.getElapsedTimeF32() / DAY_CYCLE_PLAY_TIME_SECONDS; + F32 new_frame = fmod(self->mPlayStartFrame + prcnt_played, 1.f); - self->mTimeSlider->setCurSliderValue(new_frame); // will do the rounding - self->mSkyBlender->setPosition(new_frame); - self->mWaterBlender->setPosition(new_frame); - self->synchronizeTabs(); - self->updateTimeAndLabel(); - self->updateButtons(); + self->mTimeSlider->setCurSliderValue(new_frame); // will do the rounding + + self->synchronizeTabs(); + self->updateTimeAndLabel(); + self->updateButtons(); + } } } diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp index c4e0dd483f..6e326ff3cf 100644 --- a/indra/newview/llfloatergesture.cpp +++ b/indra/newview/llfloatergesture.cpp @@ -582,8 +582,7 @@ void LLFloaterGesture::onCopyPasteAction(const LLSD& command) LLInventoryItem* item = gInventory.getItem(*it); if(item && item->getInventoryType() == LLInventoryType::IT_GESTURE) { - LLWString item_name = utf8str_to_wstring(item->getName()); - LLClipboard::instance().addToClipboard(item_name, 0, item_name.size()); + LLClipboard::instance().addToClipboard(*it); } } } diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 64b24d54c3..6d23d14374 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -40,6 +40,7 @@ #include "llagent.h" #include "llbutton.h" #include "llcombobox.h" +#include "llfloaterreg.h" #include "llfocusmgr.h" #include "llmeshrepository.h" #include "llnotificationsutil.h" @@ -347,6 +348,26 @@ void LLFloaterModelPreview::initModelPreview() mModelPreview->setModelUpdatedCallback(boost::bind(&LLFloaterModelPreview::modelUpdated, this, _1)); } +//static +bool LLFloaterModelPreview::showModelPreview() +{ +#ifdef LL_GLOD + if (LLRender::sGLCoreProfile) + { + // GLOD is incompatible with RenderGLCoreProfile, will crash on init + LLNotificationsUtil::add("MeshUploadProfilerError"); + return false; + } +#endif + + LLFloaterModelPreview* fmp = (LLFloaterModelPreview*)LLFloaterReg::getInstance("upload_model"); + if (fmp && !fmp->isModelLoading()) + { + fmp->loadHighLodModel(); + } + return true; +} + void LLFloaterModelPreview::onUploadOptionChecked(LLUICtrl* ctrl) { if (mModelPreview) diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 8a01b0c307..19b13bc48a 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -73,6 +73,7 @@ public: /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); void initModelPreview(); + static bool showModelPreview(); BOOL handleMouseDown(S32 x, S32 y, MASK mask); BOOL handleMouseUp(S32 x, S32 y, MASK mask); diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index da01457126..b45e9093f7 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -2399,7 +2399,16 @@ void LLPanelPreference::saveSettings() { view_stack.push_back(*iter); } - } + } + + if (LLStartUp::getStartupState() == STATE_STARTED) + { + LLControlVariable* control = gSavedPerAccountSettings.getControl("VoiceCallsFriendsOnly"); + if (control) + { + mSavedValues[control] = control->getValue(); + } + } } void LLPanelPreference::showMultipleViewersWarning(LLUICtrl* checkbox, const LLSD& value) diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp index 779542cfcc..2e1fbb09e0 100644 --- a/indra/newview/llfloatersearch.cpp +++ b/indra/newview/llfloatersearch.cpp @@ -169,15 +169,6 @@ void LLFloaterSearch::search(const SearchQuery &p) // add the search query string subs["QUERY"] = LLURI::escape(p.query); - // add the permissions token that login.cgi gave us - // We use "search_token", and fallback to "auth_token" if not present. - LLSD search_token = LLLoginInstance::getInstance()->getResponse("search_token"); - if (search_token.asString().empty()) - { - search_token = LLLoginInstance::getInstance()->getResponse("auth_token"); - } - subs["AUTH_TOKEN"] = search_token.asString(); - // add the user's preferred maturity (can be changed via prefs) std::string maturity; if (gAgent.prefersAdult()) diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index 27197f0b06..6ca134ecd3 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -56,6 +56,7 @@ #include "llscrolllistctrl.h" #include "llslurl.h" #include "lltextbox.h" +#include "lltoolbarview.h" #include "lltracker.h" #include "lltrans.h" #include "llviewerinventory.h" // LLViewerInventoryItem @@ -87,6 +88,9 @@ static const F32 MAP_ZOOM_TIME = 0.2f; // Currently (01/26/09), this value allows the whole grid to be visible in a 1024x1024 window. static const S32 MAX_VISIBLE_REGIONS = 512; + +const S32 HIDE_BEACON_PAD = 133; + // It would be more logical to have this inside the method where it is used but to compile under gcc this // struct has to be here. struct SortRegionNames @@ -1642,3 +1646,101 @@ void LLFloaterWorldMap::onFocusLost() LLWorldMapView* map_panel = (LLWorldMapView*)gFloaterWorldMap->mPanel; map_panel->mPanning = FALSE; } + +LLPanelHideBeacon::LLPanelHideBeacon() : + mHideButton(NULL) +{ +} + +// static +LLPanelHideBeacon* LLPanelHideBeacon::getInstance() +{ + static LLPanelHideBeacon* panel = getPanelHideBeacon(); + return panel; +} + + +BOOL LLPanelHideBeacon::postBuild() +{ + mHideButton = getChild<LLButton>("hide_beacon_btn"); + mHideButton->setCommitCallback(boost::bind(&LLPanelHideBeacon::onHideButtonClick, this)); + + gViewerWindow->setOnWorldViewRectUpdated(boost::bind(&LLPanelHideBeacon::updatePosition, this)); + + return TRUE; +} + +//virtual +void LLPanelHideBeacon::draw() +{ + if (!LLTracker::isTracking(NULL)) + { + return; + } + updatePosition(); + LLPanel::draw(); +} + +//virtual +void LLPanelHideBeacon::setVisible(BOOL visible) +{ + if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK) visible = false; + + if (visible) + { + updatePosition(); + } + + LLPanel::setVisible(visible); +} + + +//static +LLPanelHideBeacon* LLPanelHideBeacon::getPanelHideBeacon() +{ + LLPanelHideBeacon* panel = new LLPanelHideBeacon(); + panel->buildFromFile("panel_hide_beacon.xml"); + + LL_INFOS() << "Build LLPanelHideBeacon panel" << LL_ENDL; + + panel->updatePosition(); + return panel; +} + +void LLPanelHideBeacon::onHideButtonClick() +{ + LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance(); + if (instance) + { + instance->onClearBtn(); + } +} + +/** +* Updates position of the panel (similar to Stand & Stop Flying panel). +*/ +void LLPanelHideBeacon::updatePosition() +{ + S32 bottom_tb_center = 0; + if (LLToolBar* toolbar_bottom = gToolBarView->getToolbar(LLToolBarEnums::TOOLBAR_BOTTOM)) + { + bottom_tb_center = toolbar_bottom->getRect().getCenterX(); + } + + S32 left_tb_width = 0; + if (LLToolBar* toolbar_left = gToolBarView->getToolbar(LLToolBarEnums::TOOLBAR_LEFT)) + { + left_tb_width = toolbar_left->getRect().getWidth(); + } + + if (gToolBarView != NULL && gToolBarView->getToolbar(LLToolBarEnums::TOOLBAR_LEFT)->hasButtons()) + { + S32 x_pos = bottom_tb_center - getRect().getWidth() / 2 - left_tb_width; + setOrigin( x_pos + HIDE_BEACON_PAD, 0); + } + else + { + S32 x_pos = bottom_tb_center - getRect().getWidth() / 2; + setOrigin( x_pos + HIDE_BEACON_PAD, 0); + } +} diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h index 97e99297cf..30cf1b9910 100644 --- a/indra/newview/llfloaterworldmap.h +++ b/indra/newview/llfloaterworldmap.h @@ -107,7 +107,8 @@ public: // teleport to the tracked item, if there is one void teleport(); void onChangeMaturity(); - + + void onClearBtn(); //Slapp instigated avatar tracking void avatarTrackFromSlapp( const LLUUID& id ); @@ -124,7 +125,6 @@ protected: void onComboTextEntry( ); void onSearchTextEntry( ); - void onClearBtn(); void onClickTeleportBtn(); void onShowTargetBtn(); void onShowAgentBtn(); @@ -199,5 +199,25 @@ private: extern LLFloaterWorldMap* gFloaterWorldMap; + +class LLPanelHideBeacon : public LLPanel +{ +public: + static LLPanelHideBeacon* getInstance(); + + LLPanelHideBeacon(); + /*virtual*/ BOOL postBuild(); + /*virtual*/ void setVisible(BOOL visible); + /*virtual*/ void draw(); + +private: + static LLPanelHideBeacon* getPanelHideBeacon(); + void onHideButtonClick(); + void updatePosition(); + + LLButton* mHideButton; + +}; + #endif diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index 9f2119281d..bd881f8e7a 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -910,7 +910,7 @@ void LLGestureMgr::stepGesture(LLMultiGesture* gesture) else if (gesture->mWaitTimer.getElapsedTimeF32() > MAX_WAIT_ANIM_SECS) { // we've waited too long for an animation - LL_INFOS() << "Waited too long for animations to stop, continuing gesture." + LL_INFOS("GestureMgr") << "Waited too long for animations to stop, continuing gesture." << LL_ENDL; gesture->mWaitingAnimations = FALSE; gesture->mCurrentStep++; @@ -1097,6 +1097,34 @@ void LLGestureMgr::onLoadComplete(const LLUUID& asset_uuid, self.setFetchID(item_id); self.startFetch(); } + + item_map_t::iterator it = self.mActive.find(item_id); + if (it == self.mActive.end()) + { + // Gesture is supposed to be present, active, but NULL + LL_DEBUGS("GestureMgr") << "Gesture " << item_id << " not found in active list" << LL_ENDL; + } + else + { + LLMultiGesture* old_gesture = (*it).second; + if (old_gesture) + { + LL_DEBUGS("GestureMgr") << "Received dupplicate " << item_id << " callback" << LL_ENDL; + // In case somebody managest to activate, deactivate and + // then activate gesture again, before asset finishes loading. + // LLLoadInfo will have a different pointer, asset storage will + // see it as a different request, resulting in two callbacks. + + // deactivateSimilarGestures() did not turn this one off + // because of matching item_id + self.stopGesture(old_gesture); + + self.mActive.erase(item_id); + delete old_gesture; + old_gesture = NULL; + } + } + self.mActive[item_id] = gesture; // Everything has been successful. Add to the active list. @@ -1131,9 +1159,23 @@ void LLGestureMgr::onLoadComplete(const LLUUID& asset_uuid, } else { - LL_WARNS() << "Unable to load gesture" << LL_ENDL; - - self.mActive.erase(item_id); + LL_WARNS("GestureMgr") << "Unable to load gesture" << LL_ENDL; + + item_map_t::iterator it = self.mActive.find(item_id); + if (it != self.mActive.end()) + { + LLMultiGesture* old_gesture = (*it).second; + if (old_gesture) + { + // Shouldn't happen, just in case + LL_WARNS("GestureMgr") << "Gesture " << item_id << " existed when it shouldn't" << LL_ENDL; + + self.stopGesture(old_gesture); + delete old_gesture; + old_gesture = NULL; + } + self.mActive.erase(item_id); + } delete gesture; gesture = NULL; @@ -1151,9 +1193,23 @@ void LLGestureMgr::onLoadComplete(const LLUUID& asset_uuid, LLDelayedGestureError::gestureFailedToLoad( item_id ); } - LL_WARNS() << "Problem loading gesture: " << status << LL_ENDL; - - LLGestureMgr::instance().mActive.erase(item_id); + LL_WARNS("GestureMgr") << "Problem loading gesture: " << status << LL_ENDL; + + item_map_t::iterator it = self.mActive.find(item_id); + if (it != self.mActive.end()) + { + LLMultiGesture* old_gesture = (*it).second; + if (old_gesture) + { + // Shouldn't happen, just in case + LL_WARNS("GestureMgr") << "Gesture " << item_id << " existed when it shouldn't" << LL_ENDL; + + self.stopGesture(old_gesture); + delete old_gesture; + old_gesture = NULL; + } + self.mActive.erase(item_id); + } } } diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index 12d82d101f..5777a0c051 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -196,7 +196,7 @@ LLFetchLeaveGroupData* gFetchLeaveGroupData = NULL; // static void LLGroupActions::search() { - LLFloaterReg::showInstance("search", LLSD().with("category", "groups")); + LLFloaterReg::showInstance("search"); } // static diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index ba453471c6..03340dab0f 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -2841,42 +2841,69 @@ bool LLInventoryModel::saveToFile(const std::string& filename, LL_INFOS(LOG_INV) << "saving inventory to: (" << filename << ")" << LL_ENDL; - llofstream fileXML(filename.c_str()); - if (!fileXML.is_open()) - { - LL_WARNS(LOG_INV) << "unable to save inventory to: " << filename << LL_ENDL; - return false; - } + try + { + llofstream fileXML(filename.c_str()); + if (!fileXML.is_open()) + { + LL_WARNS(LOG_INV) << "Failed to open file. Unable to save inventory to: " << filename << LL_ENDL; + return false; + } - LLSD cache_ver; - cache_ver["inv_cache_version"] = sCurrentInvCacheVersion; + LLSD cache_ver; + cache_ver["inv_cache_version"] = sCurrentInvCacheVersion; - fileXML << LLSDOStreamer<LLSDNotationFormatter>(cache_ver) << std::endl; + if (fileXML.fail()) + { + LL_WARNS(LOG_INV) << "Failed to write cache version to file. Unable to save inventory to: " << filename << LL_ENDL; + return false; + } - S32 count = categories.size(); - S32 cat_count = 0; - S32 i; - for(i = 0; i < count; ++i) - { - LLViewerInventoryCategory* cat = categories[i]; - if(cat->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN) - { - fileXML << LLSDOStreamer<LLSDNotationFormatter>(cat->exportLLSD()) << std::endl; - cat_count++; - } - } + fileXML << LLSDOStreamer<LLSDNotationFormatter>(cache_ver) << std::endl; - S32 it_count = items.size(); - for(i = 0; i < it_count; ++i) - { - fileXML << LLSDOStreamer<LLSDNotationFormatter>(items[i]->asLLSD()) << std::endl; - } + S32 count = categories.size(); + S32 cat_count = 0; + S32 i; + for (i = 0; i < count; ++i) + { + LLViewerInventoryCategory* cat = categories[i]; + if (cat->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN) + { + fileXML << LLSDOStreamer<LLSDNotationFormatter>(cat->exportLLSD()) << std::endl; + cat_count++; + } - fileXML.close(); + if (fileXML.fail()) + { + LL_WARNS(LOG_INV) << "Failed to write a folder to file. Unable to save inventory to: " << filename << LL_ENDL; + return false; + } + } - LL_INFOS(LOG_INV) << "Inventory saved: " << cat_count << " categories, " << it_count << " items." << LL_ENDL; + S32 it_count = items.size(); + for (i = 0; i < it_count; ++i) + { + fileXML << LLSDOStreamer<LLSDNotationFormatter>(items[i]->asLLSD()) << std::endl; - return true; + if (fileXML.fail()) + { + LL_WARNS(LOG_INV) << "Failed to write an item to file. Unable to save inventory to: " << filename << LL_ENDL; + return false; + } + } + + fileXML.close(); + + LL_INFOS(LOG_INV) << "Inventory saved: " << cat_count << " categories, " << it_count << " items." << LL_ENDL; + } + catch (...) + { + LOG_UNHANDLED_EXCEPTION(""); + LL_INFOS(LOG_INV) << "Failed to save inventory to: (" << filename << ")" << LL_ENDL; + return false; + } + + return true; } // message handling functionality diff --git a/indra/newview/llkeyconflict.cpp b/indra/newview/llkeyconflict.cpp index b6107eeedf..83fb1ac7b5 100644 --- a/indra/newview/llkeyconflict.cpp +++ b/indra/newview/llkeyconflict.cpp @@ -376,6 +376,23 @@ bool LLKeyConflictHandler::loadFromSettings(const ESourceMode &load_mode, const LL_ERRS() << "Not implememted mode " << load_mode << LL_ENDL; break; } + + // verify version + if (keys.xml_version < 1) + { + // Updating from a version that was not aware of LMouse bindings. + // Assign defaults. + // + // mDefaultsMap is always going to have correct version so + // registerControl is usable, but using 'destination' just in case. + LLKeyConflict &type_data = (*destination)[script_mouse_handler_name]; + LLKeyData data(CLICK_LEFT, KEY_NONE, MASK_NONE, true); + type_data.mKeyBind.replaceKeyData(data, 0); + + // Mark this mode for an update, once user clicks 'OK' in preferences + // it should get saved + mHasUnsavedChanges = true; + } } return res; } @@ -411,8 +428,16 @@ void LLKeyConflictHandler::loadFromSettings(ESourceMode load_mode) filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_default); if (!gDirUtilp->fileExists(filename) || !loadFromSettings(load_mode, filename, &mControlsMap)) { - // mind placeholders - mControlsMap.insert(mDefaultsMap.begin(), mDefaultsMap.end()); + // Mind placeholders + // Do not use mControlsMap.insert(mDefaultsMap) since mControlsMap has + // placeholders that won't be added over(to) by insert. + // Or instead move generatePlaceholders call to be after copying + control_map_t::iterator iter = mDefaultsMap.begin(); + while (iter != mDefaultsMap.end()) + { + mControlsMap[iter->first].mKeyBind = iter->second.mKeyBind; + iter++; + } } } mLoadMode = load_mode; @@ -575,6 +600,8 @@ void LLKeyConflictHandler::saveToSettings(bool temporary) break; } + keys.xml_version.set(keybindings_xml_version, true); + if (temporary) { // write to temporary xml and use it for gViewerInput @@ -619,68 +646,6 @@ void LLKeyConflictHandler::saveToSettings(bool temporary) } } -#if 1 - // Legacy support - // Remove #if-#endif section half a year after DRTVWR-501 releases. - // Update legacy settings in settings.xml - // We only care for third person view since legacy settings can't store - // more than one mode. - // We are saving this even if we are in temporary mode - preferences - // will restore values on cancel - if (mLoadMode == MODE_THIRD_PERSON && mHasUnsavedChanges) - { - bool value = canHandleMouse("walk_to", CLICK_DOUBLELEFT, MASK_NONE); - gSavedSettings.setBOOL("DoubleClickAutoPilot", value); - - value = canHandleMouse("walk_to", CLICK_LEFT, MASK_NONE); - gSavedSettings.setBOOL("ClickToWalk", value); - - // new method can save both toggle and push-to-talk values simultaneously, - // but legacy one can save only one. It also doesn't support mask. - LLKeyData data = getControl("toggle_voice", 0); - bool can_toggle = !data.isEmpty(); - if (!can_toggle) - { - data = getControl("voice_follow_key", 0); - } - - gSavedSettings.setBOOL("PushToTalkToggle", can_toggle); - if (data.isEmpty()) - { - // legacy viewer has a bug that might crash it if NONE value is assigned. - // just reset to default - gSavedSettings.getControl("PushToTalkButton")->resetToDefault(false); - } - else - { - if (data.mKey != KEY_NONE) - { - gSavedSettings.setString("PushToTalkButton", LLKeyboard::stringFromKey(data.mKey)); - } - else - { - std::string ctrl_value; - switch (data.mMouse) - { - case CLICK_MIDDLE: - ctrl_value = "MiddleMouse"; - break; - case CLICK_BUTTON4: - ctrl_value = "MouseButton4"; - break; - case CLICK_BUTTON5: - ctrl_value = "MouseButton5"; - break; - default: - ctrl_value = "MiddleMouse"; - break; - } - gSavedSettings.setString("PushToTalkButton", ctrl_value); - } - } - } -#endif - if (mLoadMode == MODE_THIRD_PERSON && mHasUnsavedChanges) { // Map floater should react to doubleclick if doubleclick for teleport is set @@ -730,13 +695,19 @@ void LLKeyConflictHandler::resetToDefault(const std::string &control_name, U32 i { return; } + LLKeyConflict &type_data = mControlsMap[control_name]; + if (!type_data.mAssignable) + { + return; + } LLKeyData data = getDefaultControl(control_name, index); - if (data != mControlsMap[control_name].getKeyData(index)) + if (data != type_data.getKeyData(index)) { // reset controls that might have been switched to our current control removeConflicts(data, mControlsMap[control_name].mConflictMask); mControlsMap[control_name].setKeyData(data, index); + mHasUnsavedChanges = true; } } @@ -793,9 +764,9 @@ void LLKeyConflictHandler::resetToDefault(const std::string &control_name) resetToDefaultAndResolve(control_name, false); } -void LLKeyConflictHandler::resetToDefaults(ESourceMode mode) +void LLKeyConflictHandler::resetToDefaultsAndResolve() { - if (mode == MODE_SAVED_SETTINGS) + if (mLoadMode == MODE_SAVED_SETTINGS) { control_map_t::iterator iter = mControlsMap.begin(); control_map_t::iterator end = mControlsMap.end(); @@ -808,8 +779,16 @@ void LLKeyConflictHandler::resetToDefaults(ESourceMode mode) else { mControlsMap.clear(); - generatePlaceholders(mode); + + // Set key combinations. + // Copy from mDefaultsMap before doing generatePlaceholders, otherwise + // insert() will fail to add some keys into pre-existing values from + // generatePlaceholders() mControlsMap.insert(mDefaultsMap.begin(), mDefaultsMap.end()); + + // Set conflict masks and mark functions (un)assignable + generatePlaceholders(mLoadMode); + } mHasUnsavedChanges = true; @@ -819,7 +798,7 @@ void LLKeyConflictHandler::resetToDefaults() { if (!empty()) { - resetToDefaults(mLoadMode); + resetToDefaultsAndResolve(); } else { @@ -829,7 +808,7 @@ void LLKeyConflictHandler::resetToDefaults() // 3. We are loading 'current' only to replace it // but it is reliable and works Todo: consider optimizing. loadFromSettings(mLoadMode); - resetToDefaults(mLoadMode); + resetToDefaultsAndResolve(); } } @@ -862,7 +841,7 @@ void LLKeyConflictHandler::resetKeyboardBindings() void LLKeyConflictHandler::generatePlaceholders(ESourceMode load_mode) { - // These controls are meant to cause conflicts when user tries to assign same control somewhere else + // These placeholders are meant to cause conflict resolution when user tries to assign same control somewhere else // also this can be used to pre-record controls that should not conflict or to assign conflict groups/masks if (load_mode == MODE_FIRST_PERSON) @@ -922,24 +901,60 @@ void LLKeyConflictHandler::generatePlaceholders(ESourceMode load_mode) registerTemporaryControl("spin_around_ccw_sitting"); registerTemporaryControl("spin_around_cw_sitting"); } + + + // Special case, mouse clicks passed to scripts have 'lowest' piority + // thus do not conflict, everything else has a chance before them + // also in ML they have highest priority, but only when script-grabbed, + // thus do not conflict + // (see AGENT_CONTROL_ML_LBUTTON_DOWN and CONTROL_LBUTTON_DOWN_INDEX) + LLKeyConflict *type_data = &mControlsMap[script_mouse_handler_name]; + type_data->mAssignable = true; + type_data->mConflictMask = U32_MAX - CONFLICT_LMOUSE; } -bool LLKeyConflictHandler::removeConflicts(const LLKeyData &data, const U32 &conlict_mask) +bool LLKeyConflictHandler::removeConflicts(const LLKeyData &data, U32 conlict_mask) { if (conlict_mask == CONFLICT_NOTHING) { // Can't conflict return true; } + + if (data.mMouse == CLICK_LEFT + && data.mMask == MASK_NONE + && data.mKey == KEY_NONE) + { + if ((conlict_mask & CONFLICT_LMOUSE) == 0) + { + // Can't conflict + return true; + } + else + { + // simplify conflict mask + conlict_mask = CONFLICT_LMOUSE; + } + } + else + { + // simplify conflict mask + conlict_mask &= ~CONFLICT_LMOUSE; + } + std::map<std::string, S32> conflict_list; control_map_t::iterator cntrl_iter = mControlsMap.begin(); control_map_t::iterator cntrl_end = mControlsMap.end(); for (; cntrl_iter != cntrl_end; ++cntrl_iter) { + const U32 cmp_mask = cntrl_iter->second.mConflictMask; + if ((cmp_mask & conlict_mask) == 0) + { + // can't conflict + continue; + } S32 index = cntrl_iter->second.mKeyBind.findKeyData(data); - if (index >= 0 - && cntrl_iter->second.mConflictMask != CONFLICT_NOTHING - && (cntrl_iter->second.mConflictMask & conlict_mask) != 0) + if (index >= 0) { if (cntrl_iter->second.mAssignable) { diff --git a/indra/newview/llkeyconflict.h b/indra/newview/llkeyconflict.h index 2926ca3aeb..23c1adf1e4 100644 --- a/indra/newview/llkeyconflict.h +++ b/indra/newview/llkeyconflict.h @@ -66,6 +66,7 @@ public: }; const U32 CONFLICT_NOTHING = 0; + const U32 CONFLICT_LMOUSE = 0x1 << 1; // at the moment this just means that key will conflict with everything that is identical const U32 CONFLICT_ANY = U32_MAX; @@ -128,23 +129,24 @@ public: // resets current mode to defaults void resetToDefaults(); - bool empty() { return mControlsMap.empty(); } + bool empty() const { return mControlsMap.empty(); } void clear(); // reloads bindings from last valid user's xml or from default xml // to keyboard's handler static void resetKeyboardBindings(); - bool hasUnsavedChanges() { return mHasUnsavedChanges; } + bool hasUnsavedChanges() const { return mHasUnsavedChanges; } void setLoadMode(ESourceMode mode) { mLoadMode = mode; } - ESourceMode getLoadMode() { return mLoadMode; } + ESourceMode getLoadMode() const { return mLoadMode; } private: void resetToDefaultAndResolve(const std::string &control_name, bool ignore_conflicts); - void resetToDefaults(ESourceMode mode); + void resetToDefaultsAndResolve(); // at the moment these kind of control is not savable, but takes part in conflict resolution void registerTemporaryControl(const std::string &control_name, EMouseClickType mouse_ind, KEY key, MASK mask, U32 conflict_mask); + // conflict mask 0 means that any conflicts will be ignored void registerTemporaryControl(const std::string &control_name, U32 conflict_mask = 0); typedef std::map<std::string, LLKeyConflict> control_map_t; @@ -152,7 +154,7 @@ private: bool loadFromSettings(const ESourceMode &load_mode, const std::string &filename, control_map_t *destination); void generatePlaceholders(ESourceMode load_mode); //E.x. non-assignable values // returns false in case user is trying to reuse control that can't be reassigned - bool removeConflicts(const LLKeyData &data, const U32 &conlict_mask); + bool removeConflicts(const LLKeyData &data, U32 conlict_mask); // removes flags and removes temporary file, returns 'true' if file was removed bool clearUnsavedChanges(); diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index a9e80ab5da..767c3b30ec 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -2616,7 +2616,9 @@ void LLModelPreview::lookupLODModelFiles(S32 lod) std::string lod_filename = mLODFile[LLModel::LOD_HIGH]; std::string ext = ".dae"; - std::string::size_type i = lod_filename.rfind(ext); + std::string lod_filename_lower(lod_filename); + LLStringUtil::toLower(lod_filename_lower); + std::string::size_type i = lod_filename_lower.rfind(ext); if (i != std::string::npos) { lod_filename.replace(i, lod_filename.size() - ext.size(), getLodSuffix(next_lod) + ext); diff --git a/indra/newview/llpathfindingmanager.cpp b/indra/newview/llpathfindingmanager.cpp index cb4c07a417..852b39f442 100644 --- a/indra/newview/llpathfindingmanager.cpp +++ b/indra/newview/llpathfindingmanager.cpp @@ -61,7 +61,7 @@ #define CAP_SERVICE_NAVMESH_STATUS "NavMeshGenerationStatus" -#define CAP_SERVICE_OBJECT_LINKSETS "ObjectNavMeshProperties" +#define CAP_SERVICE_OBJECT_LINKSETS "RegionObjects" #define CAP_SERVICE_TERRAIN_LINKSETS "TerrainNavMeshProperties" #define CAP_SERVICE_CHARACTERS "CharacterProperties" diff --git a/indra/newview/llsearchableui.cpp b/indra/newview/llsearchableui.cpp index 1119e80005..620bbdfcdf 100644 --- a/indra/newview/llsearchableui.cpp +++ b/indra/newview/llsearchableui.cpp @@ -132,8 +132,11 @@ void ll::statusbar::SearchableItem::setNotHighlighted( ) { mCtrl->setHighlighted( false ); - if( mWasHiddenBySearch ) - mMenu->setVisible( TRUE ); + if (mWasHiddenBySearch) + { + mMenu->setVisible(TRUE); + mWasHiddenBySearch = false; + } } } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 54f3e6305c..1bb92ff853 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -2203,10 +2203,6 @@ bool idle_startup() // Have the agent start watching the friends list so we can update proxies gAgent.observeFriends(); - if (gSavedSettings.getBOOL("LoginAsGod")) - { - gAgent.requestEnterGodMode(); - } // Start automatic replay if the flag is set. if (gSavedSettings.getBOOL("StatsAutoRun") || gAgentPilot.getReplaySession()) diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp index f9c327b46e..6d54a3770c 100644 --- a/indra/newview/lltoolcomp.cpp +++ b/indra/newview/lltoolcomp.cpp @@ -44,6 +44,7 @@ #include "lltoolmgr.h" #include "lltoolselectrect.h" #include "lltoolplacer.h" +#include "llviewerinput.h" #include "llviewermenu.h" #include "llviewerobject.h" #include "llviewerwindow.h" @@ -343,7 +344,9 @@ BOOL LLToolCompTranslate::handleDoubleClick(S32 x, S32 y, MASK mask) } // Nothing selected means the first mouse click was probably // bad, so try again. - return FALSE; + // This also consumes the event to prevent things like double-click + // teleport from triggering. + return handleMouseDown(x, y, mask); } @@ -743,7 +746,7 @@ BOOL LLToolCompGun::handleHover(S32 x, S32 y, MASK mask) BOOL LLToolCompGun::handleMouseDown(S32 x, S32 y, MASK mask) { // if the left button is grabbed, don't put up the pie menu - if (gAgent.leftButtonGrabbed()) + if (gAgent.leftButtonGrabbed() && gViewerInput.isLMouseHandlingDefault(MODE_FIRST_PERSON)) { gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN); return FALSE; @@ -760,7 +763,7 @@ BOOL LLToolCompGun::handleMouseDown(S32 x, S32 y, MASK mask) BOOL LLToolCompGun::handleDoubleClick(S32 x, S32 y, MASK mask) { // if the left button is grabbed, don't put up the pie menu - if (gAgent.leftButtonGrabbed()) + if (gAgent.leftButtonGrabbed() && gViewerInput.isLMouseHandlingDefault(MODE_FIRST_PERSON)) { gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN); return FALSE; @@ -794,7 +797,10 @@ BOOL LLToolCompGun::handleRightMouseDown(S32 x, S32 y, MASK mask) BOOL LLToolCompGun::handleMouseUp(S32 x, S32 y, MASK mask) { - gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_UP); + if (gViewerInput.isLMouseHandlingDefault(MODE_FIRST_PERSON)) + { + gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_UP); + } setCurrentTool( (LLTool*) mGun ); return TRUE; } diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp index f01b374db1..7ab079c74d 100644 --- a/indra/newview/lltoolgrab.cpp +++ b/indra/newview/lltoolgrab.cpp @@ -51,6 +51,7 @@ #include "lltoolmgr.h" #include "lltoolpie.h" #include "llviewercamera.h" +#include "llviewerinput.h" #include "llviewerobject.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" @@ -140,7 +141,6 @@ BOOL LLToolGrabBase::handleMouseDown(S32 x, S32 y, MASK mask) LL_INFOS() << "LLToolGrab handleMouseDown" << LL_ENDL; } - // call the base class to propogate info to sim LLTool::handleMouseDown(x, y, mask); // leftButtonGrabbed() checks if controls are reserved by scripts, but does not take masks into account @@ -150,6 +150,19 @@ BOOL LLToolGrabBase::handleMouseDown(S32 x, S32 y, MASK mask) gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ TRUE); } mClickedInMouselook = gAgentCamera.cameraMouselook(); + + if (mClickedInMouselook && gViewerInput.isLMouseHandlingDefault(MODE_FIRST_PERSON)) + { + // LLToolCompGun::handleMouseDown handles the event if ML controls are grabed, + // but LLToolGrabBase is often the end point for mouselook clicks if ML controls + // are not grabbed and LLToolGrabBase::handleMouseDown consumes the event, + // so send clicks from here. + // We are sending specifically CONTROL_LBUTTON_DOWN instead of _ML_ version. + gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN); + + // Todo: LLToolGrabBase probably shouldn't consume the event if there is nothing + // to grab in Mouselook, it intercepts handling in scanMouse + } return TRUE; } @@ -953,9 +966,18 @@ void LLToolGrabBase::handleHoverFailed(S32 x, S32 y, MASK mask) BOOL LLToolGrabBase::handleMouseUp(S32 x, S32 y, MASK mask) { - // call the base class to propogate info to sim LLTool::handleMouseUp(x, y, mask); + if (gAgentCamera.cameraMouselook() && gViewerInput.isLMouseHandlingDefault(MODE_FIRST_PERSON)) + { + // LLToolCompGun::handleMouseUp handles the event if ML controls are grabed, + // but LLToolGrabBase is often the end point for mouselook clicks if ML controls + // are not grabbed and LToolGrabBase::handleMouseUp consumes the event, + // so send clicks from here. + // We are sending specifically CONTROL_LBUTTON_UP instead of _ML_ version. + gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_UP); + } + if( hasMouseCapture() ) { setMouseCapture( FALSE ); diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 54ff7d295e..6efed98fff 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -654,6 +654,13 @@ bool LLToolPie::teleportToClickedLocation() LLViewerObject* objp = mHoverPick.getObject(); LLViewerObject* parentp = objp ? objp->getRootEdit() : NULL; + if (objp->getAvatar() == gAgentAvatarp + || objp == gAgentAvatarp) // ex: nametag + { + // Don't teleport to self, teleporting to other avatars is fine + return false; + } + bool is_in_world = mHoverPick.mObjectID.notNull() && objp && !objp->isHUDAttachment(); bool is_land = mHoverPick.mPickType == LLPickInfo::PICK_LAND; bool pos_non_zero = !mHoverPick.mPosGlobal.isExactlyZero(); @@ -748,7 +755,7 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask) else if (!mMouseOutsideSlop && mMouseButtonDown // disable camera steering if click on land is not used for moving - && gViewerInput.isMouseBindUsed(CLICK_LEFT)) + && gViewerInput.isMouseBindUsed(CLICK_LEFT, MASK_NONE, MODE_THIRD_PERSON)) { S32 delta_x = x - mMouseDownX; S32 delta_y = y - mMouseDownY; diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp index f97ba0930e..f810e5f4ef 100644 --- a/indra/newview/llvieweraudio.cpp +++ b/indra/newview/llvieweraudio.cpp @@ -83,6 +83,8 @@ void LLViewerAudio::registerIdleListener() void LLViewerAudio::startInternetStreamWithAutoFade(const std::string &streamURI) { + LL_DEBUGS("AudioEngine") << "Start with outo fade: " << streamURI << LL_ENDL; + // Old and new stream are identical if (mNextStreamURI == streamURI) { @@ -166,6 +168,7 @@ bool LLViewerAudio::onIdleUpdate() if (gAudiop) { // Clear URI + LL_DEBUGS("AudioEngine") << "Done with audio fade" << LL_ENDL; gAudiop->startInternetStream(LLStringUtil::null); gAudiop->stopInternetStream(); } @@ -176,6 +179,7 @@ bool LLViewerAudio::onIdleUpdate() if (gAudiop) { + LL_DEBUGS("AudioEngine") << "Audio fade in: " << mNextStreamURI << LL_ENDL; LLStreamingAudioInterface *stream = gAudiop->getStreamingAudioImpl(); if(stream && stream->supportsAdjustableBufferSizes()) stream->setBufferSizes(gSavedSettings.getU32("FMODExStreamBufferSize"),gSavedSettings.getU32("FMODExDecodeBufferSize")); @@ -219,6 +223,7 @@ void LLViewerAudio::stopInternetStreamWithAutoFade() if (gAudiop) { + LL_DEBUGS("AudioEngine") << "Stop audio fade" << LL_ENDL; gAudiop->startInternetStream(LLStringUtil::null); gAudiop->stopInternetStream(); } diff --git a/indra/newview/llviewerinput.cpp b/indra/newview/llviewerinput.cpp index 94ec534732..1a08b1a56c 100644 --- a/indra/newview/llviewerinput.cpp +++ b/indra/newview/llviewerinput.cpp @@ -816,13 +816,20 @@ bool toggle_enable_media(EKeystate s) bool walk_to(EKeystate s) { - if (KEYSTATE_DOWN != s) return true; + if (KEYSTATE_DOWN != s) + { + // teleport/walk is usually on mouseclick, mouseclick needs + // to let AGENT_CONTROL_LBUTTON_UP happen if teleport didn't, + // so return false, but if it causes issues, do some kind of + // "return !has_teleported" + return false; + } return LLToolPie::getInstance()->walkToClickedLocation(); } bool teleport_to(EKeystate s) { - if (KEYSTATE_DOWN != s) return true; + if (KEYSTATE_DOWN != s) return false; return LLToolPie::getInstance()->teleportToClickedLocation(); } @@ -850,7 +857,47 @@ bool voice_follow_key(EKeystate s) return false; } -bool agen_control_lbutton_handle(EKeystate s) +bool script_trigger_lbutton(EKeystate s) +{ + // Check for script overriding/expecting left mouse button. + // Note that this does not pass event further and depends onto mouselook. + // Checks CONTROL_ML_LBUTTON_DOWN_INDEX for mouselook, + // CONTROL_LBUTTON_DOWN_INDEX for normal camera + if (gAgent.leftButtonGrabbed()) + { + bool mouselook = gAgentCamera.cameraMouselook(); + switch (s) + { + case KEYSTATE_DOWN: + if (mouselook) + { + gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN); + } + else + { + gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN); + } + return true; + case KEYSTATE_UP: + if (mouselook) + { + gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_UP); + } + else + { + gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_UP); + } + return true; + default: + break; + } + } + return false; +} + +// Used by scripts, for overriding/handling left mouse button +// see mControlsTakenCount +bool agent_control_lbutton_handle(EKeystate s) { switch (s) { @@ -922,6 +969,7 @@ REGISTER_KEYBOARD_ACTION("teleport_to", teleport_to); REGISTER_KEYBOARD_ACTION("walk_to", walk_to); REGISTER_KEYBOARD_GLOBAL_ACTION("toggle_voice", toggle_voice); REGISTER_KEYBOARD_GLOBAL_ACTION("voice_follow_key", voice_follow_key); +REGISTER_KEYBOARD_ACTION(script_mouse_handler_name, script_trigger_lbutton); #undef REGISTER_KEYBOARD_ACTION LLViewerInput::LLViewerInput() @@ -1193,6 +1241,20 @@ BOOL LLViewerInput::bindMouse(const S32 mode, const EMouseClickType mouse, const typedef boost::function<bool(EKeystate)> function_t; function_t function = NULL; + if (mouse == CLICK_LEFT + && mask == MASK_NONE + && function_name == script_mouse_handler_name) + { + // Special case + // Left click has script overrides and by default + // is handled via agent_control_lbutton as last option + // In case of mouselook and present overrides it has highest + // priority even over UI and is handled in LLToolCompGun::handleMouseDown + // so just mark it as having default handler + mLMouseDefaultHandling[mode] = true; + return TRUE; + } + LLKeybindFunctionData* result = LLKeyboardActionRegistry::getValue(function_name); if (result) { @@ -1269,7 +1331,8 @@ LLViewerInput::Keys::Keys() : first_person("first_person"), third_person("third_person"), sitting("sitting"), - edit_avatar("edit_avatar") + edit_avatar("edit_avatar"), + xml_version("xml_version", 0) {} void LLViewerInput::resetBindings() @@ -1280,6 +1343,7 @@ void LLViewerInput::resetBindings() mGlobalMouseBindings[i].clear(); mKeyBindings[i].clear(); mMouseBindings[i].clear(); + mLMouseDefaultHandling[i] = false; } } @@ -1298,6 +1362,16 @@ S32 LLViewerInput::loadBindingsXML(const std::string& filename) binding_count += loadBindingMode(keys.third_person, MODE_THIRD_PERSON); binding_count += loadBindingMode(keys.sitting, MODE_SITTING); binding_count += loadBindingMode(keys.edit_avatar, MODE_EDIT_AVATAR); + + // verify version + if (keys.xml_version < 1) + { + // updating from a version that was not aware of LMouse bindings + for (S32 i = 0; i < MODE_COUNT; i++) + { + mLMouseDefaultHandling[i] = true; + } + } } return binding_count; } @@ -1469,17 +1543,6 @@ bool LLViewerInput::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level) bool res = scanKey(mKeyBindings[mode], mKeyBindings[mode].size(), key, mask, key_down, key_up, key_level, repeat); - if (!res && agent_control_lbutton.canHandle(CLICK_NONE, key, mask)) - { - if (key_down && !repeat) - { - res = agen_control_lbutton_handle(KEYSTATE_DOWN); - } - if (key_up) - { - res = agen_control_lbutton_handle(KEYSTATE_UP); - } - } return res; } @@ -1603,29 +1666,36 @@ bool LLViewerInput::scanMouse(EMouseClickType click, EMouseState state) const bool res = false; S32 mode = getMode(); MASK mask = gKeyboard->currentMask(TRUE); - - // By default mouse clicks require exact mask - // Todo: support for mIgnoreMasks because some functions like teleports - // expect to be canceled, but for voice it's prefered to ignore mask. res = scanMouse(mMouseBindings[mode], mMouseBindings[mode].size(), click, mask, state, false); - // no user defined actions found or those actions can't handle the key/button, handle control if nessesary - if (!res && agent_control_lbutton.canHandle(click, KEY_NONE, mask)) + + // No user defined actions found or those actions can't handle the key/button, + // so handle CONTROL_LBUTTON if nessesary. + // + // Default handling for MODE_FIRST_PERSON is in LLToolCompGun::handleMouseDown, + // and sends AGENT_CONTROL_ML_LBUTTON_DOWN, but it only applies if ML controls + // are leftButtonGrabbed(), send a normal click otherwise. + + if (!res + && mLMouseDefaultHandling[mode] + && (mode != MODE_FIRST_PERSON || !gAgent.leftButtonGrabbed()) + && (click == CLICK_LEFT || click == CLICK_DOUBLELEFT) + ) { switch (state) { case MOUSE_STATE_DOWN: - agen_control_lbutton_handle(KEYSTATE_DOWN); + agent_control_lbutton_handle(KEYSTATE_DOWN); res = true; break; case MOUSE_STATE_CLICK: // might not work best with some functions, // but some function need specific states too specifically - agen_control_lbutton_handle(KEYSTATE_DOWN); - agen_control_lbutton_handle(KEYSTATE_UP); + agent_control_lbutton_handle(KEYSTATE_DOWN); + agent_control_lbutton_handle(KEYSTATE_UP); res = true; break; case MOUSE_STATE_UP: - agen_control_lbutton_handle(KEYSTATE_UP); + agent_control_lbutton_handle(KEYSTATE_UP); res = true; break; default: @@ -1655,7 +1725,7 @@ void LLViewerInput::scanMouse() } } -bool LLViewerInput::isMouseBindUsed(const EMouseClickType mouse, const MASK mask, const S32 mode) +bool LLViewerInput::isMouseBindUsed(const EMouseClickType mouse, const MASK mask, const S32 mode) const { S32 size = mMouseBindings[mode].size(); for (S32 index = 0; index < size; index++) diff --git a/indra/newview/llviewerinput.h b/indra/newview/llviewerinput.h index ca70ac76bf..52e95e2168 100644 --- a/indra/newview/llviewerinput.h +++ b/indra/newview/llviewerinput.h @@ -31,6 +31,8 @@ #include "llinitparam.h" const S32 MAX_KEY_BINDINGS = 128; // was 60 +const S32 keybindings_xml_version = 1; +const std::string script_mouse_handler_name = "script_trigger_lbutton"; class LLNamedFunction { @@ -100,7 +102,7 @@ public: third_person, sitting, edit_avatar; - + Optional<S32> xml_version; // 'xml', because 'version' appears to be reserved Keys(); }; @@ -131,7 +133,8 @@ public: BOOL handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down); void scanMouse(); - bool isMouseBindUsed(const EMouseClickType mouse, const MASK mask = MASK_NONE, const S32 mode = MODE_THIRD_PERSON); + bool isMouseBindUsed(const EMouseClickType mouse, const MASK mask, const S32 mode) const; + bool isLMouseHandlingDefault(const S32 mode) const { return mLMouseDefaultHandling[mode]; } private: bool scanKey(const std::vector<LLKeyboardBinding> &binding, @@ -171,6 +174,7 @@ private: // to send what we think function wants based on collection of bools (mKeyRepeated, mKeyLevel, mKeyDown) std::vector<LLKeyboardBinding> mKeyBindings[MODE_COUNT]; std::vector<LLMouseBinding> mMouseBindings[MODE_COUNT]; + bool mLMouseDefaultHandling[MODE_COUNT]; // Due to having special priority // keybindings that do not consume event and are handled earlier, before floaters std::vector<LLKeyboardBinding> mGlobalKeyBindings[MODE_COUNT]; diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 4efc3d1cb3..4da1bcf541 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -549,13 +549,8 @@ class LLFileUploadModel : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLFloaterModelPreview* fmp = (LLFloaterModelPreview*) LLFloaterReg::getInstance("upload_model"); - if (fmp && !fmp->isModelLoading()) - { - fmp->loadHighLodModel(); - } - - return TRUE; + LLFloaterModelPreview::showModelPreview(); + return TRUE; } }; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 0f409701d1..97b8538bfb 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -3001,12 +3001,12 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("ObjectAnimation"); capabilityNames.append("ObjectMedia"); capabilityNames.append("ObjectMediaNavigate"); - capabilityNames.append("ObjectNavMeshProperties"); capabilityNames.append("ParcelPropertiesUpdate"); capabilityNames.append("ParcelVoiceInfoRequest"); capabilityNames.append("ProductInfoRequest"); capabilityNames.append("ProvisionVoiceAccountRequest"); capabilityNames.append("ReadOfflineMsgs"); // Requires to respond reliably: AcceptFriendship, AcceptGroupInvite, DeclineFriendship, DeclineGroupInvite + capabilityNames.append("RegionObjects"); capabilityNames.append("RemoteParcelRequest"); capabilityNames.append("RenderMaterials"); capabilityNames.append("RequestTextureDownload"); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 92e8f8026d..544a059fe8 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -2290,6 +2290,9 @@ void LLViewerWindow::initWorldUI() LLPanelStandStopFlying* panel_stand_stop_flying = LLPanelStandStopFlying::getInstance(); panel_ssf_container->addChild(panel_stand_stop_flying); + LLPanelHideBeacon* panel_hide_beacon = LLPanelHideBeacon::getInstance(); + panel_ssf_container->addChild(panel_hide_beacon); + panel_ssf_container->setVisible(TRUE); LLMenuOptionPathfindingRebakeNavmesh::getInstance()->initialize(); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 5d994058c2..d421b3b1f6 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1323,7 +1323,8 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) { LL_RECORD_BLOCK_TIME(FTM_AVATAR_EXTENT_UPDATE); - S32 box_detail = gSavedSettings.getS32("AvatarBoundingBoxComplexity"); + static LLCachedControl<S32> box_detail_cache(gSavedSettings, "AvatarBoundingBoxComplexity"); + S32 box_detail = box_detail_cache; if (getOverallAppearance() != AOA_NORMAL) { if (isControlAvatar()) @@ -2532,10 +2533,11 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time) { LL_INFOS() << "Warning! Idle on dead avatar" << LL_ENDL; return; - } + } + static LLCachedControl<bool> disable_all_render_types(gSavedSettings, "DisableAllRenderTypes"); if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR)) - && !(gSavedSettings.getBOOL("DisableAllRenderTypes")) && !isSelf()) + && !disable_all_render_types && !isSelf()) { return; } @@ -2676,7 +2678,8 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled) // Don't render the user's own voice visualizer when in mouselook, or when opening the mic is disabled. if(isSelf()) { - if(gAgentCamera.cameraMouselook() || gSavedSettings.getBOOL("VoiceDisableMic")) + static LLCachedControl<bool> voice_disable_mic(gSavedSettings, "VoiceDisableMic"); + if(gAgentCamera.cameraMouselook() || voice_disable_mic) { render_visualizer = false; } @@ -3145,11 +3148,14 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) } const F32 time_visible = mTimeVisible.getElapsedTimeF32(); - const F32 NAME_SHOW_TIME = gSavedSettings.getF32("RenderNameShowTime"); // seconds - const F32 FADE_DURATION = gSavedSettings.getF32("RenderNameFadeDuration"); // seconds - BOOL visible_avatar = isVisible() || mNeedsAnimUpdate; - BOOL visible_chat = gSavedSettings.getBOOL("UseChatBubbles") && (mChats.size() || mTyping); - BOOL render_name = visible_chat || + + static LLCachedControl<F32> NAME_SHOW_TIME(gSavedSettings, "RenderNameShowTime"); // seconds + static LLCachedControl<F32> FADE_DURATION(gSavedSettings, "RenderNameFadeDuration"); // seconds + static LLCachedControl<bool> use_chat_bubbles(gSavedSettings, "UseChatBubbles"); + + bool visible_avatar = isVisible() || mNeedsAnimUpdate; + bool visible_chat = use_chat_bubbles && (mChats.size() || mTyping); + bool render_name = visible_chat || (visible_avatar && ((sRenderName == RENDER_NAME_ALWAYS) || (sRenderName == RENDER_NAME_FADE && time_visible < NAME_SHOW_TIME))); @@ -3157,10 +3163,11 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) // draw if we're specifically hiding our own name. if (isSelf()) { + static LLCachedControl<bool> render_name_show_self(gSavedSettings, "RenderNameShowSelf"); + static LLCachedControl<S32> name_tag_mode(gSavedSettings, "AvatarNameTagMode"); render_name = render_name && !gAgentCamera.cameraMouselook() - && (visible_chat || (gSavedSettings.getBOOL("RenderNameShowSelf") - && gSavedSettings.getS32("AvatarNameTagMode") )); + && (visible_chat || (render_name_show_self && name_tag_mode)); } if ( !render_name ) @@ -3175,7 +3182,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) return; } - BOOL new_name = FALSE; + bool new_name = FALSE; if (visible_chat != mVisibleChat) { mVisibleChat = visible_chat; @@ -3240,7 +3247,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) idleUpdateNameTagAlpha(new_name, alpha); } -void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) +void LLVOAvatar::idleUpdateNameTagText(bool new_name) { LLNameValue *title = getNVPair("Title"); LLNameValue* firstname = getNVPair("FirstName"); @@ -3550,7 +3557,7 @@ void LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last) mNameText->setPositionAgent(name_position); } -void LLVOAvatar::idleUpdateNameTagAlpha(BOOL new_name, F32 alpha) +void LLVOAvatar::idleUpdateNameTagAlpha(bool new_name, F32 alpha) { llassert(mNameText); @@ -3693,7 +3700,8 @@ void LLVOAvatar::updateAppearanceMessageDebugText() { debug_line += llformat(" - cof: %d req: %d rcv:%d", curr_cof_version, last_request_cof_version, last_received_cof_version); - if (gSavedSettings.getBOOL("DebugForceAppearanceRequestFailure")) + static LLCachedControl<bool> debug_force_failure(gSavedSettings, "DebugForceAppearanceRequestFailure"); + if (debug_force_failure) { debug_line += " FORCING ERRS"; } @@ -5927,7 +5935,8 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL //} //else { - LLUUID sound_id = LLUUID(gSavedSettings.getString("UISndTyping")); + static LLCachedControl<std::string> ui_snd_string(gSavedSettings, "UISndTyping"); + LLUUID sound_id = LLUUID(ui_snd_string); gAudiop->triggerSound(sound_id, getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_SFX, char_pos_global); } } @@ -5995,7 +6004,7 @@ void LLVOAvatar::resetAnimations() // animations. LLUUID LLVOAvatar::remapMotionID(const LLUUID& id) { - BOOL use_new_walk_run = gSavedSettings.getBOOL("UseNewWalkRun"); + static LLCachedControl<bool> use_new_walk_run(gSavedSettings, "UseNewWalkRun"); LLUUID result = id; // start special case female walk for female avatars @@ -8183,7 +8192,8 @@ BOOL LLVOAvatar::isFullyLoaded() const bool LLVOAvatar::isTooComplex() const { bool too_complex; - bool render_friend = (LLAvatarTracker::instance().isBuddy(getID()) && gSavedSettings.getBOOL("AlwaysRenderFriends")); + static LLCachedControl<bool> always_render_friends(gSavedSettings, "AlwaysRenderFriends"); + bool render_friend = (LLAvatarTracker::instance().isBuddy(getID()) && always_render_friends); if (isSelf() || render_friend || mVisuallyMuteSetting == AV_ALWAYS_RENDER) { @@ -9036,7 +9046,8 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe // Parse visual params, if any. S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam); - bool drop_visual_params_debug = gSavedSettings.getBOOL("BlockSomeAvatarAppearanceVisualParams") && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing + static LLCachedControl<bool> block_some_avatars(gSavedSettings, "BlockSomeAvatarAppearanceVisualParams"); + bool drop_visual_params_debug = block_some_avatars && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing if( num_blocks > 1 && !drop_visual_params_debug) { //LL_DEBUGS("Avatar") << avString() << " handle visual params, num_blocks " << num_blocks << LL_ENDL; @@ -9141,10 +9152,12 @@ bool resolve_appearance_version(const LLAppearanceMessageContents& contents, S32 void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) { LL_DEBUGS("Avatar") << "starts" << LL_ENDL; - - bool enable_verbose_dumps = gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"); + + static LLCachedControl<bool> enable_verbose_dumps(gSavedSettings, "DebugAvatarAppearanceMessage"); + static LLCachedControl<bool> block_avatar_appearance_messages(gSavedSettings, "BlockAvatarAppearanceMessages"); + std::string dump_prefix = getFullname() + "_" + (isSelf()?"s":"o") + "_"; - if (gSavedSettings.getBOOL("BlockAvatarAppearanceMessages")) + if (block_avatar_appearance_messages) { LL_WARNS() << "Blocking AvatarAppearance message" << LL_ENDL; return; diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 74ef589ca4..96a8372188 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -284,9 +284,9 @@ public: void idleUpdateLoadingEffect(); void idleUpdateWindEffect(); void idleUpdateNameTag(const LLVector3& root_pos_last); - void idleUpdateNameTagText(BOOL new_name); + void idleUpdateNameTagText(bool new_name); void idleUpdateNameTagPosition(const LLVector3& root_pos_last); - void idleUpdateNameTagAlpha(BOOL new_name, F32 alpha); + void idleUpdateNameTagAlpha(bool new_name, F32 alpha); LLColor4 getNameTagColor(bool is_friend); void clearNameTag(); static void invalidateNameTag(const LLUUID& agent_id); @@ -908,7 +908,7 @@ public: void startTyping() { mTyping = TRUE; mTypingTimer.reset(); } void stopTyping() { mTyping = FALSE; } private: - BOOL mVisibleChat; + bool mVisibleChat; //-------------------------------------------------------------------- // Lip synch morphs diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp index b8f1ec35f6..c4d873dd22 100644 --- a/indra/newview/llweb.cpp +++ b/indra/newview/llweb.cpp @@ -199,19 +199,16 @@ std::string LLWeb::expandURLSubstitutions(const std::string &url, // find the grid std::string current_grid = LLGridManager::getInstance()->getGridId(); std::transform(current_grid.begin(), current_grid.end(), current_grid.begin(), ::tolower); - if (current_grid == "agni") + if (current_grid == "damballah") { - substitution["GRID"] = "secondlife.com"; - } - else if (current_grid == "damballah") - { - // Staging grid has its own naming scheme. - substitution["GRID"] = "secondlife-staging.com"; - } - else - { - substitution["GRID"] = llformat("%s.lindenlab.com", current_grid.c_str()); - } + // Staging grid has its own naming scheme. + substitution["GRID"] = "secondlife-staging.com"; + } + else + { + substitution["GRID"] = "secondlife.com"; + } + // expand all of the substitution strings and escape the url std::string expanded_url = url; LLStringUtil::format(expanded_url, substitution); diff --git a/indra/newview/skins/default/xui/en/control_table_contents_media.xml b/indra/newview/skins/default/xui/en/control_table_contents_media.xml index ce5d3556b6..43e8d730cd 100644 --- a/indra/newview/skins/default/xui/en/control_table_contents_media.xml +++ b/indra/newview/skins/default/xui/en/control_table_contents_media.xml @@ -73,4 +73,14 @@ name="lst_action" value="Start Gesture" /> </rows> + <rows + name="script_trigger_lbutton" + value="script_trigger_lbutton"> + <columns + column="lst_action" + font="SansSerif" + halign="left" + name="lst_action" + value="Interact (Script LMB)" /> + </rows> </contents> diff --git a/indra/newview/skins/default/xui/en/floater_associate_listing.xml b/indra/newview/skins/default/xui/en/floater_associate_listing.xml index e019ed58dd..0f7ed24103 100644 --- a/indra/newview/skins/default/xui/en/floater_associate_listing.xml +++ b/indra/newview/skins/default/xui/en/floater_associate_listing.xml @@ -20,9 +20,10 @@ name="message"> Listing ID: </text> + <!--listing_id is a positive S32--> <line_editor type="string" - length="1" + max_length_bytes="10" follows="top|right" font="SansSerif" height="20" diff --git a/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml b/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml index c609e3bd3a..31c524c38a 100644 --- a/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml +++ b/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml @@ -342,6 +342,7 @@ width="25"> <button name="skip_back_btn" + enabled="false" follows="top" image_overlay="SkipBackward_Off" image_disabled="PushButton_Disabled" @@ -373,6 +374,7 @@ width="25"> <button name="play_btn" + enabled="false" follows="top" image_overlay="Play_Off" image_disabled="PushButton_Disabled" @@ -434,6 +436,7 @@ width="25"> <button name="skip_forward_btn" + enabled="false" follows="top" image_overlay="SkipForward_Off" image_disabled="PushButton_Disabled" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index d4f71fb370..9d520d5f9a 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -2296,6 +2296,7 @@ Please try again later. <notification icon="notifytip.tga" name="LandmarkCreated" + log_to_chat="false" type="notifytip"> You have added "[LANDMARK_NAME]" to your [FOLDER_NAME] folder. </notification> @@ -8765,6 +8766,13 @@ See SecondLife.log for details type="alert"> Error while requesting mesh upload permissons. </notification> + + <notification + name="MeshUploadProfilerError" + icon="alert.tga" + type="alert"> +Mesh uploader is incompatible with RenderGLCoreProfile, please turn RenderGLCoreProfile off in debug settings and restart the viewer. + </notification> <notification name="RegionCapabilityRequestError" diff --git a/indra/newview/skins/default/xui/en/panel_hide_beacon.xml b/indra/newview/skins/default/xui/en/panel_hide_beacon.xml new file mode 100644 index 0000000000..cb22719cef --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_hide_beacon.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + height="25" + layout="topleft" + name="panel_hide_beacon" + mouse_opaque="false" + visible="true" + width="133"> + <button + follows="left|bottom" + height="19" + label="Hide beacon" + layout="topleft" + left="10" + name="hide_beacon_btn" + tool_tip="Stop tracking and hide beacon" + top="2" + visible="true" + width="113" /> +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml index 2ea20570b1..42a34d171a 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml @@ -28,7 +28,7 @@ height="15" increment="0.025" initial_value="0.5" - label="Master volume" + label="All volume" label_width="120" layout="topleft" left="0" @@ -386,7 +386,7 @@ left="25" name="voice_chat_settings" width="200" - top_pad="7"> + top_pad="16"> Voice Chat Settings </text> <text diff --git a/indra/newview/skins/default/xui/en/panel_toolbar_view.xml b/indra/newview/skins/default/xui/en/panel_toolbar_view.xml index f5c559fe1d..a3348f28c7 100644 --- a/indra/newview/skins/default/xui/en/panel_toolbar_view.xml +++ b/indra/newview/skins/default/xui/en/panel_toolbar_view.xml @@ -95,7 +95,7 @@ tab_stop="false" name="state_management_buttons_container" visible="false" - width="200"/> + width="350"/> </layout_panel> <layout_panel name="right_toolbar_panel" auto_resize="false" diff --git a/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml index 2034409111..b4eb1ade94 100644 --- a/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml +++ b/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml @@ -19,7 +19,7 @@ height="15" increment="0.025" initial_value="0.5" - label="Master" + label="All" label_width="60" left="10" width="160" diff --git a/indra/test/sync.h b/indra/test/sync.h index ca8b7262d6..bd837cb730 100644 --- a/indra/test/sync.h +++ b/indra/test/sync.h @@ -89,25 +89,26 @@ public: /// suspend until "somebody else" has bumped mCond by n steps void yield(int n=1) { - return yield_until(STRINGIZE("Sync::yield_for(" << n << ") timed out after " - << int(mTimeout.value()) << "ms"), - mCond.get() + n); + return yield_until("Sync::yield_for", n, mCond.get() + n); } /// suspend until "somebody else" has bumped mCond to a specific value void yield_until(int until) { - return yield_until(STRINGIZE("Sync::yield_until(" << until << ") timed out after " - << int(mTimeout.value()) << "ms"), - until); + return yield_until("Sync::yield_until", until, until); } private: - void yield_until(const std::string& desc, int until) + void yield_until(const char* func, int arg, int until) { std::string name(llcoro::logname()); LL_DEBUGS() << name << " yield_until(" << until << ") suspending" << LL_ENDL; - tut::ensure(name + ' ' + desc, mCond.wait_for_equal(mTimeout, until)); + if (! mCond.wait_for_equal(mTimeout, until)) + { + tut::fail(STRINGIZE(name << ' ' << func << '(' << arg << ") timed out after " + << int(mTimeout.value()) << "ms (expected " << until + << ", actual " << mCond.get() << ')')); + } // each time we wake up, bump mCond bump(); } |