Index: src/Text2.cpp
===================================================================
--- src/Text2.cpp	(Revision 18626)
+++ src/Text2.cpp	(Arbeitskopie)
@@ -1030,14 +1030,15 @@
 
 	// not at paragraph end?
 	if (cur.pos() != cur.lastpos()) {
-		// if left of boundary -> just jump to right side 
-		if (cur.boundary())
-			return setCursor(cur, cur.pit(), cur.pos(), true, false);
-
 		// in front of editable inset, i.e. jump into it?
 		if (checkAndActivateInset(cur, true))
 			return false;
-		
+
+		// if left of boundary -> just jump to right side
+		// but for RTL boundaries don't, because: abc|DDEEFFghi -> abcDDEEF|Fghi
+		if (cur.boundary() && !bidi.isBoundary(cur.buffer(), cur.paragraph(), cur.pos()))
+			return setCursor(cur, cur.pit(), cur.pos() + 1, true, false);
+
 		// next position is left of boundary, 
 		// but go to next line for special cases like space, newline, linesep
 #if 0
@@ -1062,6 +1063,11 @@
 			return setCursor(cur, cur.pit(), cur.pos() + 1, true, true);
 		}
 		
+		// in front of RTL boundary? Stay on this side of the boundary because:
+		//   ab|cDDEEFFghi -> abc|DDEEFFghi
+		if (bidi.isBoundary(cur.buffer(), cur.paragraph(), cur.pos() + 1))
+			return setCursor(cur, cur.pit(), cur.pos() + 1, true, true);
+		
 		// move right
 		return setCursor(cur, cur.pit(), cur.pos() + 1, true, false);
 	}
Index: src/Text.cpp
===================================================================
--- src/Text.cpp	(Revision 18626)
+++ src/Text.cpp	(Arbeitskopie)
@@ -1687,20 +1750,13 @@
 	}
 
 	// see correction above
-	if (boundary_correction)
-		if (getFont(buffer, par, ppos).isVisibleRightToLeft())
+	if (boundary_correction) {
+		if (isRTL(buffer, sl, boundary))
 			x -= singleWidth(buffer, par, ppos);
 		else
 			x += singleWidth(buffer, par, ppos);
+	}
 
-	// Make sure inside an inset we always count from the left
-	// edge (bidi!) -- MV
-	if (sl.pos() < par.size()) {
-		font = getFont(buffer, par, sl.pos());
-		if (!boundary && font.isVisibleRightToLeft()
-		  && par.isInset(sl.pos()))
-			x -= par.getInset(sl.pos())->width();
-	}
 	return int(x);
 }
 
Index: src/Text3.cpp
===================================================================
--- src/Text3.cpp	(Revision 18626)
+++ src/Text3.cpp	(Arbeitskopie)
@@ -299,6 +299,20 @@
 }
 
 
+bool Text::isRTL(Buffer const & buffer, CursorSlice const & sl, bool boundary) const
+{
+	if (!sl.text())
+		return false;
+
+	int correction = 0;
+	if (boundary && sl.pos() > 0)
+		correction = -1;
+		
+	Paragraph const & par = getPar(sl.pit());
+	return getFont(buffer, par, sl.pos() + correction).isVisibleRightToLeft();
+}
+
+
 void Text::dispatch(Cursor & cur, FuncRequest & cmd)
 {
 	LYXERR(Debug::ACTION) << "Text::dispatch: cmd: " << cmd << endl;
Index: src/bufferview_funcs.cpp
===================================================================
--- src/bufferview_funcs.cpp	(Revision 18626)
+++ src/bufferview_funcs.cpp	(Arbeitskopie)
@@ -161,15 +161,34 @@
 {
 	int x = 0;
 	int y = 0;
+	int lastw = 0;
 
-	// Contribution of nested insets
-	for (size_t i = 1; i != dit.depth(); ++i) {
+	// Addup ontribution of nested insets, from inside to outside,
+	// keeping the outer paragraph for a special handling below
+	for (size_t i = dit.depth() - 1; i >= 1; --i) {
 		CursorSlice const & sl = dit[i];
 		int xx = 0;
 		int yy = 0;
+		
+		// get relative position inside sl.inset()
 		sl.inset().cursorPos(bv, sl, boundary && ((i+1) == dit.depth()), xx, yy);
+		
+		// Make relative position inside of the edited inset relative to sl.inset()
 		x += xx;
 		y += yy;
+		
+		// In case of an RTL inset, the edited inset will be positioned to the left
+		// of xx:yy
+		if (sl.text()) {
+			bool boundary_i = boundary && i + 1 == dit.depth();
+			bool rtl = sl.text()->isRTL(*bv.buffer(), sl, boundary_i);
+			if (rtl)
+				x -= lastw;
+		}
+		
+		// remember width for the case that sl.inset() is positioned in an RTL inset
+		lastw = sl.inset().width();
+		
 		//lyxerr << "Cursor::getPos, i: "
 		// << i << " x: " << xx << " y: " << y << endl;
 	}
@@ -180,6 +199,7 @@
 	BOOST_ASSERT(!pm.rows().empty());
 	y -= pm.rows()[0].ascent();
 #if 1
+	// FIXME: document this mess
 	size_t rend;
 	if (sl.pos() > 0 && dit.depth() == 1) {
 		int pos = sl.pos();
@@ -195,8 +215,18 @@
 	for (size_t rit = 0; rit != rend; ++rit)
 		y += pm.rows()[rit].height();
 	y += pm.rows()[rend].ascent();
-	x += dit.bottom().text()->cursorX(bv, dit.bottom(), boundary && dit.depth() == 1);
-
+	
+	// Make relative position from the nested inset now bufferview absolute.
+	int xx = dit.bottom().text()->cursorX(bv, dit.bottom(), boundary && dit.depth() == 1);
+	x += xx;
+	
+	// In the RTL case place the nested inset at the left of the cursor in 
+	// the outer paragraph
+	bool boundary_1 = boundary && 1 == dit.depth();
+	bool rtl = dit.bottom().text()->isRTL(*bv.buffer(), dit.bottom(), boundary_1);
+	if (rtl)
+		x -= lastw;
+	
 	return Point(x, y);
 }
 
Index: src/Text.h
===================================================================
--- src/Text.h	(Revision 18626)
+++ src/Text.h	(Arbeitskopie)
@@ -333,6 +333,8 @@
 	docstring getPossibleLabel(Cursor & cur) const;
 	/// is this paragraph right-to-left?
 	bool isRTL(Buffer const &, Paragraph const & par) const;
+	/// is this position in the paragraph right-to-left?
+	bool isRTL(Buffer const & buffer, CursorSlice const & sl, bool boundary) const;
 	///
 	bool checkAndActivateInset(Cursor & cur, bool front);
 
