diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-10-11 13:38:29 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-10-11 13:38:29 +0300 |
commit | c17b4bc36de5d610c477e7cdca66e165260c94b8 (patch) | |
tree | decb4a0484d285f46c6b2d920c0fae04e48735b6 /src/ui/documentwidget.c | |
parent | d6a9b598a9d469ece721c2ee9dbddd56ca526643 (diff) |
DocumentWidget: Fixed text selection regressions
The HarfBuzz and wrapped text changes introduced subtle differences in how text selection works. Fixed a bunch of issues regarding how the individual character selection mode works in edge cases.
IssueID #357
Diffstat (limited to 'src/ui/documentwidget.c')
-rw-r--r-- | src/ui/documentwidget.c | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 589b9e56..93b2166b 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -3380,7 +3380,7 @@ static void beginMarkingSelection_DocumentWidget_(iDocumentWidget *d, iInt2 pos) | |||
3380 | invalidateWideRunsWithNonzeroOffset_DocumentWidget_(d); | 3380 | invalidateWideRunsWithNonzeroOffset_DocumentWidget_(d); |
3381 | resetWideRuns_DocumentWidget_(d); /* Selections don't support horizontal scrolling. */ | 3381 | resetWideRuns_DocumentWidget_(d); /* Selections don't support horizontal scrolling. */ |
3382 | iChangeFlags(d->flags, selecting_DocumentWidgetFlag, iTrue); | 3382 | iChangeFlags(d->flags, selecting_DocumentWidgetFlag, iTrue); |
3383 | d->selectMark = sourceLoc_DocumentWidget_(d, pos); | 3383 | d->initialSelectMark = d->selectMark = sourceLoc_DocumentWidget_(d, pos); |
3384 | refresh_Widget(as_Widget(d)); | 3384 | refresh_Widget(as_Widget(d)); |
3385 | } | 3385 | } |
3386 | 3386 | ||
@@ -3804,7 +3804,13 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
3804 | } | 3804 | } |
3805 | } | 3805 | } |
3806 | else { | 3806 | else { |
3807 | d->selectMark.end = (d->selectMark.end > d->selectMark.start ? loc.end : loc.start); | 3807 | d->selectMark.end = loc.end;// (d->selectMark.end > d->selectMark.start ? loc.end : loc.start); |
3808 | if (loc.start < d->initialSelectMark.start) { | ||
3809 | d->selectMark.end = loc.start; | ||
3810 | } | ||
3811 | if (isEmpty_Range(&d->selectMark)) { | ||
3812 | d->selectMark = d->initialSelectMark; | ||
3813 | } | ||
3808 | } | 3814 | } |
3809 | } | 3815 | } |
3810 | iAssert((!d->selectMark.start && !d->selectMark.end) || | 3816 | iAssert((!d->selectMark.start && !d->selectMark.end) || |
@@ -3822,13 +3828,13 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
3822 | d->initialSelectMark.start = | 3828 | d->initialSelectMark.start = |
3823 | d->initialSelectMark.end = d->selectMark.start; | 3829 | d->initialSelectMark.end = d->selectMark.start; |
3824 | } | 3830 | } |
3825 | if (!isEmpty_Range(&d->initialSelectMark)) { | 3831 | } |
3826 | if (d->selectMark.end > d->selectMark.start) { | 3832 | if (d->initialSelectMark.start) { |
3827 | d->selectMark.start = d->initialSelectMark.start; | 3833 | if (d->selectMark.end > d->selectMark.start) { |
3828 | } | 3834 | d->selectMark.start = d->initialSelectMark.start; |
3829 | else if (d->selectMark.end < d->selectMark.start) { | 3835 | } |
3830 | d->selectMark.start = d->initialSelectMark.end; | 3836 | else if (d->selectMark.end < d->selectMark.start) { |
3831 | } | 3837 | d->selectMark.start = d->initialSelectMark.end; |
3832 | } | 3838 | } |
3833 | } | 3839 | } |
3834 | // printf("mark %zu ... %zu\n", d->selectMark.start - cstr_String(source_GmDocument(d->doc)), | 3840 | // printf("mark %zu ... %zu\n", d->selectMark.start - cstr_String(source_GmDocument(d->doc)), |
@@ -4026,12 +4032,11 @@ static void fillRange_DrawContext_(iDrawContext *d, const iGmRun *run, enum iCol | |||
4026 | } | 4032 | } |
4027 | int w = width_Rect(run->visBounds) - x; | 4033 | int w = width_Rect(run->visBounds) - x; |
4028 | if (contains_Range(&run->text, mark.end) || mark.end < run->text.start) { | 4034 | if (contains_Range(&run->text, mark.end) || mark.end < run->text.start) { |
4029 | w = measureRange_Text( | 4035 | iRangecc mk = !*isInside ? mark |
4030 | run->textParams.font, | 4036 | : (iRangecc){ run->text.start, iMax(run->text.start, mark.end) }; |
4031 | !*isInside ? mark | 4037 | mk.start = iMax(mk.start, run->text.start); |
4032 | : (iRangecc){ run->text.start, iMax(run->text.start, mark.end) }) | 4038 | w = measureRange_Text(run->textParams.font, mk).advance.x; |
4033 | .advance.x; | 4039 | *isInside = iFalse; |
4034 | *isInside = iFalse; | ||
4035 | } | 4040 | } |
4036 | else { | 4041 | else { |
4037 | *isInside = iTrue; /* at least until the next run */ | 4042 | *isInside = iTrue; /* at least until the next run */ |