diff options
author | dgp <dgp@users.sourceforge.net> | 2019-05-15 18:05:47 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2019-05-15 18:05:47 (GMT) |
commit | 273f03adcc49bca49f4941c8adb241b5ccc26c25 (patch) | |
tree | 4f0c7c023f723c39c34497f0c11a39407ba8e7f3 | |
parent | aefe754799655f3fa04cc84f4ea5d110d0289c46 (diff) | |
download | tk-273f03adcc49bca49f4941c8adb241b5ccc26c25.zip tk-273f03adcc49bca49f4941c8adb241b5ccc26c25.tar.gz tk-273f03adcc49bca49f4941c8adb241b5ccc26c25.tar.bz2 |
Tests and fix for similar issues in [menu].
-rw-r--r-- | generic/tkMenu.c | 32 | ||||
-rw-r--r-- | generic/tkScale.c | 1 | ||||
-rw-r--r-- | tests/menu.test | 28 |
3 files changed, 53 insertions, 8 deletions
diff --git a/generic/tkMenu.c b/generic/tkMenu.c index 42ddbd5..d7f5858 100644 --- a/generic/tkMenu.c +++ b/generic/tkMenu.c @@ -2486,9 +2486,10 @@ MenuVarProc( const char *value; const char *name, *onValue; - if (flags & TCL_INTERP_DESTROYED) { + if (Tcl_InterpDeleted(interp) || (mePtr->namePtr == NULL)) { /* - * Do nothing if the interpreter is going away. + * Do nothing if the interpreter is going away or we have + * no variable name. */ return NULL; @@ -2507,12 +2508,29 @@ MenuVarProc( */ if (flags & TCL_TRACE_UNSETS) { + ClientData probe = NULL; mePtr->entryFlags &= ~ENTRY_SELECTED; - if (flags & TCL_TRACE_DESTROYED) { - Tcl_TraceVar2(interp, name, NULL, - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - MenuVarProc, clientData); - } + + do { + probe = Tcl_VarTraceInfo(interp, name, + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + MenuVarProc, probe); + if (probe == (ClientData)mePtr) { + break; + } + } while (probe); + if (probe) { + /* + * We were able to fetch the unset trace for our + * namePtr, which means it is not unset and not + * the cause of this unset trace. Instead some outdated + * former variable must be, and we should ignore it. + */ + return NULL; + } + Tcl_TraceVar2(interp, name, NULL, + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + MenuVarProc, clientData); TkpConfigureMenuEntry(mePtr); TkEventuallyRedrawMenu(menuPtr, NULL); return NULL; diff --git a/generic/tkScale.c b/generic/tkScale.c index 3920aea..4630170 100644 --- a/generic/tkScale.c +++ b/generic/tkScale.c @@ -1198,7 +1198,6 @@ ScaleVarProc( */ if (flags & TCL_TRACE_UNSETS) { - if (!Tcl_InterpDeleted(interp) && scalePtr->varNamePtr) { ClientData probe = NULL; diff --git a/tests/menu.test b/tests/menu.test index 95699ff..9378686 100644 --- a/tests/menu.test +++ b/tests/menu.test @@ -3162,6 +3162,34 @@ test menu-17.5 {MenuVarProc} -setup { } -cleanup { deleteWindows } -result {{} goodbye {}} +test menu-17.6 {MenuVarProc [5d991b822e]} -setup { + deleteWindows +} -body { + # Want this not to crash + menu .b + set var INIT + .b add checkbutton -variable var + trace add variable var unset {apply {args { + .b entryconfigure 1 -variable {} + }}} + unset var +} -cleanup { + deleteWindows +} -result {} +test menu-17.7 {MenuVarProc [5d991b822e]} -setup { + deleteWindows +} -body { + # Want this not to duplicate traces + menu .b + set var INIT + .b add checkbutton -variable var + trace add variable var unset {apply {args { + .b entryconfigure 1 -variable new + }}} + unset var +} -cleanup { + deleteWindows +} -result {} test menu-18.1 {TkActivateMenuEntry} -setup { |