Index: FL/Fl_Text_Display.H
===================================================================
--- FL/Fl_Text_Display.H	(revision 12482)
+++ FL/Fl_Text_Display.H	(working copy)
@@ -378,7 +378,8 @@
     DRAW_LINE, 
     FIND_INDEX,
     FIND_INDEX_FROM_ZERO,
-    GET_WIDTH 
+    GET_WIDTH,
+    FIND_CURSOR_INDEX	// STR #2788
   };
   
   int handle_vline(int mode, 
Index: src/Fl_Text_Display.cxx
===================================================================
--- src/Fl_Text_Display.cxx	(revision 12482)
+++ src/Fl_Text_Display.cxx	(working copy)
@@ -1922,7 +1922,7 @@
   \li return the width of a text range in pixels
   \li return the index of a character that is at a pixel position
 
- \param[in] mode DRAW_LINE, GET_WIDTH, FIND_INDEX, or FIND_INDEX_FROM_ZERO
+ \param[in] mode DRAW_LINE, GET_WIDTH, FIND_INDEX, FIND_INDEX_FROM_ZERO, or FIND_CURSOR_INDEX
  \param[in] lineStartPos index of first character
  \param[in] lineLen size of string in bytes
  \param[in] leftChar, rightChar
@@ -1956,6 +1956,13 @@
     lineStr = mBuffer->text_range( lineStartPos, lineStartPos + lineLen );
   }
 
+  // STR #2788
+  int cursor_pos = 0;
+  if (mode==FIND_CURSOR_INDEX) {
+    mode = FIND_INDEX;
+    cursor_pos = 1;
+  }
+
   if (mode==GET_WIDTH) {
     X = 0;
   } else if (mode==FIND_INDEX_FROM_ZERO) {
@@ -2001,6 +2008,8 @@
         if (mode==FIND_INDEX && startX+w>rightClip) {
           // find x pos inside block
           free(lineStr);
+          if (cursor_pos && (startX+w/2<rightClip))  // STR #2788
+            return lineStartPos + startIndex + len;  // STR #2788
           return lineStartPos + startIndex;
         }
       } else {
@@ -2010,7 +2019,7 @@
           draw_string( style, startX, Y, startX+w, lineStr+startIndex, i-startIndex );
         if (mode==FIND_INDEX && startX+w>rightClip) {
           // find x pos inside block
-          int di = find_x(lineStr+startIndex, i-startIndex, style, rightClip-startX);
+	  int di = find_x(lineStr+startIndex, i-startIndex, style, -(rightClip-startX)); // STR #2788
           free(lineStr);
           IS_UTF8_ALIGNED2(buffer(), (lineStartPos+startIndex+di))
           return lineStartPos + startIndex + di;
@@ -2034,6 +2043,8 @@
     if (mode==FIND_INDEX) {
       // find x pos inside block
       free(lineStr);
+      if (cursor_pos) // STR #2788
+        return lineStartPos + startIndex + ( rightClip-startX>w/2 ? 1 : 0 ); // STR #2788
       return lineStartPos + startIndex + ( rightClip-startX>w ? 1 : 0 );
     }
   } else {
@@ -2042,7 +2053,7 @@
       draw_string( style, startX, Y, startX+w, lineStr+startIndex, i-startIndex );
     if (mode==FIND_INDEX) {
       // find x pos inside block
-      int di = find_x(lineStr+startIndex, i-startIndex, style, rightClip-startX);
+      int di = find_x(lineStr+startIndex, i-startIndex, style, -(rightClip-startX)); // STR #2788
       free(lineStr);
       IS_UTF8_ALIGNED2(buffer(), (lineStartPos+startIndex+di))
       return lineStartPos + startIndex + di;
@@ -2066,24 +2077,31 @@
 
 
 /**
- \brief Find the index of the character that lies at the given x position.
+ \brief Find the index of the character that lies at the given x position / closest cursor position.
 
  \param s UTF-8 text string
  \param len length of string
  \param style index into style lookup table
- \param x position in pixels
+ \param x position in pixels - negative returns closest cursor position
  \return index into buffer
  */
 int Fl_Text_Display::find_x(const char *s, int len, int style, int x) const {
   IS_UTF8_ALIGNED(s)
 
+  int cursor_pos = x<0; // STR #2788
+  x = x<0 ? -x : x;     // STR #2788
+
   // TODO: use binary search which may be quicker.
   int i = 0;
+  int last_w = 0;       // STR #2788
   while (i<len) {
     int cl = fl_utf8len1(s[i]);
     int w = int( string_width(s, i+cl, style) );
-    if (w>x)
+    if (w>x) {
+      if (cursor_pos && (w-x < x-last_w)) return i+cl; // STR #2788
       return i;
+    }
+    last_w = w;        // STR #2788
     i += cl;
   }
   return len;
@@ -2496,7 +2514,8 @@
   /* Get the line text and its length */
   lineLen = vline_length( visLineNum );
 
-  return handle_vline(FIND_INDEX,
+  int mode = (posType == CURSOR_POS) ? FIND_CURSOR_INDEX : FIND_INDEX; // STR #2788
+  return handle_vline(mode,
                       lineStart, lineLen, 0, 0,
                       0, 0,
                       text_area.x, X);
