From a906189ba8d0deb1700017221317967a9d5dc133 Mon Sep 17 00:00:00 2001 From: vincentdarley Date: Wed, 12 Nov 2003 17:19:17 +0000 Subject: old tk text widget bugs fixed --- ChangeLog | 12 ++++++++++++ generic/tkText.c | 7 +++++-- generic/tkText.h | 8 ++------ generic/tkTextDisp.c | 48 +++++++++++++++++++++++++++++++++--------------- generic/tkTextIndex.c | 4 ++-- generic/tkTextTag.c | 19 ++++++++++++------- tests/textTag.test | 31 +++++++++++++++++++++++++++++-- 7 files changed, 95 insertions(+), 34 deletions(-) diff --git a/ChangeLog b/ChangeLog index ecf5853..6292099 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2003-11-12 Vince Darley + + * generic/tkText.h: + * generic/tkText.c: + * generic/tkTextDisp.c: + * generic/tkTextIndex.c: + * generic/tkTextTag.c: + * tests/textTag.test: fixes to two very old Tk bugs [Bug 583286] + (focus handling with embedded windows), [Bug 220780] (tag + bindings trigger on window borders), and made two more functions + static in tkTextDisp.c. + 2003-11-11 Jeff Hobbs * unix/configure: diff --git a/generic/tkText.c b/generic/tkText.c index ed826db..6e0b2be 100644 --- a/generic/tkText.c +++ b/generic/tkText.c @@ -14,7 +14,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkText.c,v 1.41 2003/11/10 21:02:35 dkf Exp $ + * RCS: @(#) $Id: tkText.c,v 1.42 2003/11/12 17:19:17 vincentdarley Exp $ */ #include "default.h" @@ -1817,7 +1817,10 @@ TextEventProc(clientData, eventPtr) */ DestroyText(textPtr); } else if ((eventPtr->type == FocusIn) || (eventPtr->type == FocusOut)) { - if (eventPtr->xfocus.detail != NotifyInferior) { + if (eventPtr->xfocus.detail != NotifyInferior + || eventPtr->xfocus.detail == NotifyAncestor + || eventPtr->xfocus.detail == NotifyNonlinear + ) { Tcl_DeleteTimerHandler(textPtr->insertBlinkHandler); if (eventPtr->type == FocusIn) { textPtr->flags |= GOT_FOCUS | INSERT_ON; diff --git a/generic/tkText.h b/generic/tkText.h index 16e617a..6ca5084 100644 --- a/generic/tkText.h +++ b/generic/tkText.h @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkText.h,v 1.19 2003/11/08 17:22:46 vincentdarley Exp $ + * RCS: @(#) $Id: tkText.h,v 1.20 2003/11/12 17:19:18 vincentdarley Exp $ */ #ifndef _TKTEXT @@ -1016,14 +1016,10 @@ EXTERN int TkTextMakePixelIndex _ANSI_ARGS_((TkText *textPtr, int pixelIndex, TkTextIndex *indexPtr)); EXTERN void TkTextInvalidateLineMetrics _ANSI_ARGS_((TkText *textPtr, TkTextLine *linePtr, int lineCount, int action)); -EXTERN void TkTextAsyncUpdateLineMetrics _ANSI_ARGS_((ClientData - clientData)); EXTERN int TkTextUpdateLineMetrics _ANSI_ARGS_((TkText *textPtr, int lineNum, int endLine, int doThisMuch)); EXTERN int TkTextUpdateOneLine _ANSI_ARGS_((TkText *textPtr, TkTextLine *linePtr)); -EXTERN void TkTextUpdateYScrollbar _ANSI_ARGS_((ClientData - clientData)); EXTERN int TkTextMarkCmd _ANSI_ARGS_((TkText *textPtr, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); EXTERN int TkTextMarkNameToIndex _ANSI_ARGS_((TkText *textPtr, @@ -1034,7 +1030,7 @@ EXTERN void TkTextEventuallyRepick _ANSI_ARGS_((TkText *textPtr)); EXTERN void TkTextPickCurrent _ANSI_ARGS_((TkText *textPtr, XEvent *eventPtr)); EXTERN void TkTextPixelIndex _ANSI_ARGS_((TkText *textPtr, - int x, int y, TkTextIndex *indexPtr)); + int x, int y, TkTextIndex *indexPtr, int *nearest)); EXTERN int TkTextPrintIndex _ANSI_ARGS_(( CONST TkTextIndex *indexPtr, char *string)); EXTERN Tcl_Obj* TkTextNewIndexObj _ANSI_ARGS_((TkText *textPtr, diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c index ee1e40b..4ca732f 100644 --- a/generic/tkTextDisp.c +++ b/generic/tkTextDisp.c @@ -13,7 +13,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkTextDisp.c,v 1.26 2003/11/10 14:37:33 vincentdarley Exp $ + * RCS: @(#) $Id: tkTextDisp.c,v 1.27 2003/11/12 17:19:18 vincentdarley Exp $ */ #include "tkPort.h" @@ -446,6 +446,10 @@ static int TextGetScrollInfoObj _ANSI_ARGS_((Tcl_Interp *interp, TkText *textPtr, int objc, Tcl_Obj *CONST objv[], double *dblPtr, int *intPtr)); +static void AsyncUpdateLineMetrics _ANSI_ARGS_((ClientData + clientData)); +static void AsyncUpdateYScrollbar _ANSI_ARGS_((ClientData + clientData)); /* * Result values returned by TextGetScrollInfo: @@ -513,10 +517,10 @@ TkTextCreateDInfo(textPtr) /* Add a refCount for each of the idle call-backs */ textPtr->refCount++; dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(0, - TkTextAsyncUpdateLineMetrics, (ClientData) textPtr); + AsyncUpdateLineMetrics, (ClientData) textPtr); textPtr->refCount++; dInfoPtr->scrollbarTimer = Tcl_CreateTimerHandler(200, - TkTextUpdateYScrollbar, (ClientData) textPtr); + AsyncUpdateYScrollbar, (ClientData) textPtr); textPtr->dInfoPtr = dInfoPtr; @@ -2462,7 +2466,7 @@ DisplayLineBackground(textPtr, dlPtr, prevPtr, pixmap) /* *---------------------------------------------------------------------- * - * TkTextAsyncUpdateLineMetrics -- + * AsyncUpdateLineMetrics -- * * This procedure is invoked as a background handler to update the * pixel-height calculations of individual lines in an @@ -2484,8 +2488,8 @@ DisplayLineBackground(textPtr, dlPtr, prevPtr, pixmap) *---------------------------------------------------------------------- */ -void -TkTextAsyncUpdateLineMetrics(clientData) +static void +AsyncUpdateLineMetrics(clientData) ClientData clientData; /* Information about widget. */ { register TkText *textPtr = (TkText *) clientData; @@ -2534,7 +2538,7 @@ TkTextAsyncUpdateLineMetrics(clientData) * so no need to adjust that. */ dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1, - TkTextAsyncUpdateLineMetrics, (ClientData) textPtr); + AsyncUpdateLineMetrics, (ClientData) textPtr); } /* @@ -2784,7 +2788,7 @@ TkTextInvalidateLineMetrics(textPtr, linePtr, lineCount, action) if (dInfoPtr->lineUpdateTimer == NULL) { textPtr->refCount++; dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1, - TkTextAsyncUpdateLineMetrics, (ClientData) textPtr); + AsyncUpdateLineMetrics, (ClientData) textPtr); } } @@ -3140,7 +3144,7 @@ TkTextUpdateOneLine(textPtr, linePtr) if (textPtr->dInfoPtr->scrollbarTimer == NULL) { textPtr->refCount++; textPtr->dInfoPtr->scrollbarTimer = Tcl_CreateTimerHandler(200, - TkTextUpdateYScrollbar, (ClientData) textPtr); + AsyncUpdateYScrollbar, (ClientData) textPtr); } return displayLines; } @@ -4157,7 +4161,7 @@ TkTextRelayoutWindow(textPtr, mask) if (dInfoPtr->lineUpdateTimer == NULL) { textPtr->refCount++; dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1, - TkTextAsyncUpdateLineMetrics, (ClientData) textPtr); + AsyncUpdateLineMetrics, (ClientData) textPtr); } } } @@ -5464,7 +5468,7 @@ GetYView(interp, textPtr, report) /* *---------------------------------------------------------------------- * - * TkTextUpdateYScrollbar -- + * AsyncUpdateYScrollbar -- * * This procedure is called to update the vertical scrollbar * asychronously as the pixel height calculations progress for @@ -5480,8 +5484,8 @@ GetYView(interp, textPtr, report) *---------------------------------------------------------------------- */ -void -TkTextUpdateYScrollbar(clientData) +static void +AsyncUpdateYScrollbar(clientData) ClientData clientData; /* Information about widget. */ { register TkText *textPtr = (TkText *) clientData; @@ -5589,15 +5593,21 @@ FindDLine(dlPtr, indexPtr) */ void -TkTextPixelIndex(textPtr, x, y, indexPtr) +TkTextPixelIndex(textPtr, x, y, indexPtr, nearest) TkText *textPtr; /* Widget record for text widget. */ int x, y; /* Pixel coordinates of point in widget's * window. */ TkTextIndex *indexPtr; /* This index gets filled in with the * index of the character nearest to (x,y). */ + int *nearest; /* If non-NULL then gets set to 0 if + * (x,y) is actually over the returned + * index, and 1 if it is just nearby + * (e.g. if x,y is on the border of the + * widget). */ { TextDInfo *dInfoPtr = textPtr->dInfoPtr; register DLine *dlPtr, *validDlPtr; + int nearby = 0; /* * Make sure that all of the layout information about what's @@ -5617,14 +5627,17 @@ TkTextPixelIndex(textPtr, x, y, indexPtr) if (y < dInfoPtr->y) { y = dInfoPtr->y; x = dInfoPtr->x; + nearby = 1; } if (x >= dInfoPtr->maxX) { x = dInfoPtr->maxX - 1; + nearby = 1; } if (x < dInfoPtr->x) { x = dInfoPtr->x; + nearby = 1; } - + /* * Find the display line containing the desired y-coordinate. */ @@ -5640,11 +5653,16 @@ TkTextPixelIndex(textPtr, x, y, indexPtr) */ x = dInfoPtr->maxX - 1; + nearby = 1; break; } } if (dlPtr->chunkPtr == NULL) dlPtr = validDlPtr; + if (nearest != NULL) { + *nearest = nearby; + } + DlineIndexOfX(textPtr, dlPtr, x, indexPtr); } diff --git a/generic/tkTextIndex.c b/generic/tkTextIndex.c index c5ef481..c270320 100644 --- a/generic/tkTextIndex.c +++ b/generic/tkTextIndex.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkTextIndex.c,v 1.11 2003/11/08 17:22:46 vincentdarley Exp $ + * RCS: @(#) $Id: tkTextIndex.c,v 1.12 2003/11/12 17:19:18 vincentdarley Exp $ */ #include "default.h" @@ -781,7 +781,7 @@ GetIndex(interp, textPtr, string, indexPtr, canCachePtr) if (end == cp) { goto error; } - TkTextPixelIndex(textPtr, x, y, indexPtr); + TkTextPixelIndex(textPtr, x, y, indexPtr, NULL); endOfBase = end; goto gotBase; } diff --git a/generic/tkTextTag.c b/generic/tkTextTag.c index aae070a..dc9ae86 100644 --- a/generic/tkTextTag.c +++ b/generic/tkTextTag.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkTextTag.c,v 1.12 2003/11/07 15:36:26 vincentdarley Exp $ + * RCS: @(#) $Id: tkTextTag.c,v 1.13 2003/11/12 17:19:18 vincentdarley Exp $ */ #include "default.h" @@ -1267,7 +1267,7 @@ TkTextPickCurrent(textPtr, eventPtr) TkTextTag **copyArrayPtr = NULL; /* Initialization needed to prevent * compiler warning. */ - int numOldTags, numNewTags, i, j, size; + int numOldTags, numNewTags, i, j, size, nearby; XEvent event; /* @@ -1336,9 +1336,14 @@ TkTextPickCurrent(textPtr, eventPtr) if (textPtr->pickEvent.type != LeaveNotify) { TkTextPixelIndex(textPtr, textPtr->pickEvent.xcrossing.x, - textPtr->pickEvent.xcrossing.y, &index); - newArrayPtr = TkBTreeGetTags(&index, &numNewTags); - SortTags(numNewTags, newArrayPtr); + textPtr->pickEvent.xcrossing.y, &index, &nearby); + if (nearby) { + newArrayPtr = NULL; + numNewTags = 0; + } else { + newArrayPtr = TkBTreeGetTags(&index, &numNewTags); + SortTags(numNewTags, newArrayPtr); + } } else { newArrayPtr = NULL; numNewTags = 0; @@ -1409,11 +1414,11 @@ TkTextPickCurrent(textPtr, eventPtr) */ TkTextPixelIndex(textPtr, textPtr->pickEvent.xcrossing.x, - textPtr->pickEvent.xcrossing.y, &index); + textPtr->pickEvent.xcrossing.y, &index, &nearby); TkTextSetMark(textPtr, "current", &index); if (numNewTags != 0) { if ((textPtr->bindingTable != NULL) && (textPtr->tkwin != NULL) - && !(textPtr->flags & DESTROYED)) { + && !(textPtr->flags & DESTROYED) && !nearby) { event = textPtr->pickEvent; event.type = EnterNotify; event.xcrossing.detail = NotifyAncestor; diff --git a/tests/textTag.test b/tests/textTag.test index 6a60142..8f39142 100644 --- a/tests/textTag.test +++ b/tests/textTag.test @@ -6,14 +6,15 @@ # Copyright (c) 1998-1999 by Scriptics Corporation. # All rights reserved. # -# RCS: @(#) $Id: textTag.test,v 1.8 2003/05/19 13:04:24 vincentdarley Exp $ +# RCS: @(#) $Id: textTag.test,v 1.9 2003/11/12 17:19:18 vincentdarley Exp $ package require tcltest 2.1 eval tcltest::configure $argv tcltest::loadTestedCommands +namespace import -force tcltest::test catch {destroy .t} -testConstraint courier12 [expr {[catch { +tcltest::testConstraint courier12 [expr {[catch { text .t -font {Courier 12} -width 20 -height 10 }] == 0}] @@ -772,6 +773,32 @@ test textTag-17.1 {insert procedure inserts tags} { catch {destroy .t} +test textTag-18.1 {TkTextPickCurrent tag bindings} { + text .t -width 30 -height 4 -relief sunken -borderwidth 10 \ + -highlightthickness 10 -pady 2 + pack .t + + .t insert end " Tag here " TAG " no tag here" + .t tag configure TAG -borderwidth 4 -relief raised + .t tag bind TAG {lappend res "%x %y tag-Enter"} + .t tag bind TAG {lappend res "%x %y tag-Leave"} + bind .t {lappend res Enter} + bind .t {lappend res Leave} + + set res {} + # Bindings must not trigger on the widget border, only over + # the actual tagged characters themselves. + event gen .t -warp 1 -x 0 -y 0 ; update + event gen .t -warp 1 -x 10 -y 10 ; update + event gen .t -warp 1 -x 25 -y 25 ; update + event gen .t -warp 1 -x 20 -y 20 ; update + event gen .t -warp 1 -x 10 -y 10 ; update + event gen .t -warp 1 -x 25 -y 25 ; update + set res +} {Enter {25 25 tag-Enter} {20 20 tag-Leave} {25 25 tag-Enter}} + +catch {destroy .t} + # cleanup cleanupTests return -- cgit v0.12