In TextFieldSkin#positionCaret the caret position is set to hit.getInsertionIndex(); and the bias to setForwardBias(hit.isLeading());
This is wrong because hit.getInsertionIndex() already adds one when leading==false, see HitInfo:
public int getInsertionIndex() {
return leading ? charIndex : charIndex + 1;
}
That means when trailing is true this code will place caret in the trailing edge of the next characters of the hit.
This only works today because Text does not implement caret bias but that is about to change.
Note also that adding one to charIndex is not 100% correct, it does not work for bidi boundary nor for line end of wrapped lines.
Other problem I have is the doc of caretBias,
currently the code in controls uses caretBias==leading, meaning
caretBias==true, caret at the leading edge of character at charIndex
caretBias==false, caret at the trailing edge of character at charIndex
The doc for caretBias in Text reads:
* caret bias in the content. true means a bias towards forward character
Which makes me think that caretBias==true really trailing (towards the next character)...
In short, the code today does:
text.setImpl_caretPosition(info.getInsertionIndex());
text.setImpl_caretBias(info.isLeading());
But it should be
text.setImpl_caretPosition(info.getCharIndex());
text.setImpl_caretBias(info.isLeading());
or, depending on the definition of caretBias:
text.setImpl_caretPosition(info.getCharIndex());
text.setImpl_caretBias(!info.isLeading());