diff --git a/ChangeLog b/ChangeLog index 45ea8d7fe..0276ef598 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2010-02-12 Wolfgang Lux + + * Source/NSTextView.m (-_characterIndexForPoint:respectFraction:): + Fix issue where the insertion point was put at the end of the last + but one line when the user clicks in or below the last line with + the mouse and the last line is empty. + * Source/NSLayoutManager.m (-characterIndexMoving:...): Add extra + test to allow moving downward into an empty last line. Fixes #15893. + * Source/NSLayoutManager.m (-_insertionPointRect...:textContainer:): + Add special case for end of text. Fixes an issue where the + insertion point is not set correctly when the last line ends with + an invisible character (e.g., a tab). + 2010-02-12 Wolfgang Lux * Source/NSAttributedString.m: diff --git a/Source/NSLayoutManager.m b/Source/NSLayoutManager.m index 4764583dc..79a5af890 100644 --- a/Source/NSLayoutManager.m +++ b/Source/NSLayoutManager.m @@ -802,7 +802,7 @@ has the same y origin and height as the line frag rect it is in. if (extra_textcontainer) { for (tc = textcontainers, i = 0; i < num_textcontainers; i++, tc++) - if (tc == textcontainers) + if (tc->textContainer == extra_textcontainer) break; NSAssert(i < num_textcontainers, @"invalid extraTextContainer"); *textContainer = i; @@ -821,8 +821,9 @@ has the same y origin and height as the line frag rect it is in. } fraction_through = 1.0; } + else + [self _doLayoutToGlyph: glyph_index]; - [self _doLayoutToGlyph: glyph_index]; for (tc = textcontainers, i = 0; i < num_textcontainers; i++, tc++) if (tc->pos + tc->length > glyph_index) break; @@ -836,6 +837,20 @@ has the same y origin and height as the line frag rect it is in. LINEFRAG_FOR_GLYPH(glyph_index); + /* Special case if we are asked for the insertion point rectangle at the + end of text, since the standard code yields an incorrect result if the + last line fragment ends with an invisible character (e.g., a tab). + Note that fraction_through is always less than 1 except when + -_glyphIndexForCharacterIndex:fractionThrough: is called for + cindex == [_textStorage length], in which case we set it to 1. */ + if (fraction_through == 1.0) + { + r = lf->used_rect; + r.origin.x += r.size.width; + r.size.width = 1; + return r; + } + { unsigned int i; int j; @@ -1023,6 +1038,12 @@ has the same y origin and height as the line frag rect it is in. if (i == tc->num_linefrags) { + /* Special case for moving into the extra line at the end */ + if (tc->textContainer == extra_textcontainer && + NSMaxY(extra_rect) >= distance + NSMaxY(from_rect) && + NSMinY(extra_rect) != NSMinY(from_rect)) + return length; + /* We can't move as far as we want to. In fact, we might not have been able to move at all. TODO: figure out how to handle this diff --git a/Source/NSTextView.m b/Source/NSTextView.m index 18b539383..641de6b59 100644 --- a/Source/NSTextView.m +++ b/Source/NSTextView.m @@ -1936,6 +1936,13 @@ or add guards point.x -= _textContainerOrigin.x; point.y -= _textContainerOrigin.y; + if ([_layoutManager extraLineFragmentTextContainer] == _textContainer) + { + NSRect extraRect = [_layoutManager extraLineFragmentRect]; + if (point.y >= NSMinY(extraRect)) + return [_textStorage length]; + } + index = [_layoutManager glyphIndexForPoint: point inTextContainer: _textContainer fractionOfDistanceThroughGlyph: &fraction];