Index: ChangeLog ================================================================== --- ChangeLog +++ ChangeLog @@ -129,10 +129,16 @@ 2012-12-03 François Vogel * generic/tkTextIndex.c: [Bug 3588824]: bug in image index handling * tests/textIndex.test: for weird image names + +2012-11-16 Joe Mistachkin + + * generic/tkBind.c: Add support for an 'M' binding substitution + that is replaced with the number of script-based binding patterns + matched so far for the event. 2012-11-13 Jan Nijtmans * win/tkWinTest.c: [Bug 3585396]: winDialog.test requires user * tests/winDialog.test: interaction. Renumber test-cases as in Tk 8.6, Index: doc/bind.n ================================================================== --- doc/bind.n +++ doc/bind.n @@ -546,10 +546,13 @@ .QW synthetic event generated by \fBSendEvent\fR. .IP \fB%K\fR 5 The keysym corresponding to the event, substituted as a textual string. Valid only for \fBKeyPress\fR and \fBKeyRelease\fR events. +.IP \fB%M\fR 5 +The number of script-based binding patterns matched so far for the +event. Valid for all event types. .IP \fB%N\fR 5 The keysym corresponding to the event, substituted as a decimal number. Valid only for \fBKeyPress\fR and \fBKeyRelease\fR events. .IP \fB%P\fR 5 The name of the property being updated or deleted (which Index: generic/tkBind.c ================================================================== --- generic/tkBind.c +++ generic/tkBind.c @@ -658,11 +658,12 @@ static int DeleteVirtualEvent(Tcl_Interp *interp, VirtualEventTable *vetPtr, char *virtString, char *eventString); static void DeleteVirtualEventTable(VirtualEventTable *vetPtr); static void ExpandPercents(TkWindow *winPtr, const char *before, - XEvent *eventPtr,KeySym keySym,Tcl_DString *dsPtr); + XEvent *eventPtr,KeySym keySym, + unsigned int scriptCount, Tcl_DString *dsPtr); static void FreeTclBinding(ClientData clientData); static PatSeq * FindSequence(Tcl_Interp *interp, Tcl_HashTable *patternTablePtr, ClientData object, const char *eventString, int create, int allowVirtual, unsigned long *maskPtr); @@ -1413,10 +1414,11 @@ TkDisplay *oldDispPtr; XEvent *ringPtr; PatSeq *vMatchDetailList, *vMatchNoDetailList; int flags, oldScreen, i, deferModal; unsigned int matchCount, matchSpace; + unsigned int scriptCount; Tcl_Interp *interp; Tcl_DString scripts, savedResult; Detail detail; char *p, *end; PendingBinding staticPending, *pendingPtr; @@ -1569,10 +1571,11 @@ * callbacks. */ pendingPtr = &staticPending; matchCount = 0; + scriptCount = 0; matchSpace = sizeof(staticPending.matchArray) / sizeof(PatSeq *); Tcl_DStringInit(&scripts); for ( ; numObjects > 0; numObjects--, objectPtr++) { PatSeq *matchPtr = NULL, *sourcePtr = NULL; @@ -1626,11 +1629,11 @@ if (sourcePtr->eventProc == NULL) { Tcl_Panic("Tk_BindEvent: missing command"); } if (sourcePtr->eventProc == EvalTclBinding) { ExpandPercents(winPtr, (char *) sourcePtr->clientData, - eventPtr, detail.keySym, &scripts); + eventPtr, detail.keySym, scriptCount++, &scripts); } else { if (matchCount >= matchSpace) { PendingBinding *newPtr; unsigned int oldSize, newSize; @@ -2257,10 +2260,12 @@ * be replaced. */ XEvent *eventPtr, /* X event containing information to be used * in % replacements. */ KeySym keySym, /* KeySym: only relevant for KeyPress and * KeyRelease events). */ + unsigned int scriptCount, /* The number of script-based binding patterns + * matched so far for this event. */ Tcl_DString *dsPtr) /* Dynamic string in which to append new * command. */ { int spaceNeeded, cvtFlags; /* Used to substitute string as proper Tcl * list element. */ @@ -2538,10 +2543,13 @@ if (name != NULL) { string = name; } } goto doString; + case 'M': + number = scriptCount; + goto doNumber; case 'N': if ((flags & KEY) && (eventPtr->type != MouseWheelEvent)) { number = (int) keySym; goto doNumber; } Index: tests/bind.test ================================================================== --- tests/bind.test +++ tests/bind.test @@ -23,10 +23,18 @@ pack .b.f focus -force .b.f foreach p [event info] {event delete $p} update } +proc setup2 {} { + catch {destroy .b.e} + entry .b.e + pack .b.e + focus -force .b.e + foreach p [event info] {event delete $p} + update +} setup foreach i [bind Test] { bind Test $i {} } @@ -1563,10 +1571,28 @@ bind .b.f {set x "%R %S"} set x none event gen .b.f set x } {?? ??} +test bind-16.45 {ExpandPercents procedure} { + setup2 + bind .b.e {set x "%M"} + bind Entry {set y "%M"} + bind all {set z "%M"} + set x none; set y none; set z none + event gen .b.e + list $x $y $z +} {0 1 2} +test bind-16.46 {ExpandPercents procedure} { + setup2 + bind all {set z "%M"} + bind Entry {set y "%M"} + bind .b.e {set x "%M"} + set x none; set y none; set z none + event gen .b.e + list $x $y $z +} {0 1 2} test bind-17.1 {event command} { list [catch {event} msg] $msg } {1 {wrong # args: should be "event option ?arg?"}}