Index: src/insets/InsetCaption.cpp
===================================================================
--- src/insets/InsetCaption.cpp	(Revision 18599)
+++ src/insets/InsetCaption.cpp	(Arbeitskopie)
@@ -97,9 +97,9 @@
 
 
 void InsetCaption::cursorPos(BufferView const & bv,
-		CursorSlice const & sl, bool boundary, int & x, int & y) const
+		CursorSlice const & sl, bool boundary, int & x, int & y, bool & rtl) const
 {
-	InsetText::cursorPos(bv, sl, boundary, x, y);
+	InsetText::cursorPos(bv, sl, boundary, x, y, rtl);
 	x += labelwidth_;
 }
 
Index: src/insets/InsetTabular.h
===================================================================
--- src/insets/InsetTabular.h	(Revision 18599)
+++ src/insets/InsetTabular.h	(Arbeitskopie)
@@ -713,7 +713,7 @@
 	Code lyxCode() const { return Inset::TABULAR_CODE; }
 	/// get offset of this cursor slice relative to our upper left corner
 	void cursorPos(BufferView const & bv, CursorSlice const & sl,
-		bool boundary, int & x, int & y) const;
+		bool boundary, int & x, int & y, bool & rtl) const;
 	///
 	bool tabularFeatures(Cursor & cur, std::string const & what);
 	///
Index: src/insets/Inset.cpp
===================================================================
--- src/insets/Inset.cpp	(Revision 18599)
+++ src/insets/Inset.cpp	(Arbeitskopie)
@@ -257,7 +257,7 @@
 
 
 void Inset::cursorPos(BufferView const & /*bv*/, CursorSlice const &,
-		bool, int & x, int & y) const
+		bool, int & x, int & y, bool & rtl) const
 {
 	lyxerr << "Inset::cursorPos called directly" << std::endl;
 	x = 100;
Index: src/insets/InsetTabular.cpp
===================================================================
--- src/insets/InsetTabular.cpp	(Revision 18599)
+++ src/insets/InsetTabular.cpp	(Arbeitskopie)
@@ -3861,9 +3861,9 @@
 
 
 void InsetTabular::cursorPos(BufferView const & bv,
-		CursorSlice const & sl, bool boundary, int & x, int & y) const
+		CursorSlice const & sl, bool boundary, int & x, int & y, bool & rtl) const
 {
-	cell(sl.idx())->cursorPos(bv, sl, boundary, x, y);
+	cell(sl.idx())->cursorPos(bv, sl, boundary, x, y, rtl);
 
 	// y offset	correction
 	int const row = tabular.row_of_cell(sl.idx());
Index: src/insets/InsetCaption.h
===================================================================
--- src/insets/InsetCaption.h	(Revision 18599)
+++ src/insets/InsetCaption.h	(Arbeitskopie)
@@ -41,7 +41,7 @@
 	virtual docstring const editMessage() const;
 	///
 	virtual void cursorPos(BufferView const & bv,
-		CursorSlice const & sl, bool boundary, int & x, int & y) const;
+		CursorSlice const & sl, bool boundary, int & x, int & y, bool & rtl) const;
 	///
 	bool descendable() const { return true; }
 	///
Index: src/insets/Inset.h
===================================================================
--- src/insets/Inset.h	(Revision 18599)
+++ src/insets/Inset.h	(Arbeitskopie)
@@ -146,8 +146,10 @@
 	/// do we cover screen position x/y?
 	virtual bool covers(BufferView const & bv, int x, int y) const;
 	/// get the screen positions of the cursor (see note in Cursor.cpp)
+	/// rtl == true if x is the right side (or left for boundary == true)
+	/// of an inset placed at the cursor
 	virtual void cursorPos(BufferView const & bv,
-		CursorSlice const & sl, bool boundary, int & x, int & y) const;
+		CursorSlice const & sl, bool boundary, int & x, int & y, bool & rtl) const;
 
 	/// is this an inset that can be moved into?
 	virtual bool isActive() const { return nargs() > 0; }
