From 41a30a59fb1b6dea2d531333d0429632f1fef2fe Mon Sep 17 00:00:00 2001
From: Richard Nelson <none@none>
Date: Tue, 2 Mar 2010 14:21:58 -0800
Subject: initial work changing topctrl to popup layer

---
 indra/llui/llcombobox.cpp                        |  7 +--
 indra/llui/llfloater.cpp                         | 15 +----
 indra/llui/llfocusmgr.cpp                        | 47 +--------------
 indra/llui/llfocusmgr.h                          |  8 +--
 indra/llui/llhandle.h                            |  7 +++
 indra/llui/llmodaldialog.cpp                     |  6 +-
 indra/llui/llui.cpp                              | 29 +++++++++
 indra/llui/llui.h                                | 10 +++
 indra/llui/llview.cpp                            |  5 --
 indra/newview/CMakeLists.txt                     |  2 +
 indra/newview/llappviewer.cpp                    |  6 +-
 indra/newview/llexpandabletextbox.cpp            | 15 +----
 indra/newview/llexpandabletextbox.h              |  5 --
 indra/newview/llfolderview.cpp                   | 13 ++--
 indra/newview/llpanelnearbymedia.cpp             | 22 -------
 indra/newview/llpanelnearbymedia.h               |  1 -
 indra/newview/llprogressview.cpp                 |  5 +-
 indra/newview/llsplitbutton.cpp                  |  7 +--
 indra/newview/lluploaddialog.cpp                 |  2 +-
 indra/newview/llviewerwindow.cpp                 | 77 ++++++++++++++++--------
 indra/newview/llviewerwindow.h                   |  9 ++-
 indra/newview/skins/default/xui/en/main_view.xml | 13 ++--
 22 files changed, 146 insertions(+), 165 deletions(-)

diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index 9d23daf56d..de3bf719ee 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -615,7 +615,7 @@ void LLComboBox::showList()
 	// register ourselves as a "top" control
 	// effectively putting us into a special draw layer
 	// and not affecting the bounding rectangle calculation
-	gFocusMgr.setTopCtrl(this);
+	LLUI::addPopup(this);
 
 	// Show the list and push the button down
 	mButton->setToggleState(TRUE);
@@ -644,10 +644,7 @@ void LLComboBox::hideList()
 		mList->mouseOverHighlightNthItem(-1);
 
 		setUseBoundingRect(FALSE);
-		if( gFocusMgr.getTopCtrl() == this )
-		{
-			gFocusMgr.setTopCtrl(NULL);
-		}
+		LLUI::removePopup(this);
 	}
 }
 
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index b6d73cda3c..b93b72abf6 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -527,10 +527,7 @@ void LLFloater::setVisible( BOOL visible )
 
 	if( !visible )
 	{
-		if( gFocusMgr.childIsTopCtrl( this ) )
-		{
-			gFocusMgr.setTopCtrl(NULL);
-		}
+		LLUI::removePopup(this);
 
 		if( gFocusMgr.childHasMouseCapture( this ) )
 		{
@@ -704,10 +701,7 @@ void LLFloater::reshape(S32 width, S32 height, BOOL called_from_parent)
 
 void LLFloater::releaseFocus()
 {
-	if( gFocusMgr.childIsTopCtrl( this ) )
-	{
-		gFocusMgr.setTopCtrl(NULL);
-	}
+	LLUI::removePopup(this);
 
 	setFocus(FALSE);
 
@@ -2503,10 +2497,7 @@ void LLFloaterView::syncFloaterTabOrder()
 	if (modal_dialog)
 	{
 		// If we have a visible modal dialog, make sure that it has focus
-		if( gFocusMgr.getTopCtrl() != modal_dialog )
-		{
-			gFocusMgr.setTopCtrl( modal_dialog );
-		}
+		LLUI::addPopup(modal_dialog);
 		
 		if( !gFocusMgr.childHasKeyboardFocus( modal_dialog ) )
 		{
diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp
index 35fbc7b0a8..ad2940e685 100644
--- a/indra/llui/llfocusmgr.cpp
+++ b/indra/llui/llfocusmgr.cpp
@@ -38,8 +38,6 @@
 
 const F32 FOCUS_FADE_TIME = 0.3f;
 
-// NOTE: the LLFocusableElement implementation has been moved here from lluictrl.cpp.
-
 LLFocusableElement::LLFocusableElement()
 :	mFocusLostCallback(NULL),
 	mFocusReceivedCallback(NULL),
@@ -124,8 +122,7 @@ boost::signals2::connection	LLFocusableElement::setTopLostCallback(const focus_s
 LLFocusMgr gFocusMgr;
 
 LLFocusMgr::LLFocusMgr()
-	:
-	mLockedView( NULL ),
+:	mLockedView( NULL ),
 	mMouseCaptor( NULL ),
 	mKeyboardFocus( NULL ),
 	mLastKeyboardFocus( NULL ),
@@ -133,16 +130,11 @@ LLFocusMgr::LLFocusMgr()
 	mKeystrokesOnly(FALSE),
 	mTopCtrl( NULL ),
 	mAppHasFocus(TRUE)   // Macs don't seem to notify us that we've gotten focus, so default to true
-	#ifdef _DEBUG
-		, mMouseCaptorName("none")
-		, mKeyboardFocusName("none")
-		, mTopCtrlName("none")
-	#endif
 {
 }
 
 
-void LLFocusMgr::releaseFocusIfNeeded( const LLView* view )
+void LLFocusMgr::releaseFocusIfNeeded( LLView* view )
 {
 	if( childHasMouseCapture( view ) )
 	{
@@ -162,10 +154,7 @@ void LLFocusMgr::releaseFocusIfNeeded( const LLView* view )
 		}
 	}
 
-	if( childIsTopCtrl( view ) )
-	{
-		setTopCtrl( NULL );
-	}
+	LLUI::removePopup(view);
 }
 
 
@@ -248,11 +237,6 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL
 			return;
 		}
 
-		#ifdef _DEBUG
-			LLUICtrl* focus_ctrl = dynamic_cast<LLUICtrl*>(new_focus);
-			mKeyboardFocusName = focus_ctrl ? focus_ctrl->getName() : std::string("none");
-		#endif
-
 		// If we've got a default keyboard focus, and the caller is
 		// releasing keyboard focus, move to the default.
 		if (mDefaultKeyboardFocus != NULL && mKeyboardFocus == NULL)
@@ -334,20 +318,12 @@ void LLFocusMgr::removeKeyboardFocusWithoutCallback( const LLFocusableElement* f
 	if( mKeyboardFocus == focus )
 	{
 		mKeyboardFocus = NULL;
-		#ifdef _DEBUG
-			mKeyboardFocusName = std::string("none");
-		#endif
 	}
 }
 
 
 void LLFocusMgr::setMouseCapture( LLMouseHandler* new_captor )
 {
-	//if (mFocusLocked)
-	//{
-	//	return;
-	//}
-
 	if( new_captor != mMouseCaptor )
 	{
 		LLMouseHandler* old_captor = mMouseCaptor;
@@ -370,24 +346,14 @@ void LLFocusMgr::setMouseCapture( LLMouseHandler* new_captor )
 			old_captor->onMouseCaptureLost();
 		}
 
-		#ifdef _DEBUG
-			mMouseCaptorName = new_captor ? new_captor->getName() : std::string("none");
-		#endif
 	}
 }
 
 void LLFocusMgr::removeMouseCaptureWithoutCallback( const LLMouseHandler* captor )
 {
-	//if (mFocusLocked)
-	//{
-	//	return;
-	//}
 	if( mMouseCaptor == captor )
 	{
 		mMouseCaptor = NULL;
-		#ifdef _DEBUG
-			mMouseCaptorName = std::string("none");
-		#endif
 	}
 }
 
@@ -416,10 +382,6 @@ void LLFocusMgr::setTopCtrl( LLUICtrl* new_top  )
 	{
 		mTopCtrl = new_top;
 
-		#ifdef _DEBUG
-			mTopCtrlName = new_top ? new_top->getName() : std::string("none");
-		#endif
-
 		if (old_top)
 		{
 			old_top->onTopLost();
@@ -432,9 +394,6 @@ void LLFocusMgr::removeTopCtrlWithoutCallback( const LLUICtrl* top_view )
 	if( mTopCtrl == top_view )
 	{
 		mTopCtrl = NULL;
-		#ifdef _DEBUG
-			mTopCtrlName = std::string("none");
-		#endif
 	}
 }
 
diff --git a/indra/llui/llfocusmgr.h b/indra/llui/llfocusmgr.h
index 83ecd1d301..5b08c628d4 100644
--- a/indra/llui/llfocusmgr.h
+++ b/indra/llui/llfocusmgr.h
@@ -119,7 +119,7 @@ public:
 	BOOL			childIsTopCtrl( const LLView* parent ) const;
 
 	// All Three
-	void			releaseFocusIfNeeded( const LLView* top_view );
+	void			releaseFocusIfNeeded( LLView* top_view );
 	void			lockFocus();
 	void			unlockFocus();
 	BOOL			focusLocked() const { return mLockedView != NULL; }
@@ -149,12 +149,6 @@ private:
 
 	typedef std::map<LLHandle<LLView>, LLHandle<LLView> > focus_history_map_t;
 	focus_history_map_t mFocusHistory;
-
-	#ifdef _DEBUG
-		std::string		mMouseCaptorName;
-		std::string		mKeyboardFocusName;
-		std::string		mTopCtrlName;
-	#endif
 };
 
 extern LLFocusMgr gFocusMgr;
diff --git a/indra/llui/llhandle.h b/indra/llui/llhandle.h
index 899f6b9326..8ade327044 100644
--- a/indra/llui/llhandle.h
+++ b/indra/llui/llhandle.h
@@ -67,6 +67,13 @@ public:
 		return *this; 
 	}
 
+	template<typename Subclass>
+	LLHandle<T>& operator =(const LLHandle<Subclass>& other)  
+	{ 
+		mTombStone = other.mTombStone;
+		return *this; 
+	}
+
 	bool isDead() const 
 	{ 
 		return mTombStone->getTarget() == NULL; 
diff --git a/indra/llui/llmodaldialog.cpp b/indra/llui/llmodaldialog.cpp
index 387af05935..6cff68c20b 100644
--- a/indra/llui/llmodaldialog.cpp
+++ b/indra/llui/llmodaldialog.cpp
@@ -111,7 +111,7 @@ void LLModalDialog::onOpen(const LLSD& key)
 	
 		// This is a modal dialog.  It sucks up all mouse and keyboard operations.
 		gFocusMgr.setMouseCapture( this );
-		gFocusMgr.setTopCtrl( this );
+		LLUI::addPopup(this);
 		setFocus(TRUE);
 
 		sModalStack.push_front( this );
@@ -153,7 +153,7 @@ void LLModalDialog::setVisible( BOOL visible )
 			gFocusMgr.setMouseCapture( this );
 
 			// The dialog view is a root view
-			gFocusMgr.setTopCtrl( this );
+			LLUI::addPopup(this);
 			setFocus( TRUE );
 		}
 		else
@@ -291,7 +291,7 @@ void LLModalDialog::onAppFocusGained()
 		// This is a modal dialog.  It sucks up all mouse and keyboard operations.
 		gFocusMgr.setMouseCapture( instance );
 		instance->setFocus(TRUE);
-		gFocusMgr.setTopCtrl( instance );
+		LLUI::addPopup(instance);
 
 		instance->centerOnScreen();
 	}
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index b348ec2d29..64df1dbc7a 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -86,6 +86,9 @@ std::list<std::string> gUntranslated;
 /*static*/ LLHelp*			LLUI::sHelpImpl = NULL;
 /*static*/ std::vector<std::string> LLUI::sXUIPaths;
 /*static*/ LLFrameTimer		LLUI::sMouseIdleTimer;
+/*static*/ LLUI::add_popup_t	LLUI::sAddPopupFunc;
+/*static*/ LLUI::remove_popup_t	LLUI::sRemovePopupFunc;
+/*static*/ LLUI::clear_popups_t	LLUI::sClearPopupsFunc;
 
 // register filtereditor here
 static LLDefaultChildRegistry::Register<LLFilterEditor> register_filter_editor("filter_editor");
@@ -1607,6 +1610,13 @@ void LLUI::cleanupClass()
 	sImageProvider->cleanUp();
 }
 
+void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& remove_popup,  const clear_popups_t& clear_popups)
+{
+	sAddPopupFunc = add_popup;
+	sRemovePopupFunc = remove_popup;
+	sClearPopupsFunc = clear_popups;
+}
+
 //static
 void LLUI::dirtyRect(LLRect rect)
 {
@@ -1877,6 +1887,25 @@ LLControlGroup& LLUI::getControlControlGroup (const std::string& controlname)
 	return *sSettingGroups["config"]; // default group
 }
 
