diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h
index dbd38c1c3f03d202845029bfd0e70533c4bc6446..ef002fe9f2b53574d75081b74c4d983a73f092d6 100644
--- a/indra/llmath/v3math.h
+++ b/indra/llmath/v3math.h
@@ -156,6 +156,8 @@ F32	dist_vec(const LLVector3 &a, const LLVector3 &b);		// Returns distance betwe
 F32	dist_vec_squared(const LLVector3 &a, const LLVector3 &b);// Returns distance squared between a and b
 F32	dist_vec_squared2D(const LLVector3 &a, const LLVector3 &b);// Returns distance squared between a and b ignoring Z component
 LLVector3 projected_vec(const LLVector3 &a, const LLVector3 &b); // Returns vector a projected on vector b
+LLVector3 parallel_component(const LLVector3 &a, const LLVector3 &b); // Returns vector a projected on vector b (same as projected_vec)
+LLVector3 orthogonal_component(const LLVector3 &a, const LLVector3 &b); // Returns component of vector a not parallel to vector b (same as projected_vec)
 LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u); // Returns a vector that is a linear interpolation between a and b
 
 inline LLVector3::LLVector3(void)
@@ -490,6 +492,17 @@ inline LLVector3 projected_vec(const LLVector3 &a, const LLVector3 &b)
 	return project_axis * (a * project_axis);
 }
 
+inline LLVector3 parallel_component(const LLVector3 &a, const LLVector3 &b)
+{
+	return projected_vec(a, b);
+}
+
+inline LLVector3 orthogonal_component(const LLVector3 &a, const LLVector3 &b)
+{
+	return a - projected_vec(a, b);
+}
+
+
 inline LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u)
 {
 	return LLVector3(
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 698d55836cbe8162d6c8866a51457b725961bd78..23290e5cc69162f691142a778964a277f603a92a 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -84,6 +84,7 @@ LLToolPie::LLToolPie()
 	mMouseOutsideSlop( false ),
 	mMouseSteerX(-1),
 	mMouseSteerY(-1),
+	mAbortClickToWalk(false),
 	mClickAction(0),
 	mClickActionBuyEnabled( gSavedSettings.getBOOL("ClickActionBuyEnabled") ),
 	mClickActionPayEnabled( gSavedSettings.getBOOL("ClickActionPayEnabled") )
@@ -112,6 +113,7 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
 
 	mDragPick = mPick;
 	mMouseButtonDown = true;
+	mAbortClickToWalk = false;
 	
 	handleLeftClickPick();
 
@@ -301,7 +303,12 @@ BOOL LLToolPie::handleLeftClickPick()
 	}
 
 	// put focus back "in world"
-	gFocusMgr.setKeyboardFocus(NULL);
+	if (gFocusMgr.getKeyboardFocus())
+	{
+		// don't click to walk on attempt to give focus to world
+		mAbortClickToWalk = true;
+		gFocusMgr.setKeyboardFocus(NULL);
+	}
 
 	BOOL touchable = (object && object->flagHandleTouch()) 
 					 || (parent && parent->flagHandleTouch());
@@ -616,28 +623,28 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)
 	LLViewerObject* obj = mPick.getObject();
 	U8 click_action = final_click_action(obj);
 
-	bool media_handled_click = handleMediaMouseUp() || LLViewerMediaFocus::getInstance()->getFocus();
-	bool mouse_moved = mMouseOutsideSlop;
+	if (handleMediaMouseUp() || LLViewerMediaFocus::getInstance()->getFocus())
+	{
+		mAbortClickToWalk = true;
+	}
 	stopCameraSteering();
 	mMouseButtonDown = false;
 
