diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 65bd63a187ee715997070fdaf284e6f340d464ac..b23230bdd435fdeefc69729f41d4455c4001807c 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -543,10 +543,18 @@ LLFloater::~LLFloater()
 
 void LLFloater::storeRectControl()
 {
-	if( mRectControl.size() > 1 )
+	if (!mRectControl.empty())
 	{
 		getControlGroup()->setRect( mRectControl, getRect() );
 	}
+	if (!mPosXControl.empty() && mPositioning == LLFloaterEnums::POSITIONING_RELATIVE)
+	{
+		getControlGroup()->setF32( mPosXControl, mPosition.mX );
+	}
+	if (!mPosYControl.empty() && mPositioning == LLFloaterEnums::POSITIONING_RELATIVE)
+	{
+		getControlGroup()->setF32( mPosYControl, mPosition.mY );
+	}
 }
 
 void LLFloater::storeVisibilityControl()
@@ -565,23 +573,6 @@ void LLFloater::storeDockStateControl()
 	}
 }
 
-LLRect LLFloater::getSavedRect() const
-{
-	LLRect rect;
-
-	if (mRectControl.size() > 1)
-	{
-		rect = getControlGroup()->getRect(mRectControl);
-	}
-
-	return rect;
-}
-
-bool LLFloater::hasSavedRect() const
-{
-	return !getSavedRect().isEmpty();
-}
-
 // static
 std::string LLFloater::getControlName(const std::string& name, const LLSD& key)
 {
@@ -875,18 +866,39 @@ bool LLFloater::applyRectControl()
 		mRectControl.clear();
 		mPositioning = LLFloaterEnums::POSITIONING_CASCADE_GROUP;
 	}
-	else if (mRectControl.size() > 1)
+	else
 	{
-		// If we have a saved rect, use it
-		const LLRect& rect = getControlGroup()->getRect(mRectControl);
-		saved_rect = rect.notEmpty();
-		if (saved_rect)
+		if (!mRectControl.empty())
 		{
-			setOrigin(rect.mLeft, rect.mBottom);
+			// If we have a saved rect, use it
+			const LLRect& rect = getControlGroup()->getRect(mRectControl);
+			if (rect.notEmpty()) saved_rect = true;
+			if (saved_rect)
+			{
+				setOrigin(rect.mLeft, rect.mBottom);
 
-			if (mResizable)
+				if (mResizable)
+				{
+					reshape(llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight()));
+				}
+			}
+		}
+
+		if (!mPosXControl.empty() && !mPosYControl.empty())
+		{
+			LLControlVariablePtr x_control = getControlGroup()->getControl(mPosXControl);
+			LLControlVariablePtr y_control = getControlGroup()->getControl(mPosYControl);
+			if (x_control.notNull() 
+				&& y_control.notNull()
+				&& !x_control->isDefault()
+				&& !y_control->isDefault())
 			{
-				reshape(llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight()));
+				mPosition.mX = x_control->getValue().asReal();
+				mPosition.mY = y_control->getValue().asReal();
+				mPositioning = LLFloaterEnums::POSITIONING_RELATIVE;
+				applyRelativePosition();
+
+				saved_rect = true;
 			}
 		}
 	}
@@ -949,14 +961,8 @@ void LLFloater::applyPositioning(LLFloater* other)
 
 	case LLFloaterEnums::POSITIONING_RELATIVE:
 		{
-			LLRect snap_rect = gFloaterView->getSnapRect();
-			LLRect floater_view_screen_rect = gFloaterView->calcScreenRect();
-			snap_rect.translate(floater_view_screen_rect.mLeft, floater_view_screen_rect.mBottom);
-			LLRect floater_screen_rect = calcScreenRect();
+			applyRelativePosition();
 
-			LLCoordGL new_center = mPosition.convert();
-			LLCoordGL cur_center(floater_screen_rect.getCenterX(), floater_screen_rect.getCenterY());
-			translate(new_center.mX - cur_center.mX, new_center.mY - cur_center.mY);
 			break;
 		}
 	default:
@@ -1630,7 +1636,7 @@ void LLFloater::onClickTearOff(LLFloater* self)
 		self->openFloater(self->getKey());
 		
 		// only force position for floaters that don't have that data saved
-		if (self->mRectControl.size() <= 1)
+		if (self->mRectControl.empty())
 		{
 			new_rect.setLeftTopAndSize(host_floater->getRect().mLeft + 5, host_floater->getRect().mTop - floater_header_size - 5, self->getRect().getWidth(), self->getRect().getHeight());
 			self->setRect(new_rect);
@@ -2918,9 +2924,11 @@ void LLFloater::setInstanceName(const std::string& name)
 		std::string ctrl_name = getControlName(mInstanceName, mKey);
 
 		// save_rect and save_visibility only apply to registered floaters
-		if (!mRectControl.empty())
+		if (mSaveRect)
 		{
 			mRectControl = LLFloaterReg::declareRectControl(ctrl_name);
+			mPosXControl = LLFloaterReg::declarePosXControl(ctrl_name);
+			mPosYControl = LLFloaterReg::declarePosYControl(ctrl_name);
 		}
 		if (!mVisibilityControl.empty())
 		{
@@ -3001,10 +3009,7 @@ void LLFloater::initFromParams(const LLFloater::Params& p)
 
 	mPositioning = p.positioning;
 
-	if (p.save_rect && mRectControl.empty())
-	{
-		mRectControl = "t"; // flag to build mRectControl name once mInstanceName is set
-	}
+	mSaveRect = p.save_rect;
 	if (p.save_visibility)
 	{
 		mVisibilityControl = "t"; // flag to build mVisibilityControl name once mInstanceName is set
@@ -3283,6 +3288,19 @@ void LLFloater::stackWith(LLFloater& other)
 	other.setFollows(FOLLOWS_LEFT | FOLLOWS_TOP);
 }
 
+void LLFloater::applyRelativePosition()
+{
+	LLRect snap_rect = gFloaterView->getSnapRect();
+	LLRect floater_view_screen_rect = gFloaterView->calcScreenRect();
+	snap_rect.translate(floater_view_screen_rect.mLeft, floater_view_screen_rect.mBottom);
+	LLRect floater_screen_rect = calcScreenRect();
+
+	LLCoordGL new_center = mPosition.convert();
+	LLCoordGL cur_center(floater_screen_rect.getCenterX(), floater_screen_rect.getCenterY());
+	translate(new_center.mX - cur_center.mX, new_center.mY - cur_center.mY);
+}
+
+
 LLCoordFloater::LLCoordFloater(F32 x, F32 y, LLFloater& floater)
 :	coord_t(x, y)
 {
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 48dc290a930557d1e6d27f30c1bb75d642d74b66..4aa663d57e3ee0b80ba2fefa968afc21950ee516 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -269,8 +269,6 @@ class LLFloater : public LLPanel, public LLInstanceTracker<LLFloater>
 	BOOL			isResizable() const				{ return mResizable; }
 	void			setResizeLimits( S32 min_width, S32 min_height );
 	void			getResizeLimits( S32* min_width, S32* min_height ) { *min_width = mMinWidth; *min_height = mMinHeight; }
-	LLRect			getSavedRect() const;
-	bool			hasSavedRect() const;
 
 	static std::string		getControlName(const std::string& name, const LLSD& key);
 	static LLControlGroup*	getControlGroup();
@@ -361,6 +359,8 @@ class LLFloater : public LLPanel, public LLInstanceTracker<LLFloater>
 	virtual bool	applyRectControl();
 	bool			applyDockState();
 	void			applyPositioning(LLFloater* other);
+	void			applyRelativePosition();
+
 	void			storeRectControl();
 	void			storeVisibilityControl();
 	void			storeDockStateControl();
@@ -424,7 +424,10 @@ class LLFloater : public LLPanel, public LLInstanceTracker<LLFloater>
 	commit_signal_t* mMinimizeSignal;
 
 protected:
+	bool			mSaveRect;
 	std::string		mRectControl;
+	std::string		mPosXControl;
+	std::string		mPosYControl;
 	std::string		mVisibilityControl;
 	std::string		mDocStateControl;
 	LLSD			mKey;				// Key used for retrieving instances; set (for now) by LLFLoaterReg
diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp
index 7729e855ba5b64ef52bf8d9cc370d3587055a071..ef55e741660b8ddd03f078841ee40fafff3c73f3 100644
--- a/indra/llui/llfloaterreg.cpp
+++ b/indra/llui/llfloaterreg.cpp
@@ -358,9 +358,7 @@ void LLFloaterReg::restoreVisibleInstances()
 //static
 std::string LLFloaterReg::getRectControlName(const std::string& name)
 {
-	std::string res = std::string("floater_rect_") + name;
-	LLStringUtil::replaceChar( res, ' ', '_' );
-	return res;
+	return std::string("floater_rect_") + getBaseControlName(name);
 }
 
 //static
@@ -368,19 +366,48 @@ std::string LLFloaterReg::declareRectControl(const std::string& name)
 {
 	std::string controlname = getRectControlName(name);
 	LLFloater::getControlGroup()->declareRect(controlname, LLRect(),
-												 llformat("Window Position and Size for %s", name.c_str()),
+												 llformat("Window Size for %s", name.c_str()),
 												 TRUE);
 	return controlname;
 }
 
+std::string LLFloaterReg::declarePosXControl(const std::string& name)
+{
+	std::string controlname = std::string("floater_pos_x_") + getBaseControlName(name);
+	LLFloater::getControlGroup()->declareF32(controlname, 
+											10.f,
+											llformat("Window X Position for %s", name.c_str()),
+											TRUE);
+	return controlname;
+}
+
+std::string LLFloaterReg::declarePosYControl(const std::string& name)
+{
+	std::string controlname = std::string("floater_pos_y_") + getBaseControlName(name);
+	LLFloater::getControlGroup()->declareF32(controlname,
+											10.f,
+											llformat("Window Y Position for %s", name.c_str()),
+											TRUE);
+
+	return controlname;
+}
+
+
 //static
 std::string LLFloaterReg::getVisibilityControlName(const std::string& name)
 {
-	std::string res = std::string("floater_vis_") + name;
+	return std::string("floater_vis_") + getBaseControlName(name);
+}
+
+//static 
+std::string LLFloaterReg::getBaseControlName(const std::string& name)
+{
+	std::string res(name);
 	LLStringUtil::replaceChar( res, ' ', '_' );
 	return res;
 }
 
+
 //static
 std::string LLFloaterReg::declareVisibilityControl(const std::string& name)
 {
diff --git a/indra/llui/llfloaterreg.h b/indra/llui/llfloaterreg.h
index 534cf8b40ab882a85629aa155af26b1b2031672b..a1e1f8a98835ffa6bd8fd257a8a5799268b5e6ce 100644
--- a/indra/llui/llfloaterreg.h
+++ b/indra/llui/llfloaterreg.h
@@ -115,9 +115,11 @@ class LLFloaterReg
 	// Control Variables
 	static std::string getRectControlName(const std::string& name);
 	static std::string declareRectControl(const std::string& name);
+	static std::string declarePosXControl(const std::string& name);
+	static std::string declarePosYControl(const std::string& name);
 	static std::string getVisibilityControlName(const std::string& name);
 	static std::string declareVisibilityControl(const std::string& name);
-
+	static std::string getBaseControlName(const std::string& name);
 	static std::string declareDockStateControl(const std::string& name);
 	static std::string getDockStateControlName(const std::string& name);