Index: src/insets/InsetCollapsable.cpp
===================================================================
--- src/insets/InsetCollapsable.cpp	(Revision 18599)
+++ src/insets/InsetCollapsable.cpp	(Arbeitskopie)
@@ -240,11 +240,11 @@
 
 
 void InsetCollapsable::cursorPos(BufferView const & bv,
-		CursorSlice const & sl, bool boundary, int & x, int & y) const
+		CursorSlice const & sl, bool boundary, int & x, int & y, bool & rtl) const
 {
 	BOOST_ASSERT(status() != Collapsed);
 
-	InsetText::cursorPos(bv, sl, boundary, x, y);
+	InsetText::cursorPos(bv, sl, boundary, x, y, rtl);
 
 	if (status() == Open) {
 		if (openinlined_)
Index: src/insets/InsetText.h
===================================================================
--- src/insets/InsetText.h	(Revision 18599)
+++ src/insets/InsetText.h	(Arbeitskopie)
@@ -80,7 +80,7 @@
 
 	/// return x,y of given position relative to the inset's baseline
 	void cursorPos(BufferView const & bv, CursorSlice const & sl,
-		bool boundary, int & x, int & y) const;
+		bool boundary, int & x, int & y, bool & rtl) const;
 	///
 	Code lyxCode() const { return TEXT_CODE; }
 	///
Index: src/insets/InsetText.cpp
===================================================================
--- src/insets/InsetText.cpp	(Revision 18599)
+++ src/insets/InsetText.cpp	(Arbeitskopie)
@@ -345,10 +345,11 @@
 
 
 void InsetText::cursorPos(BufferView const & bv,
-		CursorSlice const & sl, bool boundary, int & x, int & y) const
+		CursorSlice const & sl, bool boundary, int & x, int & y, bool & rtl) const
 {
 	x = text_.cursorX(bv, sl, boundary) + border_;
 	y = text_.cursorY(bv, sl, boundary);
+	rtl = text_.isRTL(*bv.buffer(), sl.pit(), sl.pos(), boundary);
 }
 
 
Index: src/insets/InsetCollapsable.h
===================================================================
--- src/insets/InsetCollapsable.h	(Revision 18599)
+++ src/insets/InsetCollapsable.h	(Arbeitskopie)
@@ -57,7 +57,7 @@
 	void drawSelection(PainterInfo & pi, int x, int y) const;
 	/// return x,y of given position relative to the inset's baseline
 	void cursorPos(BufferView const & bv, CursorSlice const & sl,
-		bool boundary, int & x, int & y) const;
+		bool boundary, int & x, int & y, bool & rtl) const;
 	///
 	bool hitButton(FuncRequest const &) const;
 	///
Index: src/Text2.cpp
===================================================================
--- src/Text2.cpp	(Revision 18599)
+++ 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/mathed/InsetMathMBox.h
===================================================================
--- src/mathed/InsetMathMBox.h	(Revision 18599)
+++ src/mathed/InsetMathMBox.h	(Arbeitskopie)
@@ -53,7 +53,7 @@
 	Text * getText(int) const;
 	///
 	void cursorPos(BufferView const & bv, CursorSlice const & sl,
-		bool boundary, int & x, int & y) const;
+		bool boundary, int & x, int & y, bool & rtl) const;
 protected:
 	virtual void doDispatch(Cursor & cur, FuncRequest & cmd);
 
Index: src/mathed/MathMacro.h
===================================================================
--- src/mathed/MathMacro.h	(Revision 18599)
+++ src/mathed/MathMacro.h	(Arbeitskopie)
@@ -40,7 +40,7 @@
 	bool metrics(MetricsInfo & mi, Dimension & dim) const;
 	/// get cursor position
 	void cursorPos(BufferView const & bv, CursorSlice const & sl,
-		bool boundary, int & x, int & y) const;
+		bool boundary, int & x, int & y, bool & rtl) const;
 	///
 	Inset * editXY(Cursor & cur, int x, int y);
 	/// target pos when we enter the inset from the left by pressing "Right"