-	if (!media_handled_click && click_action == CLICK_ACTION_NONE && !mouse_moved)
+	if (click_action == CLICK_ACTION_NONE				// not doing 1-click action
+		&& gSavedSettings.getBOOL("ClickToWalk")		// click to walk enabled
+		&& !mAbortClickToWalk							// another behavior hasn't cancelled click to walk
+		&& !mPick.mPosGlobal.isExactlyZero()			// valid coordinates for pick
+		&& (mPick.mPickType == LLPickInfo::PICK_LAND	// we clicked on land
+			|| mPick.mObjectID.notNull()))				// or on an object
 	{
-		if (gSavedSettings.getBOOL("ClickToWalk")			// click to walk enabled
-			&& !gFocusMgr.getKeyboardFocus()				// focus is on world
-			&& !mPick.mPosGlobal.isExactlyZero()			// valid coordinates for pick
-			&& (mPick.mPickType == LLPickInfo::PICK_LAND	// we clicked on land
-				|| mPick.mObjectID.notNull()))				// or on an object
-		{
-			gAgentCamera.setFocusOnAvatar(TRUE, TRUE);
-			mAutoPilotDestination = (LLHUDEffectBlob *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BLOB, FALSE);
-			mAutoPilotDestination->setPositionGlobal(mPick.mPosGlobal);
-			mAutoPilotDestination->setColor(LLColor4U::white);
-			mAutoPilotDestination->setDuration(5.f);
+		gAgentCamera.setFocusOnAvatar(TRUE, TRUE);
+		mAutoPilotDestination = (LLHUDEffectBlob *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BLOB, FALSE);
+		mAutoPilotDestination->setPositionGlobal(mPick.mPosGlobal);
+		mAutoPilotDestination->setColor(LLColor4U::white);
+		mAutoPilotDestination->setDuration(5.f);
 
-			handle_go_to();
-			return TRUE;
-		}
+		handle_go_to();
+		return TRUE;
 	}
 	gViewerWindow->setCursor(UI_CURSOR_ARROW);
 	if (hasMouseCapture())
