diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index 515605200ed4fef1a3316601fa5a3797410fe136..b0a072c00e0902f992bbeeb536badb61cab3f927 100644
--- a/indra/llui/lltoolbar.cpp
+++ b/indra/llui/lltoolbar.cpp
@@ -112,6 +112,7 @@ LLToolBar::LLToolBar(const LLToolBar::Params& p)
 	mStartDragItemCallback(NULL),
 	mHandleDragItemCallback(NULL),
 	mHandleDropCallback(NULL),
+	mButtonAddSignal(NULL),
 	mDragAndDropTarget(false)
 {
 	mButtonParams[LLToolBarEnums::BTNTYPE_ICONS_WITH_TEXT] = p.button_icon_and_text;
@@ -121,6 +122,7 @@ LLToolBar::LLToolBar(const LLToolBar::Params& p)
 LLToolBar::~LLToolBar()
 {
 	delete mPopupMenuHandle.get();
+	delete mButtonAddSignal;
 }
 
 void LLToolBar::createContextMenu()
@@ -212,7 +214,6 @@ bool LLToolBar::addCommand(const LLCommandId& commandId, int rank)
 	mButtonPanel->addChild(button);
 	mButtonMap.insert(std::make_pair(commandId.uuid(), button));
 
-
 	// Insert the command and button in the right place in their respective lists
 	if ((rank >= mButtonCommands.size()) || (rank == RANK_NONE))
 	{
@@ -236,6 +237,11 @@ bool LLToolBar::addCommand(const LLCommandId& commandId, int rank)
 		mButtons.insert(it_button,button);
 	}
 
+	if (mButtonAddSignal)
+	{
+		(*mButtonAddSignal)(button);
+	}
+
 	mNeedsLayout = true;
 
 	return true;
@@ -898,6 +904,12 @@ LLToolBarButton* LLToolBar::createButton(const LLCommandId& id)
 	return button;
 }
 
+boost::signals2::connection LLToolBar::setButtonAddCallback(const button_add_signal_t::slot_type& cb)
+{
+	if (!mButtonAddSignal) mButtonAddSignal = new button_add_signal_t();
+	return mButtonAddSignal->connect(cb);
+}
+
 BOOL LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 										EDragAndDropType cargo_type,
 										void* cargo_data,
diff --git a/indra/llui/lltoolbar.h b/indra/llui/lltoolbar.h
index e634e57f93802d90456f8e519bb0417ed7cbb6c9..68fc44ee8ee5856f4b966dfda06f05e17e85147a 100644
--- a/indra/llui/lltoolbar.h
+++ b/indra/llui/lltoolbar.h
@@ -195,6 +195,9 @@ class LLToolBar
 
 	LLToolBarButton* createButton(const LLCommandId& id);
 
+	typedef boost::signals2::signal<void (LLView* button)> button_add_signal_t;
+	boost::signals2::connection setButtonAddCallback(const button_add_signal_t::slot_type& cb);
+
 	bool hasButtons() const { return !mButtons.empty(); }
 	bool isModified() const { return mModified; }
 
@@ -255,6 +258,8 @@ class LLToolBar
 	LLToolBarButton::Params			mButtonParams[LLToolBarEnums::BTNTYPE_COUNT];
 
 	LLHandle<class LLContextMenu>			mPopupMenuHandle;
+
+	button_add_signal_t*			mButtonAddSignal;
 };
 
 
diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp
index 619d17efad4b5f803d1be4fe3da4849d7a4406bd..affa7241d1e78a1ee4e6d0a38b7585c504dad803 100644
--- a/indra/newview/lltoolbarview.cpp
+++ b/indra/newview/lltoolbarview.cpp
@@ -35,6 +35,7 @@
 #include "lltoolbar.h"
 #include "llbutton.h"
 #include "lltooldraganddrop.h"
+#include "lltransientfloatermgr.h"
 #include "llclipboard.h"
 
 #include "llagent.h"  // HACK for destinations guide on startup
@@ -96,14 +97,17 @@ BOOL LLToolBarView::postBuild()
 	mToolbarLeft->setStartDragCallback(boost::bind(LLToolBarView::startDragTool,_1,_2,_3));
 	mToolbarLeft->setHandleDragCallback(boost::bind(LLToolBarView::handleDragTool,_1,_2,_3,_4));
 	mToolbarLeft->setHandleDropCallback(boost::bind(LLToolBarView::handleDropTool,_1,_2,_3,_4));