Index: src/mathed/MathMacro.cpp
===================================================================
--- src/mathed/MathMacro.cpp	(Revision 18599)
+++ src/mathed/MathMacro.cpp	(Arbeitskopie)
@@ -104,11 +104,11 @@
 
 
 void MathMacro::cursorPos(BufferView const & bv,
-		CursorSlice const & sl, bool boundary, int & x,	int & y) const
+		CursorSlice const & sl, bool boundary, int & x,	int & y, bool & rtl) const
 {
 	// We may have 0 arguments, but InsetMathNest requires at least one.
 	if (nargs() > 0)
-		InsetMathNest::cursorPos(bv, sl, boundary, x, y);
+		InsetMathNest::cursorPos(bv, sl, boundary, x, y, rtl);
 }
 
 
Index: src/mathed/InsetMathNest.cpp
===================================================================
--- src/mathed/InsetMathNest.cpp	(Revision 18599)
+++ src/mathed/InsetMathNest.cpp	(Arbeitskopie)
@@ -100,7 +100,7 @@
 
 void InsetMathNest::cursorPos(BufferView const & bv,
 		CursorSlice const & sl, bool /*boundary*/,
-		int & x, int & y) const
+		int & x, int & y, bool & rtl) const
 {
 // FIXME: This is a hack. Ideally, the coord cache should not store
 // absolute positions, but relative ones. This would mean to call
Index: src/mathed/InsetMathNest.h
===================================================================
--- src/mathed/InsetMathNest.h	(Revision 18599)
+++ src/mathed/InsetMathNest.h	(Arbeitskopie)
@@ -46,7 +46,7 @@
 	InsetMathNest const * asNestInset() const { return this; }
 	/// get cursor position
 	void cursorPos(BufferView const & bv, CursorSlice const & sl,
-		bool boundary, int & x, int & y) const;
+		bool boundary, int & x, int & y, bool & rtl) const;
 	///
 	void edit(Cursor & cur, bool left);
 	///
Index: src/mathed/InsetMathMBox.cpp
===================================================================
--- src/mathed/InsetMathMBox.cpp	(Revision 18599)
+++ src/mathed/InsetMathMBox.cpp	(Arbeitskopie)
@@ -117,10 +117,11 @@
 
 
 void InsetMathMBox::cursorPos(BufferView const & bv,
-		CursorSlice const & sl, bool boundary, int & x, int & y) const
+		CursorSlice const & sl, bool boundary, int & x, int & y, bool & rtl) const
 {
 	x = text_.cursorX(bv, sl, boundary);
 	y = text_.cursorY(bv, sl, boundary);
+	rtl = text_.isRTL(*bv.buffer(), sl.pit(), sl.pos(), boundary);
 }
 
 
Index: src/Text.cpp
===================================================================
--- src/Text.cpp	(Revision 18599)
+++ src/Text.cpp	(Arbeitskopie)
@@ -8,6 +8,7 @@
  * \author Jean-Marc Lasgouttes
  * \author John Levon
  * \author André Pönitz
+ * \author Stefan Schimanski
  * \author Dekel Tsur
  * \author Jürgen Vigna
  *
@@ -1330,8 +1331,10 @@
 		checkBufferStructure(cur.buffer(), cur);
 	}
 
-	if (cur.pos() == cur.lastpos())
+	if (cur.pos() == cur.lastpos()) {
+		cur.bv().textMetrics(this).redoParagraph(cur.pit());
 		setCurrentFont(cur);
+	}
 
 	needsUpdate |= handleBibitems(cur);
 
@@ -1412,91 +1415,151 @@
 	DocIterator end = cur.selectionEnd();
 
 	BufferView & bv = *pi.base.bv;
-	Buffer const & buffer = *bv.buffer();
 