@@ -1706,6 +1713,7 @@ bool intersect_ray_with_sphere( const LLVector3& ray_pt, const LLVector3& ray_di
 void LLToolPie::startCameraSteering()
 {
 	mMouseOutsideSlop = true;
+	mAbortClickToWalk = true;
 	setMouseCapture(TRUE);
 	
 	mMouseSteerX = mMouseDownX;
@@ -1729,22 +1737,14 @@ void LLToolPie::steerCameraWithMouse(S32 x, S32 y)
 	// FIXME: get this to work with camera tilt (i.e. sitting on a rotating object)
 	const LLVector3 rotation_up_axis(LLVector3::z_axis);
 
-	LLVector3 pick_offset = pick_pos - rotation_center;
-	F32 up_distance = pick_offset * rotation_up_axis;
-	LLVector3 object_rotation_center = rotation_center + rotation_up_axis * up_distance;
+	LLVector3 object_rotation_center = rotation_center + parallel_component(pick_pos - rotation_center, rotation_up_axis);
 	F32 min_rotation_radius = MIN_ROTATION_RADIUS_FRACTION * dist_vec(rotation_center, LLViewerCamera::instance().getOrigin());;
 	F32 pick_distance_from_rotation_center = llclamp(dist_vec(pick_pos, object_rotation_center), min_rotation_radius, F32_MAX);
 
-	LLVector3 screen_rotation_up_axis = rotation_up_axis - projected_vec(rotation_up_axis, LLViewerCamera::instance().getAtAxis());
-	screen_rotation_up_axis.normalize();
-	LLVector3 screen_rotation_left_axis = screen_rotation_up_axis % LLViewerCamera::instance().getAtAxis();
-
-	LLVector3 mouse_ray = gViewerWindow->mouseDirectionGlobal(x, y);
-	mouse_ray = mouse_ray - projected_vec(mouse_ray, rotation_up_axis);
+	LLVector3 mouse_ray = orthogonal_component(gViewerWindow->mouseDirectionGlobal(x, y), rotation_up_axis);
 	mouse_ray.normalize();
 
-	LLVector3 old_mouse_ray = gViewerWindow->mouseDirectionGlobal(mMouseSteerX, mMouseSteerY);
-	old_mouse_ray = old_mouse_ray - projected_vec(old_mouse_ray, rotation_up_axis);
+	LLVector3 old_mouse_ray = orthogonal_component(gViewerWindow->mouseDirectionGlobal(mMouseSteerX, mMouseSteerY), rotation_up_axis);
 	old_mouse_ray.normalize();
 
 	LLVector3 camera_pos = gAgentCamera.getCameraPositionAgent();
@@ -1752,7 +1752,7 @@ void LLToolPie::steerCameraWithMouse(S32 x, S32 y)
 	LLVector3 adjusted_camera_pos = camera_pos + projected_vec(camera_to_rotation_center, rotation_up_axis);
 	LLVector3 rotation_fwd_axis = LLViewerCamera::instance().getAtAxis() - projected_vec(LLViewerCamera::instance().getAtAxis(), rotation_up_axis);
 	rotation_fwd_axis.normalize();
-	F64 pick_dist = dist_vec(pick_pos, adjusted_camera_pos);
+	F32 pick_dist = dist_vec(pick_pos, adjusted_camera_pos);
 
 	LLVector3 mouse_on_sphere;
 	bool mouse_hit_sphere = intersect_ray_with_sphere(adjusted_camera_pos + (mouse_ray * pick_dist * 1.1f),
@@ -1770,16 +1770,21 @@ void LLToolPie::steerCameraWithMouse(S32 x, S32 y)
 
 	if (mouse_hit_sphere)
 	{
+		// calculate rotation frame in screen space
+		LLVector3 screen_rotation_up_axis = orthogonal_component(rotation_up_axis, LLViewerCamera::instance().getAtAxis());
+		screen_rotation_up_axis.normalize();
+
+		LLVector3 screen_rotation_left_axis = screen_rotation_up_axis % LLViewerCamera::instance().getAtAxis();
 
 		LLVector3 rotation_furthest_pt = object_rotation_center + pick_distance_from_rotation_center * rotation_fwd_axis;
 		F32 mouse_lateral_distance = llclamp(((mouse_on_sphere - rotation_furthest_pt) * screen_rotation_left_axis) / pick_distance_from_rotation_center, -1.f, 1.f);
 		F32 old_mouse_lateral_distance = llclamp(((old_mouse_on_sphere - rotation_furthest_pt) * screen_rotation_left_axis) / pick_distance_from_rotation_center, -1.f, 1.f);
 
-		F32 yaw_angle = -1.f * asinf(mouse_lateral_distance);
-		F32 old_yaw_angle = -1.f * asinf(old_mouse_lateral_distance);
+		F32 yaw_angle = asinf(mouse_lateral_distance);
+		F32 old_yaw_angle = asinf(old_mouse_lateral_distance);
 
 		F32 delta_angle = yaw_angle - old_yaw_angle;
-		if (mClockwise) delta_angle *= -1.f;
+		if (!mClockwise) delta_angle *= -1.f;
 
 		gAgent.yaw(delta_angle);
 		mMouseSteerX = x;
diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h
index 1ac1c35bccbd62bf7d665c3b30e564515707e069..dca661d26d1bb75d18396903c74ebab32aded9ee 100644
--- a/indra/newview/lltoolpie.h
+++ b/indra/newview/lltoolpie.h
@@ -103,7 +103,8 @@ class LLToolPie : public LLTool, public LLSingleton<LLToolPie>
 	S32					mMouseSteerY;
 	LLHUDEffectBlob*	mAutoPilotDestination;
 	LLHUDEffectBlob*	mMouseSteerGrabPoint;
-	bool				mClockwise;					
+	bool				mClockwise;			
+	bool				mAbortClickToWalk;
 	LLUUID				mMediaMouseCaptureID;
 	LLPickInfo			mPick;
 	LLPickInfo			mHoverPick;