+	mToolbarLeft->setButtonAddCallback(boost::bind(LLToolBarView::onToolBarButtonAdded, _1));
 	
 	mToolbarRight->setStartDragCallback(boost::bind(LLToolBarView::startDragTool,_1,_2,_3));
 	mToolbarRight->setHandleDragCallback(boost::bind(LLToolBarView::handleDragTool,_1,_2,_3,_4));
 	mToolbarRight->setHandleDropCallback(boost::bind(LLToolBarView::handleDropTool,_1,_2,_3,_4));
+	mToolbarRight->setButtonAddCallback(boost::bind(LLToolBarView::onToolBarButtonAdded, _1));
 	
 	mToolbarBottom->setStartDragCallback(boost::bind(LLToolBarView::startDragTool,_1,_2,_3));
 	mToolbarBottom->setHandleDragCallback(boost::bind(LLToolBarView::handleDragTool,_1,_2,_3,_4));
 	mToolbarBottom->setHandleDropCallback(boost::bind(LLToolBarView::handleDropTool,_1,_2,_3,_4));
+	mToolbarBottom->setButtonAddCallback(boost::bind(LLToolBarView::onToolBarButtonAdded, _1));
 
 	LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&handleLoginToolbarSetup));
 	
@@ -314,6 +318,22 @@ void LLToolBarView::addToToolset(command_id_list_t& command_list, Toolbar& toolb
 	}
 }
 
+void LLToolBarView::onToolBarButtonAdded(LLView* button)
+{
+	if (button && button->getName() == "speak")
+	{
+		// Add the "Speak" button as a control view in LLTransientFloaterMgr
+		// to prevent hiding the transient IM floater upon pressing "Speak".
+		LLTransientFloaterMgr::getInstance()->addControlView(button);
+	}
+	else if (button && button->getName() == "voice")
+	{
+		// Add the "Voice controls" button as a control view in LLTransientFloaterMgr
+		// to prevent hiding the transient IM floater upon pressing "Voice controls".
+		LLTransientFloaterMgr::getInstance()->addControlView(button);
+	}
+}
+
 void LLToolBarView::draw()
 {
 	//LLPanel* sizer_left = getChild<LLPanel>("sizer_left");
diff --git a/indra/newview/lltoolbarview.h b/indra/newview/lltoolbarview.h
index 60ad6316f85e23630bedbabdc409d91705d48704..8cafbc93082dd335054654dfd09194640228909a 100644
--- a/indra/newview/lltoolbarview.h
+++ b/indra/newview/lltoolbarview.h
@@ -94,6 +94,8 @@ class LLToolBarView : public LLUICtrl
 	bool	addCommand(const LLCommandId& commandId, LLToolBar*	toolbar);
 	void	addToToolset(command_id_list_t& command_list, Toolbar& toolbar) const;
 
+	static void	onToolBarButtonAdded(LLView* button);
+
 	// Pointers to the toolbars handled by the toolbar view
 	LLToolBar*	mToolbarLeft;
 	LLToolBar*	mToolbarRight;
diff --git a/indra/newview/lltransientfloatermgr.cpp b/indra/newview/lltransientfloatermgr.cpp
index c648a6a28adc892ced97913667ebcf0cb61c36b3..d15efb048b43e8c9ea3c1d2d0feda979028d077d 100644
--- a/indra/newview/lltransientfloatermgr.cpp
+++ b/indra/newview/lltransientfloatermgr.cpp
@@ -42,9 +42,9 @@ LLTransientFloaterMgr::LLTransientFloaterMgr()
 			&LLTransientFloaterMgr::leftMouseClickCallback, this, _2, _3, _4));
 	}
 
-	mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(GLOBAL, std::set<LLView*>()));
-	mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(DOCKED, std::set<LLView*>()));
-	mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(IM, std::set<LLView*>()));
+	mGroupControls.insert(std::pair<ETransientGroup, controls_set_t >(GLOBAL, controls_set_t()));
+	mGroupControls.insert(std::pair<ETransientGroup, controls_set_t >(DOCKED, controls_set_t()));
+	mGroupControls.insert(std::pair<ETransientGroup, controls_set_t >(IM, controls_set_t()));
 }
 
 void LLTransientFloaterMgr::registerTransientFloater(LLTransientFloater* floater)
