diff options
Diffstat (limited to 'indra')
61 files changed, 927 insertions, 543 deletions
| 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/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..13f8749b9f 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1918,9 +1918,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 +2268,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 +2352,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/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..15d5473c41 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -748,7 +748,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/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..b1229d90a3 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> 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();      } | 
