Index: generic/tkEntry.c ================================================================== --- generic/tkEntry.c +++ generic/tkEntry.c @@ -3291,21 +3291,25 @@ char *p; Tcl_DString script; if (entryPtr->validateCmd == NULL || entryPtr->validate == VALIDATE_NONE) { + if (entryPtr->flags & VALIDATING) { + entryPtr->flags |= VALIDATE_ABORT; + } return (varValidate ? TCL_ERROR : TCL_OK); } /* - * If we're already validating, then we're hitting a loop condition Return - * and set validate to 0 to disallow further validations and prevent - * current validation from finishing + * If we're already validating, then we're hitting a loop condition. Set + * validate to none to disallow further validations, arrange for flags + * to prevent current validation from finishing, and return. */ if (entryPtr->flags & VALIDATING) { entryPtr->validate = VALIDATE_NONE; + entryPtr->flags |= VALIDATE_ABORT; return (varValidate ? TCL_ERROR : TCL_OK); } entryPtr->flags |= VALIDATING; Index: tests/entry.test ================================================================== --- tests/entry.test +++ tests/entry.test @@ -3356,11 +3356,11 @@ .e configure -validatecommand [list doval2 %W %d %i %P %s %S %v %V] .e validate list [.e cget -validate] [.e get] $::vVals } -cleanup { destroy .e -} -result {none mydata {.e -1 -1 nextdata nextdata {} all forced}} +} -result {none nextdata {.e -1 -1 nextdata nextdata {} all forced}} ## This leaves validate alone because we trigger validation through the ## textvar (a write trace), and the write during validation triggers ## nothing (by definition of avoiding loops on var traces). This is ## one of those "dangerous" conditions where the user will have a @@ -3382,10 +3382,30 @@ set ::e testdata list [.e cget -validate] [.e get] $::e $::vVals } -cleanup { destroy .e } -result {all testdata mydata {.e -1 -1 testdata mydata {} all forced}} + +## This leaves validate alone because we trigger validation through the +## textvar (a write trace), and the write during validation triggers +## nothing (by definition of avoiding loops on var traces). This is +## one of those "dangerous" conditions where the user will have a +## different value in the entry widget shown as is in the textvar. +test entry-19.21 {entry widget validation - bug 40e4bf6198} -setup { + unset -nocomplain ::e ::vVals +} -body { + entry .e -validate key \ + -validatecommand [list doval2 %W %d %i %P %s %S %v %V] \ + -textvariable ::e + pack .e + set ::e origdata + .e insert 0 A + list [.e cget -validate] [.e get] $::e $::vVals +} -cleanup { + destroy .e +} -result {none origdata mydata {.e 1 0 Aorigdata origdata A key key}} + ## ## End validation tests ## test entry-20.1 {widget deletion while active} -body { Index: tests/spinbox.test ================================================================== --- tests/spinbox.test +++ tests/spinbox.test @@ -3592,11 +3592,11 @@ .e configure -validatecommand [list doval2 %W %d %i %P %s %S %v %V] .e validate list [.e cget -validate] [.e get] $::vVals } -cleanup { destroy .e -} -result {none mydata {.e -1 -1 nextdata nextdata {} all forced}} +} -result {none nextdata {.e -1 -1 nextdata nextdata {} all forced}} ## This leaves validate alone because we trigger validation through the ## textvar (a write trace), and the write during validation triggers ## nothing (by definition of avoiding loops on var traces). This is ## one of those "dangerous" conditions where the user will have a @@ -3618,10 +3618,30 @@ set ::e testdata list [.e cget -validate] [.e get] $::e $::vVals } -cleanup { destroy .e } -result {all testdata mydata {.e -1 -1 testdata mydata {} all forced}} + +## This leaves validate alone because we trigger validation through the +## textvar (a write trace), and the write during validation triggers +## nothing (by definition of avoiding loops on var traces). This is +## one of those "dangerous" conditions where the user will have a +## different value in the entry widget shown as is in the textvar. +test spinbox-19.21 {spinbox widget validation - bug 40e4bf6198} -setup { + unset -nocomplain ::e ::vVals +} -body { + spinbox .e -validate key \ + -validatecommand [list doval2 %W %d %i %P %s %S %v %V] \ + -textvariable ::e + pack .e + set ::e origdata + .e insert 0 A + list [.e cget -validate] [.e get] $::e $::vVals +} -cleanup { + destroy .e +} -result {none origdata mydata {.e 1 0 Aorigdata origdata A key key}} + ## ## End validation tests ## test spinbox-20.1 {spinbox config, -format specifier} -body {