summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2019-05-15 18:05:47 (GMT)
committerdgp <dgp@users.sourceforge.net>2019-05-15 18:05:47 (GMT)
commit273f03adcc49bca49f4941c8adb241b5ccc26c25 (patch)
tree4f0c7c023f723c39c34497f0c11a39407ba8e7f3
parentaefe754799655f3fa04cc84f4ea5d110d0289c46 (diff)
downloadtk-273f03adcc49bca49f4941c8adb241b5ccc26c25.zip
tk-273f03adcc49bca49f4941c8adb241b5ccc26c25.tar.gz
tk-273f03adcc49bca49f4941c8adb241b5ccc26c25.tar.bz2
Tests and fix for similar issues in [menu].
-rw-r--r--generic/tkMenu.c32
-rw-r--r--generic/tkScale.c1
-rw-r--r--tests/menu.test28
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 {