+//static 
+void LLUI::addPopup(LLView* viewp)
+{
+	if (sAddPopupFunc)
+	{
+		sAddPopupFunc(viewp);
+	}
+}
+
+//static 
+void LLUI::removePopup(LLView* viewp)
+{
+	if (sRemovePopupFunc)
+	{
+		sRemovePopupFunc(viewp);
+	}
+}
+
+
 //static
 // spawn_x and spawn_y are top left corner of view in screen GL coordinates
 void LLUI::positionViewNearMouse(LLView* view, S32 spawn_x, S32 spawn_y)
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index af8d4ea03b..824d76f526 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -160,12 +160,17 @@ public:
 	// Methods
 	//
 	typedef std::map<std::string, LLControlGroup*> settings_map_t;
+	typedef boost::function<void(LLView*)> add_popup_t;
+	typedef boost::function<void(LLView*)> remove_popup_t;
+	typedef boost::function<void(void)> clear_popups_t;
+
 	static void initClass(const settings_map_t& settings,
 						  LLImageProviderInterface* image_provider,
 						  LLUIAudioCallback audio_callback = NULL,
 						  const LLVector2 *scale_factor = NULL,
 						  const std::string& language = LLStringUtil::null);
 	static void cleanupClass();
+	static void setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t&, const clear_popups_t& );
 
 	static void pushMatrix();
 	static void popMatrix();
@@ -207,6 +212,8 @@ public:
 	static F32 getMouseIdleTime() { return sMouseIdleTimer.getElapsedTimeF32(); }
 	static void resetMouseIdleTimer() { sMouseIdleTimer.reset(); }
 	static LLWindow* getWindow() { return sWindow; }
+	static void addPopup(LLView*);
+	static void removePopup(LLView*);
 
 	// Ensures view does not overlap mouse cursor, but is inside
 	// the view's parent rectangle.  Used for tooltips, inspectors.
@@ -227,6 +234,9 @@ private:
 	static LLImageProviderInterface* sImageProvider;
 	static std::vector<std::string> sXUIPaths;
 	static LLFrameTimer		sMouseIdleTimer;
+	static add_popup_t		sAddPopupFunc;
+	static remove_popup_t	sRemovePopupFunc;
+	static clear_popups_t	sClearPopupsFunc;
 };
 
 
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 63e627ceb5..db2c460eec 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -592,11 +592,6 @@ void LLView::setVisible(BOOL visible)
 {
 	if ( mVisible != visible )
 	{
-		if( !visible && (gFocusMgr.getTopCtrl() == this) )
-		{
-			gFocusMgr.setTopCtrl( NULL );
-		}
-
 		mVisible = visible;
 
 		// notify children of visibility change if root, or part of visible hierarchy
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 14eb75e457..8ad3b2085d 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -347,6 +347,7 @@ set(viewer_SOURCE_FILES
     llpatchvertexarray.cpp
     llplacesinventorybridge.cpp
     llplacesinventorypanel.cpp
+    llpopupview.cpp
     llpolymesh.cpp
     llpolymorph.cpp
     llpreview.cpp
@@ -844,6 +845,7 @@ set(viewer_HEADER_FILES
     llplacesinventorypanel.h
     llpolymesh.h
     llpolymorph.h
+    llpopupview.h
     llpreview.h
     llpreviewanim.h
     llpreviewgesture.h
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 948d38befb..a06e54e208 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -702,9 +702,9 @@ bool LLAppViewer::init()
 	settings_map["account"] = &gSavedPerAccountSettings;
 
 	LLUI::initClass(settings_map,
-					LLUIImageList::getInstance(),
-					ui_audio_callback,
-					&LLUI::sGLScaleFactor);
+		LLUIImageList::getInstance(),
+		ui_audio_callback,
+		&LLUI::sGLScaleFactor);
 	
 	// Setup paths and LLTrans after LLUI::initClass has been called
 	LLUI::setupPaths();
diff --git a/indra/newview/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp
index 3818ee6f78..9a906d8323 100644
--- a/indra/newview/llexpandabletextbox.cpp
+++ b/indra/newview/llexpandabletextbox.cpp
@@ -35,6 +35,7 @@
 
 #include "llscrollcontainer.h"
 #include "llwindow.h"
+#include "llviewerwindow.h"
 
 static LLDefaultChildRegistry::Register<LLExpandableTextBox> t1("expandable_text");
 
@@ -382,7 +383,7 @@ void LLExpandableTextBox::expandTextBox()
 	setFocus(TRUE);
 	// this lets us receive top_lost event(needed to collapse text box)
 	// it also draws text box above all other ui elements
-	gFocusMgr.setTopCtrl(this);
+	gViewerWindow->addPopup(this);
 
 	mExpanded = true;
 }
@@ -401,10 +402,7 @@ void LLExpandableTextBox::collapseTextBox()
 
 	updateTextBoxRect();
 
-	if(gFocusMgr.getTopCtrl() == this)
-	{
-		gFocusMgr.setTopCtrl(NULL);
-	}
+	gViewerWindow->removePopup(this);
 }
 
 void LLExpandableTextBox::onFocusLost()
@@ -414,13 +412,6 @@ void LLExpandableTextBox::onFocusLost()
 	LLUICtrl::onFocusLost();
 }
 
-void LLExpandableTextBox::onTopLost()
-{
-	collapseTextBox();
-
-	LLUICtrl::onTopLost();
-}
-
 void LLExpandableTextBox::setValue(const LLSD& value)
 {
 	collapseTextBox();
diff --git a/indra/newview/llexpandabletextbox.h b/indra/newview/llexpandabletextbox.h
index 58316ddb98..690c500e84 100644
--- a/indra/newview/llexpandabletextbox.h
+++ b/indra/newview/llexpandabletextbox.h
@@ -139,11 +139,6 @@ public:
 	 */
 	/*virtual*/ void onFocusLost();
 
-	/**
-	 * Collapses text box on top_lost event
-	 */
-	/*virtual*/ void onTopLost();
-
 	/**
 	 * Draws text box, collapses text box if its expanded and its parent's position changed
 	 */
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 23f19a38a6..ff19a974bb 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -284,10 +284,7 @@ LLFolderView::~LLFolderView( void )
 
 	LLView::deleteViewByHandle(mPopupMenuHandle);
 
-	if(mRenamer == gFocusMgr.getTopCtrl())
-	{
-		gFocusMgr.setTopCtrl(NULL);
-	}
+	gViewerWindow->removePopup(mRenamer);
 
 	mAutoOpenItems.removeAllNodes();
 	clearSelection();
@@ -971,7 +968,7 @@ void LLFolderView::finishRenamingItem( void )
 		mRenameItem->rename( mRenamer->getText() );
 	}
 
-	gFocusMgr.setTopCtrl( NULL );	
+	gViewerWindow->removePopup(mRenamer);
 
 	if( mRenameItem )
 	{
@@ -988,7 +985,7 @@ void LLFolderView::closeRenamer( void )
 	// will commit current name (which could be same as original name)
 	mRenamer->setFocus( FALSE );
 	mRenamer->setVisible( FALSE );
-	gFocusMgr.setTopCtrl( NULL );
+	gViewerWindow->removePopup(mRenamer);
 
 	if( mRenameItem )
 	{
@@ -1420,7 +1417,7 @@ void LLFolderView::startRenamingSelectedItem( void )
 		mRenamer->setFocus( TRUE );
 		mRenamer->setTopLostCallback(boost::bind(onRenamerLost, _1));
 		mRenamer->setFocusLostCallback(boost::bind(onRenamerLost, _1));
-		gFocusMgr.setTopCtrl( mRenamer );
+		gViewerWindow->addPopup(mRenamer);
 	}
 }
 
@@ -1901,7 +1898,7 @@ void LLFolderView::deleteAllChildren()
 {
 	if(mRenamer == gFocusMgr.getTopCtrl())
 	{
-		gFocusMgr.setTopCtrl(NULL);
+		gViewerWindow->removePopup(mRenamer);
 	}
 	LLView::deleteViewByHandle(mPopupMenuHandle);
 	mPopupMenuHandle = LLHandle<LLView>();
diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp
index c02f154dc8..41e37a9b1b 100644
--- a/indra/newview/llpanelnearbymedia.cpp
+++ b/indra/newview/llpanelnearbymedia.cpp
@@ -193,28 +193,13 @@ void LLPanelNearByMedia::handleVisibilityChange ( BOOL new_visibility )
 	if (new_visibility)	
 	{
 		mHoverTimer.start(); // timer will be stopped when mouse hovers over panel
-		//gFocusMgr.setTopCtrl(this);
 	}
 	else
 	{
 		mHoverTimer.stop();
-		//if (gFocusMgr.getTopCtrl() == this)
-		//{
-		//	gFocusMgr.setTopCtrl(NULL);
-		//}
 	}
 }
 
-/*virtual*/ 
-void LLPanelNearByMedia::onTopLost ()
-{
-	//LLUICtrl* new_top = gFocusMgr.getTopCtrl();
-	//if (!new_top || !new_top->hasAncestor(this))
-	//{
-	//	setVisible(FALSE);
-	//}
-}
-
 /*virtual*/
 void LLPanelNearByMedia::reshape(S32 width, S32 height, BOOL called_from_parent)
 {
@@ -234,13 +219,6 @@ const F32 AUTO_CLOSE_FADE_TIME_END = 5.0f;
 /*virtual*/
 void LLPanelNearByMedia::draw()
 {
-	//LLUICtrl* new_top = gFocusMgr.getTopCtrl();
-	//if (new_top != this)
-	//{
-	//	// reassert top ctrl
-	//	gFocusMgr.setTopCtrl(this);
-	//}
-
 	// keep bottom of panel on screen
 	LLRect screen_rect = calcScreenRect();
 	if (screen_rect.mBottom < 0)
diff --git a/indra/newview/llpanelnearbymedia.h b/indra/newview/llpanelnearbymedia.h
index 4f864519f5..809a8d81a1 100644
--- a/indra/newview/llpanelnearbymedia.h
+++ b/indra/newview/llpanelnearbymedia.h
@@ -54,7 +54,6 @@ public:
 	/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
 	/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
 	/*virtual*/ void handleVisibilityChange ( BOOL new_visibility );
-	/*virtual*/ void onTopLost ();
 	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent);
 	/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
 
diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp
index 0476e785a5..15831d85a0 100644
--- a/indra/newview/llprogressview.cpp
+++ b/indra/newview/llprogressview.cpp
@@ -128,11 +128,14 @@ void LLProgressView::setVisible(BOOL visible)
 {
 	if (getVisible() && !visible)
 	{
+		gViewerWindow->removePopup(this);
+
 		mFadeTimer.start();
 	}
 	else if (!getVisible() && visible)
 	{
-		gFocusMgr.setTopCtrl(this);
+		gViewerWindow->addPopup(this);
+
 		setFocus(TRUE);
 		mFadeTimer.stop();
 		mProgressTimer.start();
diff --git a/indra/newview/llsplitbutton.cpp b/indra/newview/llsplitbutton.cpp
index ffd9bc7624..e5323db466 100644
--- a/indra/newview/llsplitbutton.cpp
+++ b/indra/newview/llsplitbutton.cpp
@@ -165,7 +165,7 @@ void LLSplitButton::showButtons()
 
 	// register ourselves as a "top" control
 	// effectively putting us into a special draw layer
-	gFocusMgr.setTopCtrl(this);
+	gViewerWindow->addPopup(this);
 
 	mItemsPanel->setFocus(TRUE);
 
@@ -182,10 +182,7 @@ void LLSplitButton::hideButtons()
 	mArrowBtn->setToggleState(FALSE);
 
 	setUseBoundingRect(FALSE);
-	if(gFocusMgr.getTopCtrl() == this)
-	{
-		gFocusMgr.setTopCtrl(NULL);
-	}
+	gViewerWindow->removePopup(this);
 }
 
 
diff --git a/indra/newview/lluploaddialog.cpp b/indra/newview/lluploaddialog.cpp
index 577b5952e5..22c7d670f8 100644
--- a/indra/newview/lluploaddialog.cpp
+++ b/indra/newview/lluploaddialog.cpp
@@ -91,7 +91,7 @@ LLUploadDialog::LLUploadDialog( const std::string& msg)
 	setMessage(msg);
 
 	// The dialog view is a root view
-	gFocusMgr.setTopCtrl( this );
+	gViewerWindow->addPopup(this);
 }
 
 void LLUploadDialog::setMessage( const std::string& msg)
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index f1ec489a20..5bd79c67c3 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -131,6 +131,7 @@
 #include "llmorphview.h"
 #include "llmoveview.h"
 #include "llnavigationbar.h"
+#include "llpopupview.h"
 #include "llpreviewtexture.h"
 #include "llprogressview.h"
 #include "llresmgr.h"
@@ -690,30 +691,30 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window,  LLCoordGL pos, MASK
 	}
 
 	// Topmost view gets a chance before the hierarchy
