diff --git a/indra/llui/llradiogroup.cpp b/indra/llui/llradiogroup.cpp
index c66b9bde2b138da01033c7db9b658f78128c7384..d1ea5843eb318075732bb048a88903ebc6bfe828 100644
--- a/indra/llui/llradiogroup.cpp
+++ b/indra/llui/llradiogroup.cpp
@@ -45,8 +45,6 @@
 #include "lluictrlfactory.h"
 
 static LLDefaultChildRegistry::Register<LLRadioGroup> r1("radio_group");
-
-
 static RadioGroupRegistry::Register<LLRadioCtrl> register_radio_ctrl("radio_item");
 
 
@@ -83,6 +81,10 @@ LLRadioGroup::~LLRadioGroup()
 // virtual
 BOOL LLRadioGroup::postBuild()
 {
+	if (!mRadioButtons.empty())
+	{
+		mRadioButtons[0]->setTabStop(true);
+	}
 	if (mControlVariable)
 	{
 		setSelectedIndex(mControlVariable->getValue().asInteger());
@@ -102,7 +104,7 @@ void LLRadioGroup::setIndexEnabled(S32 index, BOOL enabled)
 			child->setEnabled(enabled);
 			if (index == mSelectedIndex && enabled == FALSE)
 			{
-				setSelectedIndex(-1);
+				mSelectedIndex = -1;
 			}
 			break;
 		}
@@ -142,8 +144,28 @@ BOOL LLRadioGroup::setSelectedIndex(S32 index, BOOL from_event)
 		return FALSE;
 	}
 
+	if (mSelectedIndex >= 0)
+	{
+		LLRadioCtrl* old_radio_item = mRadioButtons[mSelectedIndex];
+		old_radio_item->setTabStop(false);
+		old_radio_item->setValue( FALSE );
+	}
+	else
+	{
+		mRadioButtons[0]->setTabStop(false);
+	}
+
 	mSelectedIndex = index;
 
+	LLRadioCtrl* radio_item = mRadioButtons[mSelectedIndex];
+	radio_item->setTabStop(true);
+	radio_item->setValue( TRUE );
+
+	if (hasFocus())
+	{
+		mRadioButtons[mSelectedIndex]->focusFirstItem(FALSE, FALSE);
+	}
+
 	if (!from_event)
 	{
 		setControlValue(getSelectedIndex());
@@ -211,33 +233,6 @@ BOOL LLRadioGroup::handleKeyHere(KEY key, MASK mask)
 	return handled;
 }
 
-void LLRadioGroup::draw()
-{
-	S32 current_button = 0;
-
-	BOOL take_focus = FALSE;
-	if (gFocusMgr.childHasKeyboardFocus(this))
-	{
-		take_focus = TRUE;
-	}
-
-	for (button_list_t::iterator iter = mRadioButtons.begin();
-		 iter != mRadioButtons.end(); ++iter)
-	{
-		LLRadioCtrl* radio = *iter;
-		BOOL selected = (current_button == mSelectedIndex);
-		radio->setValue( selected );
-		if (take_focus && selected && !gFocusMgr.childHasKeyboardFocus(radio))
-		{
-			// don't flash keyboard focus when navigating via keyboard
-			BOOL DONT_FLASH = FALSE;
-			radio->focusFirstItem(FALSE, DONT_FLASH);
-		}
-		current_button++;
-	}
-
-	LLView::draw();
-}
 
 // When adding a child button, we need to ensure that the radio
 // group gets a message when the button is clicked.
@@ -259,6 +254,19 @@ bool LLRadioGroup::addChild(LLView* view, S32 tab_group)
 	return res;
 }
 
+BOOL LLRadioGroup::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+	// grab focus preemptively, before child button takes mousecapture
+	// 
+	if (hasTabStop())
+	{
+		focusFirstItem(FALSE, FALSE);
+	}
+
+	return LLUICtrl::handleMouseDown(x, y, mask);
+}
+
+
 // Handle one button being clicked.  All child buttons must have this
 // function as their callback function.
 
