summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generic/tkTextDisp.c33
-rw-r--r--tests/textDisp.test11
2 files changed, 31 insertions, 13 deletions
diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c
index d45ac73..4d41134 100644
--- a/generic/tkTextDisp.c
+++ b/generic/tkTextDisp.c
@@ -6590,6 +6590,7 @@ FindDLine(
CONST TkTextIndex *indexPtr)/* Index of desired character. */
{
DLine *dlPtrPrev;
+ TkTextIndex indexPtr2;
if (dlPtr == NULL) {
return NULL;
@@ -6614,7 +6615,6 @@ FindDLine(
dlPtrPrev = dlPtr;
dlPtr = dlPtr->nextPtr;
if (dlPtr == NULL) {
- TkTextIndex indexPtr2;
/*
* We're past the last display line, either because the desired
* index lies past the visible text, or because the desired index
@@ -6632,14 +6632,41 @@ FindDLine(
} else {
/*
* The desired index is past the visible text. There is no
- * display line displaying something at the desired index
+ * display line displaying something at the desired index.
* --> return NULL.
*/
}
break;
}
if (TkTextIndexCmp(&dlPtr->index,indexPtr) > 0) {
- dlPtr = dlPtrPrev;
+ /*
+ * If we're here then we would normally expect that:
+ * dlPtrPrev->index <= indexPtr < dlPtr->index
+ * i.e. we have found the searched display line being dlPtr.
+ * However it is possible that some DLines were unlinked
+ * previously, leading to a situation where going through
+ * the list of display lines skips display lines that did
+ * exist just a moment ago.
+ */
+ indexPtr2 = dlPtrPrev->index;
+ TkTextIndexForwBytes(textPtr, &indexPtr2, dlPtrPrev->byteCount,
+ &indexPtr2);
+ if (TkTextIndexCmp(&indexPtr2,indexPtr) > 0) {
+ /*
+ * Confirmed:
+ * dlPtrPrev->index <= indexPtr < dlPtr->index
+ * --> return dlPtrPrev.
+ */
+ dlPtr = dlPtrPrev;
+ } else {
+ /*
+ * The last (rightmost) index shown by dlPtrPrev is still
+ * before the desired index. This may be because there was
+ * previously a display line between dlPtrPrev and dlPtr
+ * and this display line has been unlinked.
+ * --> return dlPtr.
+ */
+ }
break;
}
}
diff --git a/tests/textDisp.test b/tests/textDisp.test
index 6aa3721..885c940 100644
--- a/tests/textDisp.test
+++ b/tests/textDisp.test
@@ -1181,16 +1181,7 @@ test textDisp-8.12 {TkTextChanged, moving the insert cursor redraws only past an
.t mark set insert 3.8 ; # within the same line
update
lappend res $tk_textRedraw
- # This last one is tricky: correct result really is {2.0 3.0} when
- # calling .t mark set insert, two calls to TkTextChanged are done:
- # (a) to redraw the line of the past position of the cursor
- # (b) to redraw the line of the new position of the cursor
- # During (a) the display line showing the cursor gets unlinked,
- # which leads TkTextChanged in (b) to schedule a redraw starting
- # one line _before_ the line containing the insert cursor. This is
- # because during (b) findDLine cannot return the display line the
- # cursor is in since this display line was just unlinked in (a).
-} {{8.0 9.0} {8.0 12.0} {8.0 12.0} {3.0 8.0} {2.0 3.0}}
+} {{8.0 9.0} {8.0 12.0} {8.0 12.0} {3.0 8.0} {3.0 4.0}}
test textDisp-8.13 {TkTextChanged, used to crash, see [06c1433906]} {
.t delete 1.0 end
.t insert 1.0 \nLine2\nLine3\n