-	// the selection doesn't touch the visible screen
+	// the selection doesn't touch the visible screen?
 	if (bv_funcs::status(&bv, beg) == bv_funcs::CUR_BELOW
 	    || bv_funcs::status(&bv, end) == bv_funcs::CUR_ABOVE)
 		return;
 
-	Paragraph const & par1 = pars_[beg.pit()];
-	Paragraph const & par2 = pars_[end.pit()];
 	TextMetrics const & tm = bv.textMetrics(this);
 	ParagraphMetrics const & pm1 = tm.parMetrics(beg.pit());
 	ParagraphMetrics const & pm2 = tm.parMetrics(end.pit());
+	Row const & row1 = pm1.getRow(beg.pos(), beg.boundary());
+	Row const & row2 = pm2.getRow(end.pos(), end.boundary());
 
-	bool const above = (bv_funcs::status(&bv, beg)
-			    == bv_funcs::CUR_ABOVE);
-	bool const below = (bv_funcs::status(&bv, end)
-			    == bv_funcs::CUR_BELOW);
-	int y1,y2,x1,x2;
-	if (above) {
-		y1 = 0;
-		y2 = 0;
-		x1 = 0;
-		x2 = tm.width();
-	} else {
-		Row const & row1 = pm1.getRow(beg.pos(), beg.boundary());
-		y1 = bv_funcs::getPos(bv, beg, beg.boundary()).y_ - row1.ascent();
-		y2 = y1 + row1.height();
-		int const startx = cursorX(bv, beg.top(), beg.boundary());
-		if (!isRTL(buffer, par1)) {
-			x1 = startx;
-			x2 = 0 + tm.width();
+	// clip above
+	int middleTop;
+	bool const clipAbove = 
+		(bv_funcs::status(&bv, beg) == bv_funcs::CUR_ABOVE);
+	if (clipAbove)
+		middleTop = 0;
+	else
+		middleTop = bv_funcs::getPos(bv, beg, beg.boundary()).y_ + row1.descent();
+	
+	// clip below
+	int middleBottom;
+	bool const clipBelow = 
+		(bv_funcs::status(&bv, end)	== bv_funcs::CUR_BELOW);
+	if (clipBelow)
+		middleBottom = bv.workHeight();
+	else
+		middleBottom = bv_funcs::getPos(bv, end, end.boundary()).y_ - row2.ascent();
+
+	// start and end in the same line?
+	if (!(clipAbove || clipBelow) && &row1 == &row2)
+		// then only draw this row's selection
+		drawRowSelection(pi, x, row1, beg, end, false, false);
+	else {
+		if (!clipAbove) {
+			// get row end
+			DocIterator begRowEnd = beg;
+			begRowEnd.pos() = row1.endpos();
+			begRowEnd.boundary(true);
+			
+			// draw upper rectangle
+			drawRowSelection(pi, x, row1, beg, begRowEnd, false, true);
 		}
-		else {
-			x1 = 0;
-			x2 = startx;
+			
+		if (middleTop < middleBottom) {
+			// draw middle rectangle
+			pi.pain.fillRectangle(x, middleTop, 
+														tm.width(), middleBottom - middleTop, 
+														Color::selection);
 		}
+
+		if (!clipBelow) {
+			// get row begin
+			DocIterator endRowBeg = end;
+			endRowBeg.pos() = row2.pos();
+			endRowBeg.boundary(false);
+			
+			// draw low rectangle
+			drawRowSelection(pi, x, row2, endRowBeg, end, true, false);
+		}
 	}
+}
 
-	int Y1,Y2,X1,X2;
-	if (below) {
-		Y1 = bv.workHeight();
-		Y2 = bv.workHeight();
-		X1 = 0;
-		X2 = tm.width();
-	} else {
-		Row const & row2 = pm2.getRow(end.pos(), end.boundary());
-		Y1 = bv_funcs::getPos(bv, end, end.boundary()).y_ - row2.ascent();
-		Y2 = Y1 + row2.height();
-		int const endx = cursorX(bv, end.top(), end.boundary());
-		if (!isRTL(buffer, par2)) {
-			X1 = 0;
-			X2 = endx;
+
+void Text::drawRowSelection(PainterInfo & pi, int x, Row const & row,
+														DocIterator const & beg, DocIterator const & end, 
+														bool drawOnBegMargin, bool drawOnEndMargin) const
+{
+	BufferView & bv = *pi.base.bv;
+	Buffer & buffer = *bv.buffer();
+	TextMetrics const & tm = bv.textMetrics(this);
+	DocIterator cur = beg;
+	int x1 = cursorX(bv, beg.top(), beg.boundary());
+	int x2 = cursorX(bv, end.top(), end.boundary());
+	int y1 = bv_funcs::getPos(bv, cur, cur.boundary()).y_ - row.ascent();
+	int y2 = y1 + row.height();
+	
+	// draw the margins
+	if (drawOnBegMargin) {
+		if (isRTL(buffer, beg.paragraph()))
+			pi.pain.fillRectangle(x + x1, y1, tm.width() - x1, y2 - y1, Color::selection);
+		else
+			pi.pain.fillRectangle(x, y1, x1, y2 - y1, Color::selection);
+	}
+	
+	if (drawOnEndMargin) {
+		if (isRTL(buffer, beg.paragraph()))
+			pi.pain.fillRectangle(x, y1, x2, y2 - y1, Color::selection);
+		else
+			pi.pain.fillRectangle(x + x2, y1, tm.width() - x2, y2 - y1, Color::selection);
+	}
+	
+	// if we are on a boundary from the beginning, it's probably
+	// a RTL boundary and we jump to the other side directly as this
+	// segement is 0-size and confuses the logic below
+	if (cur.boundary())
+		cur.boundary(false);
+	
+	// go through row and draw from RTL boundary to RTL boundary
+	while (cur < end) {
+		bool drawNow = false;
+		
+		// simplified cursorRight code below which does not
+		// descend into insets and which does not go into the
+		// next line. Compare the logic with the original cursorRight
+		
+		// if left of boundary -> just jump to right side
+		// but for RTL boundaries don't, because: abc|DDEEFFghi -> abcDDEEF|Fghi
+		if (cur.boundary()) {
+			cur.boundary(false);
+		}	else if (bidi.isBoundary(buffer, cur.paragraph(), cur.pos() + 1)) {
+			// in front of RTL boundary -> Stay on this side of the boundary because:
+			//   ab|cDDEEFFghi -> abc|DDEEFFghi
+			++cur.pos();
+			cur.boundary(true);
+			drawNow = true;
+		} else {
+			// move right
+			++cur.pos();
+			
+			// line end?
+			if (cur.pos() == row.endpos())
+				cur.boundary(true);
 		}
-		else {
-			X1 = endx;
-			X2 = 0 + tm.width();
+			
+		if (x1 == -1) {
+			// the previous segment was just drawn, now the next starts
+			x1 = cursorX(bv, cur.top(), cur.boundary());
 		}
+		
+		if (!(cur < end) || drawNow) {
+			x2 = cursorX(bv, cur.top(), cur.boundary());
+			pi.pain.fillRectangle(x + min(x1,x2), y1, abs(x2 - x1), y2 - y1,
+														Color::selection);
+			
+			// reset x1, so it is set again next round (which will be on the 
+			// right side of a boundary or at the selection end)
+			x1 = -1;
+		}
 	}
+}
 
-	if (!above && !below && &pm1.getRow(beg.pos(), beg.boundary())
-	    == &pm2.getRow(end.pos(), end.boundary()))
-	{
-		// paint only one rectangle
-		int const b( !isRTL(*bv.buffer(), par1) ? x + x1 : x + X1 );
-		int const w( !isRTL(*bv.buffer(), par1) ? X2 - x1 : x2 - X1 );
-		pi.pain.fillRectangle(b, y1, w, y2 - y1, Color::selection);
-		return;
-	}
 
-	LYXERR(Debug::DEBUG) << " y1: " << y1 << " y2: " << y2
-		<< "X1:" << X1 << " x2: " << X2 << " wid: " << tm.width()
-		<< endl;
 
-	// paint upper rectangle
-	pi.pain.fillRectangle(x + x1, y1, x2 - x1, y2 - y1,
-				      Color::selection);
-	// paint bottom rectangle
-	pi.pain.fillRectangle(x + X1, Y1, X2 - X1, Y2 - Y1,
-				      Color::selection);
-	// paint center rectangle
-	pi.pain.fillRectangle(x, y2, tm.width(),
-			      Y1 - y2, Color::selection);
-}
-
-
 bool Text::isLastRow(pit_type pit, Row const & row) const
 {
 	return row.endpos() >= pars_[pit].size()
@@ -1693,14 +1756,6 @@
 		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 18599)
+++ src/Text3.cpp	(Arbeitskopie)
@@ -299,6 +299,13 @@
 }
 
 
+bool Text::isRTL(Buffer const & buffer, pit_type pit, pos_type pos, bool boundary) const
+{
+	Paragraph const & par = getPar(pit);
+	return getFont(buffer, par, pos).isVisibleRightToLeft();
+}
+
+
 void Text::dispatch(Cursor & cur, FuncRequest & cmd)
 {
 	LYXERR(Debug::ACTION) << "Text::dispatch: cmd: " << cmd << endl;
Index: src/Cursor.cpp
===================================================================
--- src/Cursor.cpp	(Revision 18599)
+++ src/Cursor.cpp	(Arbeitskopie)
@@ -110,9 +110,13 @@
 			}
 
 			Point o = I->second;
-			inset->cursorPos(c.bv(), it.top(), c.boundary(), xo, yo);
+			bool rtl = false;
+			inset->cursorPos(c.bv(), it.top(), c.boundary(), xo, yo, rtl);
 			// Convert to absolute
-			xo += o.x_;
+			if (rtl && it != et)
+				xo += o.x_ - inset->width();
+			else
+				xo += o.x_;
 			yo += o.y_;
 			double d = (x - xo) * (x - xo) + (y - yo) * (y - yo);
 			// '<=' in order to take the last possible position
Index: src/bufferview_funcs.cpp
===================================================================
--- src/bufferview_funcs.cpp	(Revision 18599)
+++ src/bufferview_funcs.cpp	(Arbeitskopie)
@@ -161,15 +161,31 @@
 {
 	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;
-		sl.inset().cursorPos(bv, sl, boundary && ((i+1) == dit.depth()), xx, yy);
+		
+		// get relative position inside sl.inset()
+		bool rtl = false;
+		sl.inset().cursorPos(bv, sl, boundary && ((i+1) == dit.depth()), xx, yy, rtl);
+		
+		// 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 (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 +196,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 +212,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 rtl = dit.bottom().text()->isRTL(*bv.buffer(), dit.bottom().pit(), 
+																				dit.bottom().pos(), boundary);
+	if (rtl)
+		x -= lastw;
+	
 	return Point(x, y);
 }
 
Index: src/Text.h
===================================================================
--- src/Text.h	(Revision 18599)
+++ 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 &, pit_type pit, pos_type pos, bool boundary) const;
 	///
 	bool checkAndActivateInset(Cursor & cur, bool front);
 
@@ -405,7 +407,12 @@
 	void charInserted();
 	/// set 'number' font property
 	void number(Cursor & cur);
+	/// draw selection for a single row
+	void drawRowSelection(PainterInfo & pi, int x, Row const & row,
+												DocIterator const & beg, DocIterator const & end, 
+												bool drawOnBegMargin, bool drawOnEndMargin) const;
 
+
 	/// paste plain text at current cursor.
 	/// \param str string to paste
 	/// \param asParagraphs whether to paste as paragraphs or as lines