diff --git a/indra/llui/llradiogroup.h b/indra/llui/llradiogroup.h
index b5516307fd45568260c83237a24463df62567408..914548b6aa23448de75ad1270ad0dc2b6d0e230a 100644
--- a/indra/llui/llradiogroup.h
+++ b/indra/llui/llradiogroup.h
@@ -54,7 +54,10 @@ class LLRadioCtrl : public LLCheckBoxCtrl
 		Params() 
 		:	length("length"),
 			type("type")
-		{}
+		{
+			// radio items are not tabbable until they are selected
+			tab_stop = false;
+		}
 	};
 
 	/*virtual*/ ~LLRadioCtrl();
@@ -103,6 +106,7 @@ class LLRadioGroup
 	virtual BOOL postBuild();
 	
 	virtual bool addChild(LLView* view, S32 tab_group = 0);
+	virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
 	
 	virtual BOOL handleKeyHere(KEY key, MASK mask);
 
@@ -117,9 +121,6 @@ class LLRadioGroup
 	virtual void	setValue(const LLSD& value );
 	virtual LLSD	getValue() const;
 
-	// Draw the group, but also fix the highlighting based on the control.
-	void draw();
-
 	// Update the control as needed.  Userdata must be a pointer to the button.
 	void onClickButton(LLUICtrl* clicked_radio);
 	
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index 28cdb1ac2760b41853455f20cf4076f3409ae23e..8807e26f6b3cb7eca84c5850c838ea30de58d228 100644
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -506,56 +506,6 @@ void LLUICtrl::setFocus(BOOL b)
 	}
 }
 
-void LLUICtrl::onFocusReceived()
-{
-	// trigger callbacks
-	LLFocusableElement::onFocusReceived();
-
-	// find first view in hierarchy above new focus that is a LLUICtrl
-	LLView* viewp = getParent();
-	LLUICtrl* last_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getLastKeyboardFocus());
-
-	while (viewp && !viewp->isCtrl()) 
-	{
-		viewp = viewp->getParent();
-	}
-
-	// and if it has newly gained focus, call onFocusReceived()
-	LLUICtrl* ctrlp = static_cast<LLUICtrl*>(viewp);
-	if (ctrlp && (!last_focus || !last_focus->hasAncestor(ctrlp)))
-	{
-		ctrlp->onFocusReceived();
-	}
-}
-
-void LLUICtrl::onFocusLost()
-{
-	// trigger callbacks
-	LLFocusableElement::onFocusLost();
-
-	// find first view in hierarchy above old focus that is a LLUICtrl
-	LLView* viewp = getParent();
-	while (viewp && !viewp->isCtrl()) 
-	{
-		viewp = viewp->getParent();
-	}
-
-	// and if it has just lost focus, call onFocusReceived()
-	LLUICtrl* ctrlp = static_cast<LLUICtrl*>(viewp);
-	// hasFocus() includes any descendants
-	if (ctrlp && !ctrlp->hasFocus())
-	{
-		ctrlp->onFocusLost();
-	}
-}
-
-void LLUICtrl::onTopLost()
-{
-	// trigger callbacks
-	LLFocusableElement::onTopLost();
-}
-
-
 // virtual
 void LLUICtrl::setTabStop( BOOL b )	
 { 
diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h
index 40302306846640b4bcd4f2a8aa1c3c7c022bfae9..3add9393ea605059f6ec032fdd767ab8c5da98d2 100644
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
@@ -153,9 +153,6 @@ class LLUICtrl
 public:
 	// LLView interface
 	/*virtual*/ BOOL	setLabelArg( const std::string& key, const LLStringExplicit& text );
-	/*virtual*/ void	onFocusReceived();
-	/*virtual*/ void	onFocusLost();
-	/*virtual*/ void	onTopLost();
 	/*virtual*/ BOOL	isCtrl() const;
 	/*virtual*/ void	setTentative(BOOL b);
 	/*virtual*/ BOOL	getTentative() const;