-	LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
-	if (top_ctrl)
-	{
-		S32 local_x, local_y;
-		top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
-		if (down)
-		{
-			if (top_ctrl->pointInView(local_x, local_y))
-			{
-				return top_ctrl->handleAnyMouseClick(local_x, local_y, mask, clicktype, down)	;
-			}
-			else
-			{
-				gFocusMgr.setTopCtrl(NULL);
-			}
-		}
-		else
-		{
-			if (top_ctrl->pointInView(local_x, local_y) && top_ctrl->handleMouseUp(local_x, local_y, mask))
-			{
-				return TRUE;
-			}
-		}
-	}
+	//LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
+	//if (top_ctrl)
+	//{
+	//	S32 local_x, local_y;
+	//	top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
+	//	if (down)
+	//	{
+	//		if (top_ctrl->pointInView(local_x, local_y))
+	//		{
+	//			return top_ctrl->handleAnyMouseClick(local_x, local_y, mask, clicktype, down)	;
+	//		}
+	//		else
+	//		{
+	//			gFocusMgr.setTopCtrl(NULL);
+	//		}
+	//	}
+	//	else
+	//	{
+	//		if (top_ctrl->pointInView(local_x, local_y) && top_ctrl->handleMouseUp(local_x, local_y, mask))
+	//		{
+	//			return TRUE;
+	//		}
+	//	}
+	//}
 
 	// Give the UI views a chance to process the click
 	if( mRootView->handleAnyMouseClick(x, y, mask, clicktype, down) )
@@ -1367,6 +1368,8 @@ LLViewerWindow::LLViewerWindow(
 	LLNotifications::instance().setIgnoreAllNotifications(gSavedSettings.getBOOL("IgnoreAllNotifications"));
 	llinfos << "NOTE: ALL NOTIFICATIONS THAT OCCUR WILL GET ADDED TO IGNORE LIST FOR LATER RUNS." << llendl;
 
+	LLUI::setPopupFuncs(boost::bind(&LLViewerWindow::addPopup, this, _1), boost::bind(&LLViewerWindow::removePopup, this, _1), boost::bind(&LLViewerWindow::clearPopups, this));
+
 	// Default to application directory.
 	LLViewerWindow::sSnapshotBaseName = "Snapshot";
 	LLViewerWindow::sMovieBaseName = "SLmovie";
@@ -1559,11 +1562,13 @@ void LLViewerWindow::initBase()
 	mWorldViewPlaceholder = main_view->getChildView("world_view_rect")->getHandle();
 	mNonSideTrayView = main_view->getChildView("non_side_tray_view")->getHandle();
 	mFloaterViewHolder = main_view->getChildView("floater_view_holder")->getHandle();
+	mPopupView = main_view->getChild<LLPopupView>("popup_holder");
 
 	// Constrain floaters to inside the menu and status bar regions.
 	gFloaterView = main_view->getChild<LLFloaterView>("Floater View");
 	gSnapshotFloaterView = main_view->getChild<LLSnapshotFloaterView>("Snapshot Floater View");
 	
+
 	// Console
 	llassert( !gConsole );
 	LLConsole::Params cp;
@@ -2433,6 +2438,30 @@ void LLViewerWindow::handleScrollWheel(S32 clicks)
 	return;
 }
 
+void LLViewerWindow::addPopup(LLView* popup)
+{
+	if (mPopupView)
+	{
+		mPopupView->addPopup(popup);
+	}
+}
+
+void LLViewerWindow::removePopup(LLView* popup)
+{
+	if (mPopupView)
+	{
+		mPopupView->removePopup(popup);
+	}
+}
+
+void LLViewerWindow::clearPopups()
+{
+	if (mPopupView)
+	{
+		mPopupView->clearPopups();
+	}
+}
+
 void LLViewerWindow::moveCursorToCenter()
 {
 	if (! gSavedSettings.getBOOL("DisableMouseWarp"))
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index bfce65f2ba..410445d97f 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -69,6 +69,7 @@ class LLHUDIcon;
 class LLWindow;
 class LLRootView;
 class LLViewerWindowListener;
+class LLPopupView;
 
 #define PICK_HALF_WIDTH 5
 #define PICK_DIAMETER (2 * PICK_HALF_WIDTH + 1)
@@ -300,6 +301,11 @@ public:
 	BOOL			handleKey(KEY key, MASK mask);
 	void			handleScrollWheel	(S32 clicks);
 
+	// add and remove views from "popup" layer
+	void			addPopup(LLView* popup);
+	void			removePopup(LLView* popup);
+	void			clearPopups();
+
 	// Hide normal UI when a logon fails, re-show everything when logon is attempted again
 	void			setNormalControlsVisible( BOOL visible );
 	void			setMenuBackgroundColor(bool god_mode = false, bool dev_grid = false);
@@ -458,6 +464,7 @@ protected:
 	LLHandle<LLView> mWorldViewPlaceholder;	// widget that spans the portion of screen dedicated to rendering the 3d world
 	LLHandle<LLView> mNonSideTrayView;		// parent of world view + bottom bar, etc...everything but the side tray
 	LLHandle<LLView> mFloaterViewHolder;	// container for floater_view
+	LLPopupView*	mPopupView;			// container for transient popups
 	
 	class LLDebugText* mDebugText; // Internal class for debug text
 	
@@ -477,7 +484,7 @@ protected:
 private:
 	// Object temporarily hovered over while dragging
 	LLPointer<LLViewerObject>	mDragHoveredObject;
-};	
+};
 
 void toggle_flying(void*);
 void toggle_first_person();
diff --git a/indra/newview/skins/default/xui/en/main_view.xml b/indra/newview/skins/default/xui/en/main_view.xml
index 7b6081d7be..85853f39bb 100644
--- a/indra/newview/skins/default/xui/en/main_view.xml
+++ b/indra/newview/skins/default/xui/en/main_view.xml
@@ -156,18 +156,19 @@
                    name="notify_container"
                    tab_group="-2"
                    width="1024"/>
-  <menu_holder top="0"
-               follows="all"
-               height="768"
-               mouse_opaque="false"
-               name="Menu Holder"
-               width="1024"/>
   <panel top="0"
          follows="all"
          height="768"
          mouse_opaque="false"
          name="popup_holder"
+         class="popup_holder"
          width="1024"/>
+  <menu_holder top="0"
+               follows="all"
+               height="768"
+               mouse_opaque="false"
+               name="Menu Holder"
+               width="1024"/>
   <snapshot_floater_view enabled="false"
                          follows="all"
                          height="768"
-- 
cgit v1.2.3


From c3c04adaa56c895018e1d2dd32b94469aaf44347 Mon Sep 17 00:00:00 2001
From: Richard Nelson <none@none>
Date: Tue, 2 Mar 2010 15:11:56 -0800
Subject: added missing files

---
 indra/newview/llpopupview.cpp | 202 ++++++++++++++++++++++++++++++++++++++++++
 indra/newview/llpopupview.h   |  64 +++++++++++++
 2 files changed, 266 insertions(+)
 create mode 100644 indra/newview/llpopupview.cpp
 create mode 100644 indra/newview/llpopupview.h