@@ -59,12 +59,16 @@ void LLTransientFloaterMgr::unregisterTransientFloater(LLTransientFloater* float
 
 void LLTransientFloaterMgr::addControlView(ETransientGroup group, LLView* view)
 {
-	mGroupControls.find(group)->second.insert(view);
+	if (!view) return;
+
+	mGroupControls.find(group)->second.insert(view->getHandle());
 }
 
 void LLTransientFloaterMgr::removeControlView(ETransientGroup group, LLView* view)
 {
-	mGroupControls.find(group)->second.erase(view);
+	if (!view) return;
+
+	mGroupControls.find(group)->second.erase(view->getHandle());
 }
 
 void LLTransientFloaterMgr::addControlView(LLView* view)
@@ -89,7 +93,7 @@ void LLTransientFloaterMgr::hideTransientFloaters(S32 x, S32 y)
 		{
 			ETransientGroup group = floater->getGroup();
 
-			bool hide = isControlClicked(mGroupControls.find(group)->second, x, y);
+			bool hide = isControlClicked(group, mGroupControls.find(group)->second, x, y);
 			if (hide)
 			{
 				floater->setTransientVisible(FALSE);
@@ -98,13 +102,23 @@ void LLTransientFloaterMgr::hideTransientFloaters(S32 x, S32 y)
 	}
 }
 
-bool LLTransientFloaterMgr::isControlClicked(std::set<LLView*>& set, S32 x, S32 y)
+bool LLTransientFloaterMgr::isControlClicked(ETransientGroup group, controls_set_t& set, S32 x, S32 y)
 {
 	bool res = true;
 	for (controls_set_t::iterator it = set.begin(); it
 			!= set.end(); it++)
 	{
-		LLView* control_view = *it;
+		LLView* control_view = NULL;
+
+		LLHandle<LLView> handle = *it;
+		if (handle.isDead())
+		{
+			mGroupControls.find(group)->second.erase(handle);
+			continue;
+		}
+
+		control_view = handle.get();
+
 		if (!control_view->getVisible())
 		{
 			continue;
@@ -130,8 +144,8 @@ void LLTransientFloaterMgr::leftMouseClickCallback(S32 x, S32 y,
 		return;
 	}
 
-	bool hide = isControlClicked(mGroupControls.find(DOCKED)->second, x, y)
-			&& isControlClicked(mGroupControls.find(GLOBAL)->second, x, y);
+	bool hide = isControlClicked(DOCKED, mGroupControls.find(DOCKED)->second, x, y)
+			&& isControlClicked(GLOBAL, mGroupControls.find(GLOBAL)->second, x, y);
 	if (hide)
 	{
 		hideTransientFloaters(x, y);
diff --git a/indra/newview/lltransientfloatermgr.h b/indra/newview/lltransientfloatermgr.h
index 2919244121bdbe80dd0979a8f18d76344f42ecae..b4611c8c87bb4d2954938fba16110e08d9c72a06 100644
--- a/indra/newview/lltransientfloatermgr.h
+++ b/indra/newview/lltransientfloatermgr.h
@@ -56,14 +56,15 @@ class LLTransientFloaterMgr: public LLSingleton<LLTransientFloaterMgr>
 	void removeControlView(LLView* view);
 
 private:
+	typedef std::set<LLHandle<LLView> > controls_set_t;
+	typedef std::map<ETransientGroup, controls_set_t > group_controls_t;
+
 	void hideTransientFloaters(S32 x, S32 y);
 	void leftMouseClickCallback(S32 x, S32 y, MASK mask);
-	bool isControlClicked(std::set<LLView*>& set, S32 x, S32 y);
-private:
+	bool isControlClicked(ETransientGroup group, controls_set_t& set, S32 x, S32 y);
+
 	std::set<LLTransientFloater*> mTransSet;
 
-	typedef std::set<LLView*> controls_set_t;
-	typedef std::map<ETransientGroup, std::set<LLView*> > group_controls_t;
 	group_controls_t mGroupControls;
 };