diff --git a/indra/newview/llpopupview.cpp b/indra/newview/llpopupview.cpp
new file mode 100644
index 0000000000..964ca4d361
--- /dev/null
+++ b/indra/newview/llpopupview.cpp
@@ -0,0 +1,202 @@
+/** 
+ * @file llpopupview.cpp
+ * @brief Holds transient popups
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ * 
+ * Copyright (c) 2001-2010, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#include "llviewerprecompiledheaders.h"
+
+#include "llpopupview.h"
+
+static LLRegisterPanelClassWrapper<LLPopupView> r("popup_holder");
+
+bool view_visible_and_enabled(LLView* viewp)
+{
+	return viewp->getVisible() && viewp->getEnabled();
+}
+
+bool view_visible(LLView* viewp)
+{
+	return viewp->getVisible();
+}
+
+
+LLPopupView::LLPopupView()
+{
+}
+
+void LLPopupView::draw()
+{
+	S32 screen_x, screen_y;
+
+	for (popup_list_t::iterator popup_it = mPopups.begin();
+		popup_it != mPopups.end();)
+	{
+		LLView* popup = popup_it->get();
+		if (!popup)
+		{
+			popup_list_t::iterator cur_popup_it = popup_it;
+			++popup_it;
+			mPopups.erase(cur_popup_it);
+			continue;
+		}
+
+		if (popup->getVisible())
+		{
+			popup->localPointToScreen(0, 0, &screen_x, &screen_y);
+
+			LLUI::pushMatrix();
+			{
+				LLUI::translate( (F32) screen_x, (F32) screen_y, 0.f);
+				popup->draw();
+			}
+			LLUI::popMatrix();
+		}
+		++popup_it;
+	}
+
+	LLPanel::draw();
+}
+
+BOOL LLPopupView::handleMouseEvent(boost::function<BOOL(LLView*, S32, S32)> func, 
+								   boost::function<bool(LLView*)> predicate, 
+								   S32 x, S32 y)
+{
+	for (popup_list_t::reverse_iterator popup_it = mPopups.rbegin();
+		popup_it != mPopups.rend();
+		++popup_it)
+	{
+		LLView* popup = popup_it->get();
+		if (!popup 
+			|| !predicate(popup))
+		{
+			continue;
+		}
+
+		S32 popup_x, popup_y;
+		if (localPointToOtherView(x, y, &popup_x, &popup_y, popup) 
+			&& popup->getRect().pointInRect(popup_x, popup_y))
+		{
+			if (func(popup, popup_x, popup_y))
+			{
+				return TRUE;
+			}
+		}
+	}
+
+	return FALSE;
+}
+
+
+BOOL LLPopupView::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+	if (!handleMouseEvent(boost::bind(&LLMouseHandler::handleMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y))
+	{
+		clearPopups();
+		return FALSE;
+	}
+	return TRUE;
+}
+
+BOOL LLPopupView::handleMouseUp(S32 x, S32 y, MASK mask)
+{
+	return handleMouseEvent(boost::bind(&LLMouseHandler::handleMouseUp, _1, _2, _3, mask), view_visible_and_enabled, x, y);
+}
+
+BOOL LLPopupView::handleMiddleMouseDown(S32 x, S32 y, MASK mask)
+{
+	if (!handleMouseEvent(boost::bind(&LLMouseHandler::handleMiddleMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y))
+	{
+		clearPopups();
+		return FALSE;
+	}
+	return TRUE;
+}
+
+BOOL LLPopupView::handleMiddleMouseUp(S32 x, S32 y, MASK mask)
+{
+	return handleMouseEvent(boost::bind(&LLMouseHandler::handleMiddleMouseUp, _1, _2, _3, mask), view_visible_and_enabled, x, y);
+}
+
+BOOL LLPopupView::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+	if (!handleMouseEvent(boost::bind(&LLMouseHandler::handleRightMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y))
+	{
+		clearPopups();
+		return FALSE;
+	}
+	return TRUE;
+}
+
+BOOL LLPopupView::handleRightMouseUp(S32 x, S32 y, MASK mask)
+{
+	return handleMouseEvent(boost::bind(&LLMouseHandler::handleRightMouseUp, _1, _2, _3, mask), view_visible_and_enabled, x, y);
+}
+
+BOOL LLPopupView::handleDoubleClick(S32 x, S32 y, MASK mask)
+{
+	return handleMouseEvent(boost::bind(&LLMouseHandler::handleDoubleClick, _1, _2, _3, mask), view_visible_and_enabled, x, y);
+}
+
+BOOL LLPopupView::handleHover(S32 x, S32 y, MASK mask)
+{
+	return handleMouseEvent(boost::bind(&LLMouseHandler::handleHover, _1, _2, _3, mask), view_visible_and_enabled, x, y);
+}
+
+BOOL LLPopupView::handleScrollWheel(S32 x, S32 y, S32 clicks)
+{
+	return handleMouseEvent(boost::bind(&LLMouseHandler::handleScrollWheel, _1, _2, _3, clicks), view_visible_and_enabled, x, y);
+}
+
+BOOL LLPopupView::handleToolTip(S32 x, S32 y, MASK mask)
+{
+	return handleMouseEvent(boost::bind(&LLMouseHandler::handleToolTip, _1, _2, _3, mask), view_visible, x, y);
+}
+
+void LLPopupView::addPopup(LLView* popup)
+{
+	removePopup(popup);
+	if (popup)
+	{
+		mPopups.push_back(popup->getHandle());
+	}
+}
+
+void LLPopupView::removePopup(LLView* popup)
+{
+	if (popup)
+	{
+		mPopups.erase(std::find(mPopups.begin(), mPopups.end(), popup->getHandle()));
+	}
+}
+
+void LLPopupView::clearPopups()
+{
+	mPopups.clear();
+}
+
diff --git a/indra/newview/llpopupview.h b/indra/newview/llpopupview.h
new file mode 100644
index 0000000000..591e033161
--- /dev/null
+++ b/indra/newview/llpopupview.h
@@ -0,0 +1,64 @@
+/** 
+ * @file llpopupview.h
+ * @brief Holds transient popups
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ * 
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPOPUPVIEW_H
+#define LL_LLPOPUPVIEW_H
+
+#include "llpanel.h"
+
+class LLPopupView : public LLPanel
+{
+public:
+	LLPopupView();
+
+	/*virtual*/ void draw();
+	/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+	/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
+	/*virtual*/ BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask);
+	/*virtual*/ BOOL handleMiddleMouseUp(S32 x, S32 y, MASK mask);
+	/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+	/*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
+	/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
+	/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
+	/*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
+	/*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask);
+
+	void addPopup(LLView* popup);
+	void removePopup(LLView* popup);
+	void clearPopups();
+
+private:
+	BOOL handleMouseEvent(boost::function<BOOL(LLView*, S32, S32)>, boost::function<bool(LLView*)>, S32 x, S32 y);
+	typedef std::list<LLHandle<LLView> > popup_list_t;
+	popup_list_t mPopups;
+};
+#endif //LL_LLROOTVIEW_H
-- 
cgit v1.2.3


From 69f9c0bcf9764a1b682bfdd5baa3f340922dcbaa Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 3 Mar 2010 19:37:41 -0800
Subject: WIP - replace top ctrl with LLPopupView

---
 indra/llui/llcombobox.cpp               | 14 ++++++++------
 indra/llui/llcombobox.h                 |  1 +
 indra/llui/llfloater.cpp                |  2 +-
 indra/llui/llfocusmgr.cpp               |  4 ++--
 indra/llui/llfocusmgr.h                 |  2 +-
 indra/llui/llui.cpp                     |  9 +++++++++
 indra/llui/llui.h                       |  2 ++
 indra/newview/llpanelnearbymedia.cpp    |  9 +++++++++
 indra/newview/llpanelnearbymedia.h      |  1 +
 indra/newview/llpanelvolumepulldown.cpp | 14 ++++++++------
 indra/newview/llpanelvolumepulldown.h   |  2 +-
 indra/newview/llpopupview.cpp           | 18 ++++++++++++++++--
 indra/newview/llpopupview.h             |  4 +++-
 indra/newview/llstatusbar.cpp           | 33 +++++++++++----------------------
 indra/newview/llviewerwindow.cpp        | 27 +++++++++++++++++++++++++++
 15 files changed, 100 insertions(+), 42 deletions(-)

diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index de3bf719ee..c679717807 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -160,7 +160,7 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p)
 
 	createLineEditor(p);
 
-	setTopLostCallback(boost::bind(&LLComboBox::hideList, this));
+	mTopLostSignalConnection = setTopLostCallback(boost::bind(&LLComboBox::hideList, this));
 }
 
 void LLComboBox::initFromParams(const LLComboBox::Params& p)
@@ -187,6 +187,9 @@ BOOL LLComboBox::postBuild()
 LLComboBox::~LLComboBox()
 {
 	// children automatically deleted, including mMenu, mButton
+
+	// explicitly disconect this signal, since base class destructor might fire top lost
+	mTopLostSignalConnection.disconnect();
 }
 
 
@@ -612,16 +615,14 @@ void LLComboBox::showList()
 
 	mList->setFocus(TRUE);
 
-	// register ourselves as a "top" control
-	// effectively putting us into a special draw layer
-	// and not affecting the bounding rectangle calculation
-	LLUI::addPopup(this);
-
 	// Show the list and push the button down
 	mButton->setToggleState(TRUE);
 	mList->setVisible(TRUE);
 	
+	LLUI::addPopup(this);
+
 	setUseBoundingRect(TRUE);
+	updateBoundingRect();
 }
 
 void LLComboBox::hideList()
@@ -645,6 +646,7 @@ void LLComboBox::hideList()
 
 		setUseBoundingRect(FALSE);
 		LLUI::removePopup(this);
+		updateBoundingRect();
 	}
 }
 
diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h
index 4f27588467..aa1e708bec 100644
--- a/indra/llui/llcombobox.h
+++ b/indra/llui/llcombobox.h
@@ -231,5 +231,6 @@ private:
 	commit_callback_t	mTextEntryCallback;
 	commit_callback_t	mSelectionCallback;
 	S32                 mLastSelectedIndex;
+	boost::signals2::connection mTopLostSignalConnection;
 };
 #endif
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index b93b72abf6..c45be34d43 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -1354,7 +1354,7 @@ void LLFloater::bringToFront( S32 x, S32 y )
 // virtual
 void LLFloater::setVisibleAndFrontmost(BOOL take_focus)
 {
-	gFocusMgr.setTopCtrl(NULL);
+	LLUI::clearPopups();
 	setVisible(TRUE);
 	setFrontmost(take_focus);
 }
diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp
index ad2940e685..b3af258456 100644
--- a/indra/llui/llfocusmgr.cpp
+++ b/indra/llui/llfocusmgr.cpp
@@ -437,9 +437,9 @@ void LLFocusMgr::setAppHasFocus(BOOL focus)
 	}
 	
 	// release focus from "top ctrl"s, which generally hides them
-	if (!focus && mTopCtrl)
+	if (!focus)
 	{
-		setTopCtrl(NULL);
+		LLUI::clearPopups();
 	}
 	mAppHasFocus = focus; 
 }
diff --git a/indra/llui/llfocusmgr.h b/indra/llui/llfocusmgr.h
index 5b08c628d4..86d3ccf111 100644
--- a/indra/llui/llfocusmgr.h
+++ b/indra/llui/llfocusmgr.h
@@ -65,10 +65,10 @@ public:
 	virtual BOOL	handleKey(KEY key, MASK mask, BOOL called_from_parent);
 	virtual BOOL	handleUnicodeChar(llwchar uni_char, BOOL called_from_parent);
 
+	virtual void	onTopLost();	// called when registered as top ctrl and user clicks elsewhere
 protected:	
 	virtual void	onFocusReceived();
 	virtual void	onFocusLost();
-	virtual void	onTopLost();	// called when registered as top ctrl and user clicks elsewhere
 	focus_signal_t*  mFocusLostCallback;
 	focus_signal_t*  mFocusReceivedCallback;
 	focus_signal_t*  mFocusChangedCallback;
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index 64df1dbc7a..5121ef5351 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -1905,6 +1905,15 @@ void LLUI::removePopup(LLView* viewp)
 	}
 }
 
+//static
+void LLUI::clearPopups()
+{
+	if (sClearPopupsFunc)
+	{
+		sClearPopupsFunc();
+	}
+}
+
 
 //static
 // spawn_x and spawn_y are top left corner of view in screen GL coordinates
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index 824d76f526..30f3623ded 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -212,8 +212,10 @@ public:
 	static F32 getMouseIdleTime() { return sMouseIdleTimer.getElapsedTimeF32(); }
 	static void resetMouseIdleTimer() { sMouseIdleTimer.reset(); }
 	static LLWindow* getWindow() { return sWindow; }
+
 	static void addPopup(LLView*);
 	static void removePopup(LLView*);
+	static void clearPopups();
 
 	// Ensures view does not overlap mouse cursor, but is inside
 	// the view's parent rectangle.  Used for tooltips, inspectors.
diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp
index 41e37a9b1b..4bbecc4799 100644
--- a/indra/newview/llpanelnearbymedia.cpp
+++ b/indra/newview/llpanelnearbymedia.cpp
@@ -82,6 +82,8 @@ LLPanelNearByMedia::LLPanelNearByMedia()
 	  mParcelMediaItem(NULL),
 	  mParcelAudioItem(NULL)
 {
+	mHoverTimer.stop();
+
 	mParcelAudioAutoStart = gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) &&
 							gSavedSettings.getBOOL("MediaTentativeAutoPlay");
 
@@ -187,6 +189,13 @@ void LLPanelNearByMedia::onMouseLeave(S32 x, S32 y, MASK mask)
 	LLPanel::onMouseLeave(x,y,mask);
 }
 
+/*virtual*/ 
+void LLPanelNearByMedia::onTopLost()
+{
+	setVisible(FALSE);
+}
+
+
 /*virtual*/ 
 void LLPanelNearByMedia::handleVisibilityChange ( BOOL new_visibility )
 {
diff --git a/indra/newview/llpanelnearbymedia.h b/indra/newview/llpanelnearbymedia.h
index 809a8d81a1..af4659365f 100644
--- a/indra/newview/llpanelnearbymedia.h
+++ b/indra/newview/llpanelnearbymedia.h
@@ -53,6 +53,7 @@ public:
 	/*virtual*/ void draw();
 	/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
 	/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
+	/*virtual*/ void onTopLost();
 	/*virtual*/ void handleVisibilityChange ( BOOL new_visibility );
 	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent);
 	/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
diff --git a/indra/newview/llpanelvolumepulldown.cpp b/indra/newview/llpanelvolumepulldown.cpp
index 559997254e..ae52bd3703 100644
--- a/indra/newview/llpanelvolumepulldown.cpp
+++ b/indra/newview/llpanelvolumepulldown.cpp
@@ -56,6 +56,8 @@
 // Default constructor
 LLPanelVolumePulldown::LLPanelVolumePulldown()
 {
+	mHoverTimer.stop();
+
     mCommitCallbackRegistrar.add("Vol.setControlFalse", boost::bind(&LLPanelVolumePulldown::setControlFalse, this, _2));
 	mCommitCallbackRegistrar.add("Vol.GoAudioPrefs", boost::bind(&LLPanelVolumePulldown::onAdvancedButtonClick, this, _2));
 	LLUICtrlFactory::instance().buildPanel(this, "panel_volume_pulldown.xml");
@@ -77,6 +79,11 @@ void LLPanelVolumePulldown::onMouseEnter(S32 x, S32 y, MASK mask)
 	LLPanel::onMouseEnter(x,y,mask);
 }
 
+/*virtual*/
+void LLPanelVolumePulldown::onTopLost()
+{
+	setVisible(FALSE);
+}
 
 /*virtual*/
 void LLPanelVolumePulldown::onMouseLeave(S32 x, S32 y, MASK mask)
@@ -95,13 +102,8 @@ void LLPanelVolumePulldown::handleVisibilityChange ( BOOL new_visibility )
 	else
 	{
 		mHoverTimer.stop();
-	}
-}
 
-/*virtual*/ 
-void LLPanelVolumePulldown::onTopLost()
-{
-	setVisible(FALSE);
+	}
 }
 
 void LLPanelVolumePulldown::onAdvancedButtonClick(const LLSD& user_data)
diff --git a/indra/newview/llpanelvolumepulldown.h b/indra/newview/llpanelvolumepulldown.h
index 9f20caa1a8..7fb025f329 100644
--- a/indra/newview/llpanelvolumepulldown.h
+++ b/indra/newview/llpanelvolumepulldown.h
@@ -47,8 +47,8 @@ class LLPanelVolumePulldown : public LLPanel
 	/*virtual*/ void draw();
 	/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
 	/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
-	/*virtual*/ void handleVisibilityChange ( BOOL new_visibility );
 	/*virtual*/ void onTopLost();
+	/*virtual*/ void handleVisibilityChange ( BOOL new_visibility );
 	/*virtual*/ BOOL postBuild();
 	
  private:
diff --git a/indra/newview/llpopupview.cpp b/indra/newview/llpopupview.cpp
index 964ca4d361..eb750a87e2 100644
--- a/indra/newview/llpopupview.cpp
+++ b/indra/newview/llpopupview.cpp
@@ -100,7 +100,7 @@ BOOL LLPopupView::handleMouseEvent(boost::function<BOOL(LLView*, S32, S32)> func
 
 		S32 popup_x, popup_y;
 		if (localPointToOtherView(x, y, &popup_x, &popup_y, popup) 
-			&& popup->getRect().pointInRect(popup_x, popup_y))
+			&& popup->pointInView(popup_x, popup_y))
 		{
 			if (func(popup, popup_x, popup_y))
 			{
@@ -180,9 +180,9 @@ BOOL LLPopupView::handleToolTip(S32 x, S32 y, MASK mask)
 
 void LLPopupView::addPopup(LLView* popup)
 {
-	removePopup(popup);
 	if (popup)
 	{
+		mPopups.erase(std::find(mPopups.begin(), mPopups.end(), popup->getHandle()));
 		mPopups.push_back(popup->getHandle());
 	}
 }
@@ -191,12 +191,26 @@ void LLPopupView::removePopup(LLView* popup)
 {
 	if (popup)
 	{
+		if (gFocusMgr.childHasKeyboardFocus(popup))
+		{
+			gFocusMgr.setKeyboardFocus(NULL);
+		}
+		popup->onTopLost();
 		mPopups.erase(std::find(mPopups.begin(), mPopups.end(), popup->getHandle()));
 	}
 }
 
 void LLPopupView::clearPopups()
 {
+	for (popup_list_t::iterator popup_it = mPopups.begin();
+		popup_it != mPopups.end();)
+	{
+		LLView* popup = popup_it->get();
+		++popup_it;
+
+		if (popup) popup->onTopLost();
+	}
+
 	mPopups.clear();
 }
 
diff --git a/indra/newview/llpopupview.h b/indra/newview/llpopupview.h
index 591e033161..c5dbb94c4c 100644
--- a/indra/newview/llpopupview.h
+++ b/indra/newview/llpopupview.h
@@ -56,9 +56,11 @@ public:
 	void removePopup(LLView* popup);
 	void clearPopups();
 
+	typedef std::list<LLHandle<LLView> > popup_list_t;
+	popup_list_t getCurrentPopups() { return mPopups; }
+
 private:
 	BOOL handleMouseEvent(boost::function<BOOL(LLView*, S32, S32)>, boost::function<bool(LLView*)>, S32 x, S32 y);
-	typedef std::list<LLHandle<LLView> > popup_list_t;
 	popup_list_t mPopups;
 };
 #endif //LL_LLROOTVIEW_H
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index 732c23982b..2ed0718e41 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -239,20 +239,16 @@ BOOL LLStatusBar::postBuild()
 
 	childSetActionTextbox("stat_btn", onClickStatGraph);
 
-	LLView* popup_holder = gViewerWindow->getRootView()->getChildView("popup_holder");
-
 	mPanelVolumePulldown = new LLPanelVolumePulldown();
-	popup_holder->addChild(mPanelVolumePulldown);
+	addChild(mPanelVolumePulldown);
+	mPanelVolumePulldown->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT);
+	mPanelVolumePulldown->setVisible(FALSE);
 
 	mPanelNearByMedia = new LLPanelNearByMedia();
-	popup_holder->addChild(mPanelNearByMedia);
-	gViewerWindow->getRootView()->addMouseDownCallback(boost::bind(&LLStatusBar::onClickScreen, this, _1, _2));
+	addChild(mPanelNearByMedia);
 	mPanelNearByMedia->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT);
 	mPanelNearByMedia->setVisible(FALSE);
 
-	mPanelVolumePulldown->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT);
-	mPanelVolumePulldown->setVisible(FALSE);
-
 	return TRUE;
 }
 
@@ -538,8 +534,10 @@ void LLStatusBar::onMouseEnterVolume()
 
 
 	// show the master volume pull-down
-	mPanelVolumePulldown->setVisible(TRUE);
+	LLUI::clearPopups();
+	LLUI::addPopup(mPanelVolumePulldown);
 	mPanelNearByMedia->setVisible(FALSE);
+	mPanelVolumePulldown->setVisible(TRUE);
 }
 
 void LLStatusBar::onMouseEnterNearbyMedia()
@@ -558,8 +556,11 @@ void LLStatusBar::onMouseEnterNearbyMedia()
 	
 	// show the master volume pull-down
 	mPanelNearByMedia->setShape(nearby_media_rect);
-	mPanelNearByMedia->setVisible(TRUE);
+	LLUI::clearPopups();
+	LLUI::addPopup(mPanelNearByMedia);
+
 	mPanelVolumePulldown->setVisible(FALSE);
+	mPanelNearByMedia->setVisible(TRUE);
 }
 
 
@@ -648,18 +649,6 @@ void LLStatusBar::onClickStatGraph(void* data)
 	LLFloaterReg::showInstance("lagmeter");
 }
 
-void LLStatusBar::onClickScreen(S32 x, S32 y)
-{
-	if (mPanelNearByMedia->getVisible())
-	{
-		LLRect screen_rect = mPanelNearByMedia->calcScreenRect();
-		if (!screen_rect.pointInRect(x, y))
-		{
-			mPanelNearByMedia->setVisible(FALSE);
-		}
-	}
-}
-
 BOOL can_afford_transaction(S32 cost)
 {
 	return((cost <= 0)||((gStatusBar) && (gStatusBar->getBalance() >=cost)));
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 5bd79c67c3..1304a66397 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2590,6 +2590,33 @@ void LLViewerWindow::updateUI()
 	}
 
 	// aggregate visible views that contain mouse cursor in display order
+	LLPopupView::popup_list_t popups = mPopupView->getCurrentPopups();
+
+	for(LLPopupView::popup_list_t::iterator popup_it = popups.begin(); popup_it != popups.end(); ++popup_it)
+	{
+		LLView* popup = popup_it->get();
+		if (popup && popup->calcScreenBoundingRect().pointInRect(x, y))
+		{
+			// iterator over contents of top_ctrl, and throw into mouse_hover_set
+			for (LLView::tree_iterator_t it = popup->beginTreeDFS();
+				it != popup->endTreeDFS();
+				++it)
+			{
+				LLView* viewp = *it;
+				if (viewp->getVisible()
+					&& viewp->calcScreenBoundingRect().pointInRect(x, y))
+				{
+					// we have a view that contains the mouse, add it to the set
+					mouse_hover_set.insert(viewp->getHandle());
+				}
+				else
+				{
+					// skip this view and all of its children
+					it.skipDescendants();
+				}
+			}
+		}
+	}
 
 	// while the top_ctrl contains the mouse cursor, only it and its descendants will receive onMouseEnter events
 	if (top_ctrl && top_ctrl->calcScreenBoundingRect().pointInRect(x, y))
-- 
cgit v1.2.3


From 0bbcb0d22d2a215e0d8bf824b44a18a8bd948f20 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 3 Mar 2010 20:23:26 -0800
Subject: resizing and nesting of popups now work

---
 indra/newview/llpopupview.cpp | 64 +++++++++++++++++++++++++------------------
 indra/newview/llpopupview.h   |  2 +-
 indra/newview/llstatusbar.cpp | 10 +++----
 3 files changed, 43 insertions(+), 33 deletions(-)

diff --git a/indra/newview/llpopupview.cpp b/indra/newview/llpopupview.cpp
index eb750a87e2..3494522969 100644
--- a/indra/newview/llpopupview.cpp
+++ b/indra/newview/llpopupview.cpp
@@ -54,17 +54,25 @@ void LLPopupView::draw()
 {
 	S32 screen_x, screen_y;
 
+	// remove dead popups
 	for (popup_list_t::iterator popup_it = mPopups.begin();
 		popup_it != mPopups.end();)
 	{
-		LLView* popup = popup_it->get();
-		if (!popup)
+		if (!popup_it->get())
 		{
-			popup_list_t::iterator cur_popup_it = popup_it;
-			++popup_it;
-			mPopups.erase(cur_popup_it);
-			continue;
+			mPopups.erase(popup_it++);
+		}
+		else
+		{
+			popup_it++;
 		}
+	}
+
+	// draw in reverse order (most recent is on top)
+	for (popup_list_t::reverse_iterator popup_it = mPopups.rbegin();
+		popup_it != mPopups.rend();)
+	{
+		LLView* popup = popup_it->get();
 
 		if (popup->getVisible())
 		{
@@ -85,16 +93,17 @@ void LLPopupView::draw()
 
 BOOL LLPopupView::handleMouseEvent(boost::function<BOOL(LLView*, S32, S32)> func, 
 								   boost::function<bool(LLView*)> predicate, 
-								   S32 x, S32 y)
+								   S32 x, S32 y,
+								   bool close_popups)
 {
-	for (popup_list_t::reverse_iterator popup_it = mPopups.rbegin();
-		popup_it != mPopups.rend();
-		++popup_it)
+	for (popup_list_t::iterator popup_it = mPopups.begin();
+		popup_it != mPopups.end();)
 	{
 		LLView* popup = popup_it->get();
 		if (!popup 
 			|| !predicate(popup))
 		{
+			++popup_it;
 			continue;
 		}
 
@@ -107,6 +116,9 @@ BOOL LLPopupView::handleMouseEvent(boost::function<BOOL(LLView*, S32, S32)> func
 				return TRUE;
 			}
 		}
+
+		popup->onTopLost();
+		mPopups.erase(popup_it++);
 	}
 
 	return FALSE;
@@ -115,9 +127,8 @@ BOOL LLPopupView::handleMouseEvent(boost::function<BOOL(LLView*, S32, S32)> func
 
 BOOL LLPopupView::handleMouseDown(S32 x, S32 y, MASK mask)
 {
-	if (!handleMouseEvent(boost::bind(&LLMouseHandler::handleMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y))
+	if (!handleMouseEvent(boost::bind(&LLMouseHandler::handleMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y, true))
 	{
-		clearPopups();
 		return FALSE;
 	}
 	return TRUE;
@@ -125,14 +136,13 @@ BOOL LLPopupView::handleMouseDown(S32 x, S32 y, MASK mask)
 
 BOOL LLPopupView::handleMouseUp(S32 x, S32 y, MASK mask)
 {
-	return handleMouseEvent(boost::bind(&LLMouseHandler::handleMouseUp, _1, _2, _3, mask), view_visible_and_enabled, x, y);
+	return handleMouseEvent(boost::bind(&LLMouseHandler::handleMouseUp, _1, _2, _3, mask), view_visible_and_enabled, x, y, false);
 }
 
 BOOL LLPopupView::handleMiddleMouseDown(S32 x, S32 y, MASK mask)
 {
-	if (!handleMouseEvent(boost::bind(&LLMouseHandler::handleMiddleMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y))
+	if (!handleMouseEvent(boost::bind(&LLMouseHandler::handleMiddleMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y, true))
 	{
-		clearPopups();
 		return FALSE;
 	}
 	return TRUE;
@@ -140,14 +150,13 @@ BOOL LLPopupView::handleMiddleMouseDown(S32 x, S32 y, MASK mask)
 
 BOOL LLPopupView::handleMiddleMouseUp(S32 x, S32 y, MASK mask)
 {
-	return handleMouseEvent(boost::bind(&LLMouseHandler::handleMiddleMouseUp, _1, _2, _3, mask), view_visible_and_enabled, x, y);
+	return handleMouseEvent(boost::bind(&LLMouseHandler::handleMiddleMouseUp, _1, _2, _3, mask), view_visible_and_enabled, x, y, false);
 }
 
 BOOL LLPopupView::handleRightMouseDown(S32 x, S32 y, MASK mask)
 {
-	if (!handleMouseEvent(boost::bind(&LLMouseHandler::handleRightMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y))
+	if (!handleMouseEvent(boost::bind(&LLMouseHandler::handleRightMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y, true))
 	{
-		clearPopups();
 		return FALSE;
 	}
 	return TRUE;
@@ -155,27 +164,27 @@ BOOL LLPopupView::handleRightMouseDown(S32 x, S32 y, MASK mask)
 
 BOOL LLPopupView::handleRightMouseUp(S32 x, S32 y, MASK mask)
 {
-	return handleMouseEvent(boost::bind(&LLMouseHandler::handleRightMouseUp, _1, _2, _3, mask), view_visible_and_enabled, x, y);
+	return handleMouseEvent(boost::bind(&LLMouseHandler::handleRightMouseUp, _1, _2, _3, mask), view_visible_and_enabled, x, y, false);
 }
 
 BOOL LLPopupView::handleDoubleClick(S32 x, S32 y, MASK mask)
 {
-	return handleMouseEvent(boost::bind(&LLMouseHandler::handleDoubleClick, _1, _2, _3, mask), view_visible_and_enabled, x, y);
+	return handleMouseEvent(boost::bind(&LLMouseHandler::handleDoubleClick, _1, _2, _3, mask), view_visible_and_enabled, x, y, false);
 }
 
 BOOL LLPopupView::handleHover(S32 x, S32 y, MASK mask)
 {
-	return handleMouseEvent(boost::bind(&LLMouseHandler::handleHover, _1, _2, _3, mask), view_visible_and_enabled, x, y);
+	return handleMouseEvent(boost::bind(&LLMouseHandler::handleHover, _1, _2, _3, mask), view_visible_and_enabled, x, y, false);
 }
 
 BOOL LLPopupView::handleScrollWheel(S32 x, S32 y, S32 clicks)
 {
-	return handleMouseEvent(boost::bind(&LLMouseHandler::handleScrollWheel, _1, _2, _3, clicks), view_visible_and_enabled, x, y);
+	return handleMouseEvent(boost::bind(&LLMouseHandler::handleScrollWheel, _1, _2, _3, clicks), view_visible_and_enabled, x, y, false);
 }
 
 BOOL LLPopupView::handleToolTip(S32 x, S32 y, MASK mask)
 {
-	return handleMouseEvent(boost::bind(&LLMouseHandler::handleToolTip, _1, _2, _3, mask), view_visible, x, y);
+	return handleMouseEvent(boost::bind(&LLMouseHandler::handleToolTip, _1, _2, _3, mask), view_visible, x, y, false);
 }
 
 void LLPopupView::addPopup(LLView* popup)
@@ -183,7 +192,7 @@ void LLPopupView::addPopup(LLView* popup)
 	if (popup)
 	{
 		mPopups.erase(std::find(mPopups.begin(), mPopups.end(), popup->getHandle()));
-		mPopups.push_back(popup->getHandle());
+		mPopups.push_front(popup->getHandle());
 	}
 }
 
@@ -206,11 +215,12 @@ void LLPopupView::clearPopups()
 		popup_it != mPopups.end();)
 	{
 		LLView* popup = popup_it->get();
+
+		popup_list_t::iterator cur_popup_it = popup_it;
 		++popup_it;
 
-		if (popup) popup->onTopLost();
+		mPopups.erase(cur_popup_it);
+		popup->onTopLost();
 	}
-
-	mPopups.clear();
 }
 
diff --git a/indra/newview/llpopupview.h b/indra/newview/llpopupview.h
index c5dbb94c4c..6248e9a553 100644
--- a/indra/newview/llpopupview.h
+++ b/indra/newview/llpopupview.h
@@ -60,7 +60,7 @@ public:
 	popup_list_t getCurrentPopups() { return mPopups; }
 
 private:
-	BOOL handleMouseEvent(boost::function<BOOL(LLView*, S32, S32)>, boost::function<bool(LLView*)>, S32 x, S32 y);
+	BOOL handleMouseEvent(boost::function<BOOL(LLView*, S32, S32)>, boost::function<bool(LLView*)>, S32 x, S32 y, bool close_popups);
 	popup_list_t mPopups;
 };
 #endif //LL_LLROOTVIEW_H
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index 2ed0718e41..0a30ed0ecf 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -522,11 +522,11 @@ static void onClickScriptDebug(void*)
 void LLStatusBar::onMouseEnterVolume()
 {
 	LLButton* volbtn =  getChild<LLButton>( "volume_btn" );
-	LLRect vol_btn_screen_rect = volbtn->calcScreenRect();
+	LLRect vol_btn_rect = volbtn->getRect();
 	LLRect volume_pulldown_rect = mPanelVolumePulldown->getRect();
-	volume_pulldown_rect.setLeftTopAndSize(vol_btn_screen_rect.mLeft -
-	     (volume_pulldown_rect.getWidth() - vol_btn_screen_rect.getWidth())/2,
-			       vol_btn_screen_rect.mBottom,
+	volume_pulldown_rect.setLeftTopAndSize(vol_btn_rect.mLeft -
+	     (volume_pulldown_rect.getWidth() - vol_btn_rect.getWidth())/2,
+			       vol_btn_rect.mBottom,
 			       volume_pulldown_rect.getWidth(),
 			       volume_pulldown_rect.getHeight());
 
@@ -545,7 +545,7 @@ void LLStatusBar::onMouseEnterNearbyMedia()
 	LLView* popup_holder = gViewerWindow->getRootView()->getChildView("popup_holder");
 	LLRect nearby_media_rect = mPanelNearByMedia->getRect();
 	LLButton* nearby_media_btn =  getChild<LLButton>( "media_toggle_btn" );
-	LLRect nearby_media_btn_rect = nearby_media_btn->calcScreenRect();
+	LLRect nearby_media_btn_rect = nearby_media_btn->getRect();
 	nearby_media_rect.setLeftTopAndSize(nearby_media_btn_rect.mLeft - 
 										(nearby_media_rect.getWidth() - nearby_media_btn_rect.getWidth())/2,
 										nearby_media_btn_rect.mBottom,
-- 
cgit v1.2.3


From 902548c55cce856633a74fe98f515ad4b1804c05 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 3 Mar 2010 20:58:00 -0800
Subject: nested popups close properly

---
 indra/newview/llpopupview.cpp | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/indra/newview/llpopupview.cpp b/indra/newview/llpopupview.cpp
index 3494522969..d9e4ebcd3c 100644
--- a/indra/newview/llpopupview.cpp
+++ b/indra/newview/llpopupview.cpp
@@ -117,8 +117,16 @@ BOOL LLPopupView::handleMouseEvent(boost::function<BOOL(LLView*, S32, S32)> func
 			}
 		}
 
-		popup->onTopLost();
-		mPopups.erase(popup_it++);
+		if (close_popups)
+		{
+			popup_list_t::iterator cur_popup_it = popup_it++;
+			mPopups.erase(cur_popup_it);
+			popup->onTopLost();
+		}
+		else
+		{
+			++popup_it;
+		}
 	}
 
 	return FALSE;
-- 
cgit v1.2.3


From 5208aa56bd28490084166d0f755ce8d2f0dcd5a2 Mon Sep 17 00:00:00 2001
From: Richard Nelson <none@none>
Date: Thu, 4 Mar 2010 15:27:28 -0800
Subject: fixed expandable text box not hiding when clicking off them

---
 indra/newview/llexpandabletextbox.cpp | 7 +++++++
 indra/newview/llexpandabletextbox.h   | 6 ++++++
 2 files changed, 13 insertions(+)

diff --git a/indra/newview/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp
index 9a906d8323..362010d65a 100644
--- a/indra/newview/llexpandabletextbox.cpp
+++ b/indra/newview/llexpandabletextbox.cpp
@@ -412,6 +412,13 @@ void LLExpandableTextBox::onFocusLost()
 	LLUICtrl::onFocusLost();
 }
 
+void LLExpandableTextBox::onTopLost()
+{
+	collapseTextBox();
+
+	LLUICtrl::onTopLost();
+}
+
 void LLExpandableTextBox::setValue(const LLSD& value)
 {
 	collapseTextBox();
diff --git a/indra/newview/llexpandabletextbox.h b/indra/newview/llexpandabletextbox.h
index 690c500e84..9d4a8aef76 100644
--- a/indra/newview/llexpandabletextbox.h
+++ b/indra/newview/llexpandabletextbox.h
@@ -139,6 +139,12 @@ public:
 	 */
 	/*virtual*/ void onFocusLost();
 
+	/**
+	 * Collapses text box on top_lost event
+	 */
+	/*virtual*/ void onTopLost();
+
+
 	/**
 	 * Draws text box, collapses text box if its expanded and its parent's position changed
 	 */
-- 
cgit v1.2.3


From 485711e179e0ccf6351feb02318f41bbb5593662 Mon Sep 17 00:00:00 2001
From: Richard Nelson <none@none>
Date: Thu, 4 Mar 2010 16:35:52 -0800
Subject: removed extraneous updateBoundingRect() calls remove the login
 progress panel as a popup only after it has finished fading out popupview
 manages it's own registering and unregistering of popup callbacks

---
 indra/llui/llcombobox.cpp        |  4 ++--
 indra/newview/llpopupview.cpp    | 10 +++++++++-
 indra/newview/llpopupview.h      |  1 +
 indra/newview/llprogressview.cpp |  3 ++-
 indra/newview/llviewerwindow.cpp |  2 --
 5 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index c679717807..9ec1a9f7c4 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -622,7 +622,7 @@ void LLComboBox::showList()
 	LLUI::addPopup(this);
 
 	setUseBoundingRect(TRUE);
-	updateBoundingRect();
+//	updateBoundingRect();
 }
 
 void LLComboBox::hideList()
@@ -646,7 +646,7 @@ void LLComboBox::hideList()
 
 		setUseBoundingRect(FALSE);
 		LLUI::removePopup(this);
-		updateBoundingRect();
+//		updateBoundingRect();
 	}
 }
 
diff --git a/indra/newview/llpopupview.cpp b/indra/newview/llpopupview.cpp
index d9e4ebcd3c..590a45c96c 100644
--- a/indra/newview/llpopupview.cpp
+++ b/indra/newview/llpopupview.cpp
@@ -48,6 +48,14 @@ bool view_visible(LLView* viewp)
 
 LLPopupView::LLPopupView()
 {
+	// register ourself as handler of UI popups
+	LLUI::setPopupFuncs(boost::bind(&LLPopupView::addPopup, this, _1), boost::bind(&LLPopupView::removePopup, this, _1), boost::bind(&LLPopupView::clearPopups, this));
+}
+
+LLPopupView::~LLPopupView()
+{
+	// set empty callback function so we can't handle popups anymore
+	LLUI::setPopupFuncs(LLUI::add_popup_t(), LLUI::remove_popup_t(), LLUI::clear_popups_t());
 }
 
 void LLPopupView::draw()
@@ -212,8 +220,8 @@ void LLPopupView::removePopup(LLView* popup)
 		{
 			gFocusMgr.setKeyboardFocus(NULL);
 		}
-		popup->onTopLost();
 		mPopups.erase(std::find(mPopups.begin(), mPopups.end(), popup->getHandle()));
+		popup->onTopLost();
 	}
 }
 
diff --git a/indra/newview/llpopupview.h b/indra/newview/llpopupview.h
index 6248e9a553..1ec61d5450 100644
--- a/indra/newview/llpopupview.h
+++ b/indra/newview/llpopupview.h
@@ -39,6 +39,7 @@ class LLPopupView : public LLPanel
 {
 public:
 	LLPopupView();
+	~LLPopupView();
 
 	/*virtual*/ void draw();
 	/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp
index 15831d85a0..120b584cd9 100644
--- a/indra/newview/llprogressview.cpp
+++ b/indra/newview/llprogressview.cpp
@@ -128,7 +128,6 @@ void LLProgressView::setVisible(BOOL visible)
 {
 	if (getVisible() && !visible)
 	{
-		gViewerWindow->removePopup(this);
 
 		mFadeTimer.start();
 	}
@@ -190,6 +189,8 @@ void LLProgressView::draw()
 			// Fade is complete, release focus
 			gFocusMgr.releaseFocusIfNeeded( this );
 			LLPanel::setVisible(FALSE);
+			gViewerWindow->removePopup(this);
+
 			gStartTexture = NULL;
 		}
 		return;
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 1304a66397..7dd606ccda 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1368,8 +1368,6 @@ LLViewerWindow::LLViewerWindow(
 	LLNotifications::instance().setIgnoreAllNotifications(gSavedSettings.getBOOL("IgnoreAllNotifications"));
 	llinfos << "NOTE: ALL NOTIFICATIONS THAT OCCUR WILL GET ADDED TO IGNORE LIST FOR LATER RUNS." << llendl;
 
-	LLUI::setPopupFuncs(boost::bind(&LLViewerWindow::addPopup, this, _1), boost::bind(&LLViewerWindow::removePopup, this, _1), boost::bind(&LLViewerWindow::clearPopups, this));
-
 	// Default to application directory.
 	LLViewerWindow::sSnapshotBaseName = "Snapshot";
 	LLViewerWindow::sMovieBaseName = "SLmovie";
-- 
cgit v1.2.3


From dd663449b6f8b802892e11fab7cc2cbce36f734f Mon Sep 17 00:00:00 2001
From: Palmer <palmer@lindenlab.com>
Date: Fri, 5 Mar 2010 13:07:32 -0800
Subject: Only comments added to crash reporting code on handling old crash
 logs on mac.  No code changed :)

---
 indra/newview/llappviewermacosx.cpp | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
index f8f8f50cd6..80d9b14345 100644
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -392,7 +392,12 @@ void LLAppViewerMacOSX::handleCrashReporting(bool reportFreeze)
 		_exit(1);
 	}
 	
-	// TODO:palmer REMOVE THIS VERY SOON.  THIS WILL NOT BE IN VIEWER 2.0
+	// TODO from palmer: Find a better way to handle managing old crash logs
+	// when this is a separate imbedable module.  Ideally just sort crash stack
+	// logs based on date, and grab the latest one as opposed to deleting them
+	// for thoughts on what the module would look like.
+	// See: https://wiki.lindenlab.com/wiki/Viewer_Crash_Reporter_Round_4
+	
 	// Remove the crash stack log from previous executions.
 	// Since we've started logging a new instance of the app, we can assume 
 	// The old crash stack is invalid for the next crash report.
-- 
cgit v1.2.3


From 65ecde210e24a691190444e88090c0cd3c2d9559 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 5 Mar 2010 16:29:37 -0500
Subject: Fix Mac llmediaplugintest build breakage. A viewport array passed to
 glGetIntegerv() and gluUnProject() was declared as 'int'. This compiles on
 Windows, but fails on Mac. Declaring as 'GLint' works.

---
 indra/test_apps/llplugintest/llmediaplugintest.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/test_apps/llplugintest/llmediaplugintest.cpp b/indra/test_apps/llplugintest/llmediaplugintest.cpp
index 6b275bbcad..e5a846f15a 100644
--- a/indra/test_apps/llplugintest/llmediaplugintest.cpp
+++ b/indra/test_apps/llplugintest/llmediaplugintest.cpp
@@ -307,7 +307,7 @@ GLfloat LLMediaPluginTest::distanceToCamera( GLfloat point_x, GLfloat point_y, G
 
 	GLdouble modelMatrix[16];
 	GLdouble projMatrix[16];
-	int viewport[4];
+	GLint viewport[4];
 
 	glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
 	glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
-- 
cgit v1.2.3


From f22423fb2912e9c1b0757617aed22d118ea73fa4 Mon Sep 17 00:00:00 2001
From: Eli Linden <eli@lindenlab.com>
Date: Fri, 5 Mar 2010 13:34:40 -0800
Subject: VWR-17362

---
 indra/newview/skins/default/xui/fr/floater_about_land.xml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/indra/newview/skins/default/xui/fr/floater_about_land.xml b/indra/newview/skins/default/xui/fr/floater_about_land.xml
index e7e2d8a0ee..53f7f8af6f 100644
--- a/indra/newview/skins/default/xui/fr/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/fr/floater_about_land.xml
@@ -312,17 +312,17 @@ Seules les parcelles de grande taille peuvent apparaître dans la recherche.
 			</text>
 			<check_box label="Modifier le terrain" name="edit land check" tool_tip="Si cette option est cochée, n&apos;importe qui peut terraformer votre terrain. Il vaut mieux ne pas cocher cette option pour toujours pouvoir modifer votre propre terrain."/>
 			<check_box label="Voler" name="check fly" tool_tip="Si cette option est cochée, les résidents peuvent voler sur votre terrain. Si elle n&apos;est pas cochée, ils ne pourront voler que lorsqu&apos;ils arrivent et passent au dessus de votre terrain."/>
-			<text left="152" name="allow_label2">
+			<text name="allow_label2">
 				Construire :
 			</text>
 			<check_box label="Tous" left="285" name="edit objects check"/>
 			<check_box label="Groupe" left="395" name="edit group objects check"/>
-			<text left="152" name="allow_label3" width="150">
+			<text name="allow_label3">
 				Laisser entrer des objets :
 			</text>
 			<check_box label="Tous" left="285" name="all object entry check"/>
 			<check_box label="Groupe" left="395" name="group object entry check"/>
-			<text left="152" name="allow_label4">
+			<text name="allow_label4">
 				Exécuter des scripts :
 			</text>
 			<check_box label="Tous" left="285" name="check other scripts"/>
-- 
cgit v1.2.3


From eee6b1c77934f58e26094d25297e942d9914842f Mon Sep 17 00:00:00 2001
From: Eli Linden <eli@lindenlab.com>
Date: Fri, 5 Mar 2010 13:45:06 -0800
Subject: VWR-17686

---
 indra/newview/skins/default/xui/en/floater_live_lsleditor.xml | 8 ++++----
 indra/newview/skins/default/xui/fr/floater_live_lsleditor.xml | 6 +++---
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/indra/newview/skins/default/xui/en/floater_live_lsleditor.xml b/indra/newview/skins/default/xui/en/floater_live_lsleditor.xml
index 990be55847..1f192f9b28 100644
--- a/indra/newview/skins/default/xui/en/floater_live_lsleditor.xml
+++ b/indra/newview/skins/default/xui/en/floater_live_lsleditor.xml
@@ -45,9 +45,9 @@
      layout="topleft"
      name="Reset"
      left="10"
-     width="61" />
+     width="85" />
     <check_box
-    left_delta="71"
+    left_delta="90"
     top_delta="3"
      enabled="false"
      follows="left|bottom"
@@ -57,9 +57,9 @@
      label="Running"
      layout="topleft"
      name="running"
-     width="100" />
+     width="205" />
     <check_box
-    left_delta="75"
+    left_delta="140"
      enabled="true"
      follows="left|bottom"
      font="SansSerif"
diff --git a/indra/newview/skins/default/xui/fr/floater_live_lsleditor.xml b/indra/newview/skins/default/xui/fr/floater_live_lsleditor.xml
index feb2fe1027..7647452e91 100644
--- a/indra/newview/skins/default/xui/fr/floater_live_lsleditor.xml
+++ b/indra/newview/skins/default/xui/fr/floater_live_lsleditor.xml
@@ -9,7 +9,7 @@
 	<floater.string name="Title">
 		SCRIPT : [NAME]
 	</floater.string>
-	<button label="Réinitialiser" label_selected="Réinitialiser" left="390" name="Reset" width="100"/>
-	<check_box initial_value="true" label="Exécution en cours" left="4" name="running"/>
-	<check_box initial_value="true" label="Mono" left_delta="160" name="mono"/>
+	<button label="Réinitialiser" label_selected="Réinitialiser" name="Reset"/>
+	<check_box initial_value="true" label="Exécution en cours" name="running"/>
+	<check_box initial_value="true" label="Mono" name="mono"/>
 </floater>
-- 
cgit v1.2.3


From ae66c372ece512490b20d5a63775228232ab9965 Mon Sep 17 00:00:00 2001
From: Eli Linden <eli@lindenlab.com>
Date: Fri, 5 Mar 2010 13:53:20 -0800
Subject: VWR-17687 en_xui_change

---
 indra/newview/skins/default/xui/en/panel_script_ed.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/skins/default/xui/en/panel_script_ed.xml b/indra/newview/skins/default/xui/en/panel_script_ed.xml
index d14355b9f4..d444420550 100644
--- a/indra/newview/skins/default/xui/en/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/en/panel_script_ed.xml
@@ -178,5 +178,5 @@
      top_pad="-35"
      right="487"
      name="Save_btn"
-     width="61" />
+     width="81" />
 </panel>
-- 
cgit v1.2.3


From a714e9ed7eaad7ae2da6dd1fb131bd4aed0eea59 Mon Sep 17 00:00:00 2001
From: Eli Linden <eli@lindenlab.com>
Date: Fri, 5 Mar 2010 14:07:11 -0800
Subject: VWR-17558 en_xui_change

---
 indra/newview/skins/default/xui/en/floater_about_land.xml |  4 ++--
 indra/newview/skins/default/xui/fr/floater_about_land.xml | 10 +++++-----
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index 29c6ae8009..3297150c7f 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -395,7 +395,7 @@ Leyla Linden               </text>
              name="Cancel Land Sale"
              left_pad="5"
              top_pad="-25"
-             width="145" />
+             width="155" />
             <text
              type="string"
              length="1"
@@ -1504,7 +1504,7 @@ Only large parcels can be listed in search.
              name="Clear"
              tool_tip="Clear the landing point"
              right="-10"
-             width="50" />
+             width="55" />
             <text
              type="string"
              length="1"
diff --git a/indra/newview/skins/default/xui/fr/floater_about_land.xml b/indra/newview/skins/default/xui/fr/floater_about_land.xml
index 53f7f8af6f..d0e96583f0 100644
--- a/indra/newview/skins/default/xui/fr/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/fr/floater_about_land.xml
@@ -109,7 +109,7 @@
 			<text name="Selling with no objects in parcel.">
 				Objets non inclus dans la vente
 			</text>
-			<button label="Annuler la vente du terrain" label_selected="Annuler la vente du terrain" left="275" name="Cancel Land Sale" width="165"/>
+			<button label="Annuler la vente du terrain" label_selected="Annuler la vente du terrain" name="Cancel Land Sale"/>
 			<text name="Claimed:">
 				Acquis :
 			</text>
@@ -367,11 +367,11 @@ Seules les parcelles de grande taille peuvent apparaître dans la recherche.
 				Photo :
 			</text>
 			<texture_picker bottom="-319" label="" name="snapshot_ctrl" tool_tip="Cliquez pour sélectionner une image"/>
-			<text bottom="-323" name="landing_point">
+			<text name="landing_point">
 				Lieu d&apos;arrivée : [LANDING]
 			</text>
-			<button bottom="-323" label="Définir" label_selected="Définir" name="Set" tool_tip="Définit le point d&apos;arrivée des visiteurs. Définit l&apos;emplacement de votre avatar sur ce terrain."/>
-			<button bottom="-323" label="Annuler" label_selected="Annuler" name="Clear" tool_tip="Effacer le lieu d&apos;arrivée"/>
+			<button label="Définir" label_selected="Définir" name="Set" tool_tip="Définit le point d&apos;arrivée des visiteurs. Définit l&apos;emplacement de votre avatar sur ce terrain."/>
+			<button label="Annuler" label_selected="Annuler" name="Clear" tool_tip="Effacer le lieu d&apos;arrivée"/>
 			<text bottom="-343" name="Teleport Routing: ">
 				Règles de téléportation :
 			</text>
@@ -380,7 +380,7 @@ Seules les parcelles de grande taille peuvent apparaître dans la recherche.
 				<combo_box.item label="Lieu d&apos;arrivée fixe" name="LandingPoint"/>
 				<combo_box.item label="Lieu d&apos;arrivée libre" name="Anywhere"/>
 			</combo_box>
-		</panel>
+		</panel>	
 		<panel label="MÉDIA" name="land_media_panel">
 			<text name="with media:" width="85">
 				Type :
-- 
cgit v1.2.3


From 90e7506cae0d6c3f93507abce4a6aceee9c08fe5 Mon Sep 17 00:00:00 2001
From: Eli Linden <eli@lindenlab.com>
Date: Fri, 5 Mar 2010 15:32:50 -0800
Subject: VWR-17116 en_xui_change

---
 .../skins/default/xui/en/floater_customize.xml     | 88 +++++++++++-----------
 1 file changed, 44 insertions(+), 44 deletions(-)

diff --git a/indra/newview/skins/default/xui/en/floater_customize.xml b/indra/newview/skins/default/xui/en/floater_customize.xml
index fd10938539..6f2b0fc3ea 100644
--- a/indra/newview/skins/default/xui/en/floater_customize.xml
+++ b/indra/newview/skins/default/xui/en/floater_customize.xml
@@ -307,7 +307,7 @@
              label_selected="Save"
              layout="topleft"
              name="Save"
-             right="190"
+             right="186"
              top="477"
              width="82" />
             <button
@@ -319,7 +319,7 @@
              name="Save As"
              top="477"
              right="304"
-             width="110" />
+             width="115" />
         </panel>
         <panel
          border="false"
@@ -489,7 +489,7 @@
              height="23"
              layout="topleft"
              name="Item Action Label"
-             right="132"
+             right="90"
              width="100">
                 Skin:
             </text>
@@ -548,7 +548,7 @@
              label="Save"
              label_selected="Save"
              layout="topleft"
-             right="218"
+             right="186"
              name="Save"
              top="477"
              width="82" />
@@ -561,7 +561,7 @@
              right="304"
              name="Save As"
              top="477"
-             width="82" />
+             width="115" />
             <button
              follows="right|bottom"
              height="23"
@@ -739,7 +739,7 @@
              height="23"
              layout="topleft"
              name="Item Action Label"
-             right="132"
+             right="90" 
              width="100">
                 Hair:
             </text>
@@ -771,7 +771,7 @@
              label="Save"
              label_selected="Save"
              layout="topleft"
-             right="218"
+             right="186"
              name="Save"
              top="477"
              width="82" />
@@ -784,7 +784,7 @@
              right="304"
              name="Save As"
              top="477"
-             width="82" />
+             width="115" />
             <button
              follows="right|bottom"
              height="23"
@@ -924,7 +924,7 @@
              height="23"
              layout="bottomleft"
              name="Item Action Label"
-             right="132"
+             right="90" 
              width="100">
                 Eyes:
             </text>
@@ -955,7 +955,7 @@
              label="Save"
              label_selected="Save"
              layout="topleft"
-             right="218"
+             right="186"
              name="Save"
              top="477"
              width="82" />
@@ -968,7 +968,7 @@
              right="304"
              name="Save As"
              top="477"
-             width="82" />
+             width="115" />
             <button
              follows="right|bottom"
              height="23"
@@ -1069,7 +1069,7 @@
              label="Save"
              label_selected="Save"
              layout="topleft"
-             right="218"
+             right="186"
              name="Save"
              top="477"
              width="82" />
@@ -1082,7 +1082,7 @@
              right="304"
              name="Save As"
              top="477"
-             width="82" />
+             width="115" />
             <button
              follows="right|bottom"
              height="23"
@@ -1193,7 +1193,7 @@
              height="23"
              layout="bottomleft"
              name="Item Action Label"
-             right="132"
+             right="90" 
              width="100">
                 Shirt:
             </text>
@@ -1272,7 +1272,7 @@
              label="Save"
              label_selected="Save"
              layout="topleft"
-             right="218"
+             right="186"
              name="Save"
              top="477"
              width="82" />
@@ -1285,7 +1285,7 @@
              right="304"
              name="Save As"
              top="477"
-             width="82" />
+             width="115" />
             <button
              follows="right|bottom"
              height="23"
@@ -1396,7 +1396,7 @@
              height="23"
              layout="bottomleft"
              name="Item Action Label"
-             right="132"
+             right="90" 
              width="100">
                 Pants:
             </text>
@@ -1538,7 +1538,7 @@
              height="23"
              layout="bottomleft"
              name="Item Action Label"
-             right="132"
+             right="90" 
              width="100">
                 Shoes:
             </text>
@@ -1579,7 +1579,7 @@
              label="Save"
              label_selected="Save"
              layout="topleft"
-             right="218"
+             right="186"
              name="Save"
              top="477"
              width="82" />
@@ -1592,7 +1592,7 @@
              right="304"
              name="Save As"
              top="477"
-             width="82" />
+             width="115" />
             <button
              follows="right|bottom"
              height="23"
@@ -1741,7 +1741,7 @@
              height="23"
              layout="bottomleft"
              name="Item Action Label"
-             right="132"
+             right="90" 
              width="100">
                 Socks:
             </text>
@@ -1782,7 +1782,7 @@
              label="Save"
              label_selected="Save"
              layout="topleft"
-             right="218"
+             right="186"
              name="Save"
              top="477"
              width="82" />
@@ -1795,7 +1795,7 @@
              right="304"
              name="Save As"
              top="477"
-             width="82" />
+             width="115" />
             <button
              follows="right|bottom"
              height="23"
@@ -1944,7 +1944,7 @@
              height="23"
              layout="bottomleft"
              name="Item Action Label"
-             right="132"
+             right="90" 
              width="100">
                 Jacket:
             </text>
@@ -1996,7 +1996,7 @@
              label="Save"
              label_selected="Save"
              layout="topleft"
-             right="218"
+             right="186"
              name="Save"
              top="477"
              width="82" />
@@ -2009,7 +2009,7 @@
              right="304"
              name="Save As"
              top="477"
-             width="82" />
+             width="115" />
             <button
              follows="right|bottom"
              height="23"
@@ -2158,7 +2158,7 @@
              height="23"
              layout="bottomleft"
              name="Item Action Label"
-             right="132"
+             right="90" 
              width="100">
                 Gloves:
             </text>
@@ -2199,7 +2199,7 @@
              label="Save"
              label_selected="Save"
              layout="topleft"
-             right="218"
+             right="186"
              name="Save"
              top="477"
              width="82" />
@@ -2212,7 +2212,7 @@
              right="304"
              name="Save As"
              top="477"
-             width="82" />
+             width="115" />
             <button
              follows="right|bottom"
              height="23"
@@ -2361,7 +2361,7 @@
              height="23"
              layout="bottomleft"
              name="Item Action Label"
-             right="132"
+             right="90" 
              width="100">
                 Undershirt:
             </text>
@@ -2402,7 +2402,7 @@
              label="Save"
              label_selected="Save"
              layout="topleft"
-             right="218"
+             right="186"
              name="Save"
              top="477"
              width="82" />
@@ -2415,7 +2415,7 @@
              right="304"
              name="Save As"
              top="477"
-             width="82" />
+             width="115" />
             <button
              follows="right|bottom"
              height="23"
@@ -2564,7 +2564,7 @@
              height="23"
              layout="bottomleft"
              name="Item Action Label"
-             right="132"
+             right="90" 
              width="100">
                 Underpants:
             </text>
@@ -2605,7 +2605,7 @@
              label="Save"
              label_selected="Save"
              layout="topleft"
-             right="218"
+             right="186"
              name="Save"
              top="477"
              width="82" />
@@ -2618,7 +2618,7 @@
              right="304"
              name="Save As"
              top="477"
-             width="82" />
+             width="115" />
             <button
              follows="right|bottom"
              height="23"
@@ -2767,7 +2767,7 @@
              height="23"
              layout="bottomleft"
              name="Item Action Label"
-             right="132"
+             right="90" 
              width="100">
                 Skirt:
             </text>
@@ -2808,7 +2808,7 @@
              label="Save"
              label_selected="Save"
              layout="topleft"
-             right="218"
+             right="186"
              name="Save"
              top="477"
              width="82" />
@@ -2821,7 +2821,7 @@
              right="304"
              name="Save As"
              top="477"
-             width="82" />
+             width="115" />
             <button
              follows="right|bottom"
              height="23"
@@ -2970,7 +2970,7 @@
              height="23"
              layout="bottomleft"
              name="Item Action Label"
-             right="132"
+             right="90" 
              width="100">
                 Tattoo:
             </text>
@@ -3024,7 +3024,7 @@
              label="Save"
              label_selected="Save"
              layout="topleft"
-             right="218"
+             right="186"
              name="Save"
              top="477"
              width="82" />
@@ -3037,7 +3037,7 @@
              right="304"
              name="Save As"
              top="477"
-             width="82" />
+             width="115" />
             <button
              follows="right|bottom"
              height="23"
@@ -3186,7 +3186,7 @@
              height="23"
              layout="bottomleft"
              name="Item Action Label"
-             right="132"
+             right="90" 
              width="100">
                 Alpha:
             </text>
@@ -3305,7 +3305,7 @@
              label="Save"
              label_selected="Save"
              layout="topleft"
-             right="218"
+             right="186"
              name="Save"
              top="477"
              width="82" />
@@ -3318,7 +3318,7 @@
              right="304"
              name="Save As"
              top="477"
-             width="82" />
+             width="115" />
             <button
              follows="right|bottom"
              height="23"
-- 
cgit v1.2.3


From 27919e106a383ea873b9bf73d2974b40cbe2e603 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 5 Mar 2010 15:41:15 -0800
Subject: fix for merge

---
 indra/newview/llviewerwindow.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index a6b4ed3df4..6c8900df21 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -131,6 +131,7 @@
 #include "llmorphview.h"
 #include "llmoveview.h"
 #include "llnavigationbar.h"
+#include "llpopupview.h"
 #include "llpreviewtexture.h"
 #include "llprogressview.h"
 #include "llresmgr.h"
-- 
cgit v1.2.3


From 218a60ea9e67cad7896256c1f9222d54402a2432 Mon Sep 17 00:00:00 2001
From: Eli Linden <eli@lindenlab.com>
Date: Fri, 5 Mar 2010 15:50:09 -0800
Subject: VWR-17121 en_xui_change

---
 indra/newview/skins/default/xui/en/floater_snapshot.xml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/indra/newview/skins/default/xui/en/floater_snapshot.xml b/indra/newview/skins/default/xui/en/floater_snapshot.xml
index 01548dd820..dda14f02ff 100644
--- a/indra/newview/skins/default/xui/en/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/en/floater_snapshot.xml
@@ -45,7 +45,7 @@
     </radio_group>
   <ui_ctrl 
     height="90"
-    width="90"
+    width="125"
     layout="topleft"
     name="thumbnail_placeholder"
     top_pad="6"
@@ -149,7 +149,7 @@
      left="10"
      name="type_label2"
      top_pad="5"
-     width="120">
+     width="127">
         Size
     </text>
     <text
@@ -199,7 +199,7 @@
      left_delta="0"
      name="texture_size_combo"
      top_delta="0"
-     width="120">
+     width="127">
         <combo_box.item
          label="Current Window"
          name="CurrentWindow"
@@ -228,7 +228,7 @@
      left_delta="0"
      name="local_size_combo"
      top_delta="0"
-     width="120">
+     width="127">
         <combo_box.item
          label="Current Window"
          name="CurrentWindow"
-- 
cgit v1.2.3


From f92a3add5910103e910ad993c3b09a26cc0d2d59 Mon Sep 17 00:00:00 2001
From: Eli Linden <eli@lindenlab.com>
Date: Fri, 5 Mar 2010 16:07:59 -0800
Subject: VWR-17723

---
 indra/newview/skins/default/xui/de/floater_buy_currency.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/indra/newview/skins/default/xui/de/floater_buy_currency.xml b/indra/newview/skins/default/xui/de/floater_buy_currency.xml
index 4bf4692e36..d0d3628448 100644
--- a/indra/newview/skins/default/xui/de/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/de/floater_buy_currency.xml
@@ -18,13 +18,13 @@
 	<text name="balance_amount">
 		[AMT] L$
 	</text>
-	<text name="currency_action" width="90">
+	<text name="currency_action">
 		Ich möchte kaufen
 	</text>
 	<text name="currency_label">
 		L$
 	</text>
-	<line_editor label="L$" left_delta="55" name="currency_amt">
+	<line_editor label="L$" name="currency_amt">
 		1234
 	</line_editor>
 	<text name="buying_label">
-- 
cgit v1.2.3


From 7cea645ba2b77d5bbcba7a7189aa584ac95ff453 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 5 Mar 2010 17:38:21 -0800
Subject: added some logging to help track down crash in EXT-5849

---
 indra/llui/llview.cpp            | 8 ++++++--
 indra/llui/llview.h              | 4 ++--
 indra/newview/llviewerwindow.cpp | 8 ++++----
 3 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index db2c460eec..b695731a02 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -73,9 +73,9 @@ S32		LLView::sLastBottomXML = S32_MIN;
 std::vector<LLViewDrawContext*> LLViewDrawContext::sDrawContextStack;
 
 
-#if LL_DEBUG
+//#if LL_DEBUG
 BOOL LLView::sIsDrawing = FALSE;
-#endif
+//#endif
 
 // Compiler optimization, generate extern template
 template class LLView* LLView::getChild<class LLView>(
@@ -150,6 +150,10 @@ LLView::~LLView()
 {
 	dirtyRect();
 	//llinfos << "Deleting view " << mName << ":" << (void*) this << llendl;
+	if (LLView::isDrawing)
+	{
+		llwarns << "Deleting view " << mName << " during UI draw() phase" << llendl;
+	}
 // 	llassert(LLView::sIsDrawing == FALSE);
 	
 //	llassert_always(sDepth == 0); // avoid deleting views while drawing! It can subtly break list iterators
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index c4d7313743..efae00f0e5 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -171,9 +171,9 @@ private:
 	// widgets in general are not copyable
 	LLView(const LLView& other) {};
 public:
-#if LL_DEBUG
+//#if LL_DEBUG
 	static BOOL sIsDrawing;
-#endif
+//#endif
 	enum ESoundFlags
 	{
 		SILENT = 0,
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 6c8900df21..d0a1a31ebd 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2021,9 +2021,9 @@ void LLViewerWindow::drawDebugText()
 void LLViewerWindow::draw()
 {
 	
-#if LL_DEBUG
+//#if LL_DEBUG
 	LLView::sIsDrawing = TRUE;
-#endif
+//#endif
 	stop_glerror();
 	
 	LLUI::setLineWidth(1.f);
@@ -2135,9 +2135,9 @@ void LLViewerWindow::draw()
 	LLUI::popMatrix();
 	gGL.popMatrix();
 
-#if LL_DEBUG
+//#if LL_DEBUG
 	LLView::sIsDrawing = FALSE;
-#endif
+//#endif
 }
 
 // Takes a single keydown event, usually when UI is visible
-- 
cgit v1.2.3


From eee50d1401ff7dfcb9c9fdc2c6e61e6d6281f5e2 Mon Sep 17 00:00:00 2001
From: Monroe Linden <monroe@lindenlab.com>
Date: Fri, 5 Mar 2010 18:11:55 -0800
Subject: Fix for a crash on startup/shutdown introduced in the tip of
 viewer-2-0 very recently.

list.erase(list.find()) is not safe, because erasing list.end() is undefined.  Check to make sure the find succeeded before doing the erase.

Reviewed by Richard at http://codereview.lindenlab.com/341001
---
 indra/newview/llpopupview.cpp | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/indra/newview/llpopupview.cpp b/indra/newview/llpopupview.cpp
index 590a45c96c..1668a91eed 100644
--- a/indra/newview/llpopupview.cpp
+++ b/indra/newview/llpopupview.cpp
@@ -207,7 +207,11 @@ void LLPopupView::addPopup(LLView* popup)
 {
 	if (popup)
 	{
-		mPopups.erase(std::find(mPopups.begin(), mPopups.end(), popup->getHandle()));
+		popup_list_t::iterator iter = std::find(mPopups.begin(), mPopups.end(), popup->getHandle());
+		if(iter != mPopups.end())
+		{
+			mPopups.erase(iter);
+		}
 		mPopups.push_front(popup->getHandle());
 	}
 }
@@ -220,7 +224,11 @@ void LLPopupView::removePopup(LLView* popup)
 		{
 			gFocusMgr.setKeyboardFocus(NULL);
 		}
-		mPopups.erase(std::find(mPopups.begin(), mPopups.end(), popup->getHandle()));
+		popup_list_t::iterator iter = std::find(mPopups.begin(), mPopups.end(), popup->getHandle());
+		if(iter != mPopups.end())
+		{
+			mPopups.erase(iter);
+		}
 		popup->onTopLost();
 	}
 }
-- 
cgit v1.2.3


From 4ada9e7f15eed6a462f22a119a724f64799aba54 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 5 Mar 2010 18:19:29 -0800
Subject: fix

---
 indra/llui/llview.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index b695731a02..d34083a384 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -150,7 +150,7 @@ LLView::~LLView()
 {
 	dirtyRect();
 	//llinfos << "Deleting view " << mName << ":" << (void*) this << llendl;
-	if (LLView::isDrawing)
+	if (LLView::sIsDrawing)
 	{
 		llwarns << "Deleting view " << mName << " during UI draw() phase" << llendl;
 	}
-- 
cgit v1.2.3