Attachment "traceprocs.diff" to
ticket [5d991b82]
added by
chw
2018-01-27 09:38:09.
Index: generic/tkButton.c
==================================================================
--- generic/tkButton.c
+++ generic/tkButton.c
@@ -1607,10 +1607,23 @@
int flags) /* Information about what happened. */
{
register TkButton *butPtr = clientData;
const char *value;
Tcl_Obj *valuePtr;
+
+ /*
+ * See ticket [5d991b82].
+ */
+
+ if (butPtr->selVarNamePtr == NULL) {
+ if (!(flags & TCL_INTERP_DESTROYED)) {
+ Tcl_UntraceVar2(interp, name1, name2,
+ TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ ButtonVarProc, clientData);
+ }
+ return NULL;
+ }
/*
* If the variable is being unset, then just re-establish the trace unless
* the whole interpreter is going away.
*/
@@ -1690,18 +1703,31 @@
/* ARGSUSED */
static char *
ButtonTextVarProc(
ClientData clientData, /* Information about button. */
Tcl_Interp *interp, /* Interpreter containing variable. */
- const char *name1, /* Not used. */
- const char *name2, /* Not used. */
+ const char *name1, /* Name of variable. */
+ const char *name2, /* Second part of variable name. */
int flags) /* Information about what happened. */
{
TkButton *butPtr = clientData;
Tcl_Obj *valuePtr;
if (butPtr->flags & BUTTON_DELETED) {
+ return NULL;
+ }
+
+ /*
+ * See ticket [5d991b82].
+ */
+
+ if (butPtr->textVarNamePtr == NULL) {
+ if (!(flags & TCL_INTERP_DESTROYED)) {
+ Tcl_UntraceVar2(interp, name1, name2,
+ TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ ButtonTextVarProc, clientData);
+ }
return NULL;
}
/*
* If the variable is unset, then immediately recreate it unless the whole
Index: generic/tkEntry.c
==================================================================
--- generic/tkEntry.c
+++ generic/tkEntry.c
@@ -3133,21 +3133,34 @@
/* ARGSUSED */
static char *
EntryTextVarProc(
ClientData clientData, /* Information about button. */
Tcl_Interp *interp, /* Interpreter containing variable. */
- const char *name1, /* Not used. */
- const char *name2, /* Not used. */
+ const char *name1, /* Name of variable. */
+ const char *name2, /* Second part of variable name. */
int flags) /* Information about what happened. */
{
Entry *entryPtr = clientData;
const char *value;
if (entryPtr->flags & ENTRY_DELETED) {
/*
* Just abort early if we entered here while being deleted.
*/
+ return NULL;
+ }
+
+ /*
+ * See ticket [5d991b82].
+ */
+
+ if (entryPtr->textVarName == NULL) {
+ if (!(flags & TCL_INTERP_DESTROYED)) {
+ Tcl_UntraceVar2(interp, name1, name2,
+ TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ EntryTextVarProc, clientData);
+ }
return NULL;
}
/*
* If the variable is unset, then immediately recreate it unless the whole
Index: generic/tkListbox.c
==================================================================
--- generic/tkListbox.c
+++ generic/tkListbox.c
@@ -3429,18 +3429,31 @@
static char *
ListboxListVarProc(
ClientData clientData, /* Information about button. */
Tcl_Interp *interp, /* Interpreter containing variable. */
- const char *name1, /* Not used. */
- const char *name2, /* Not used. */
+ const char *name1, /* Name of variable. */
+ const char *name2, /* Second part of variable name. */
int flags) /* Information about what happened. */
{
Listbox *listPtr = clientData;
Tcl_Obj *oldListObj, *varListObj;
int oldLength, i;
Tcl_HashEntry *entry;
+
+ /*
+ * See ticket [5d991b82].
+ */
+
+ if (listPtr->listVarName == NULL) {
+ if (!(flags & TCL_INTERP_DESTROYED)) {
+ Tcl_UntraceVar2(interp, name1, name2,
+ TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ ListboxListVarProc, clientData);
+ }
+ return NULL;
+ }
/*
* Bwah hahahaha! Puny mortal, you can't unset a -listvar'd variable!
*/
Index: generic/tkMenu.c
==================================================================
--- generic/tkMenu.c
+++ generic/tkMenu.c
@@ -2495,11 +2495,22 @@
}
menuPtr = mePtr->menuPtr;
if (menuPtr->menuFlags & MENU_DELETION_PENDING) {
- return NULL;
+ return NULL;
+ }
+
+ /*
+ * See ticket [5d991b82].
+ */
+
+ if (mePtr->namePtr == NULL) {
+ Tcl_UntraceVar2(interp, name1, name2,
+ TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ MenuVarProc, clientData);
+ return NULL;
}
name = Tcl_GetString(mePtr->namePtr);
/*
Index: generic/tkMenubutton.c
==================================================================
--- generic/tkMenubutton.c
+++ generic/tkMenubutton.c
@@ -878,10 +878,23 @@
int flags) /* Information about what happened. */
{
register TkMenuButton *mbPtr = clientData;
const char *value;
unsigned len;
+
+ /*
+ * See ticket [5d991b82].
+ */
+
+ if (mbPtr->textVarName == NULL) {
+ if (!(flags & TCL_INTERP_DESTROYED)) {
+ Tcl_UntraceVar2(interp, name1, name2,
+ TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ MenuButtonTextVarProc, clientData);
+ }
+ return NULL;
+ }
/*
* If the variable is unset, then immediately recreate it unless the whole
* interpreter is going away.
*/
Index: generic/tkMessage.c
==================================================================
--- generic/tkMessage.c
+++ generic/tkMessage.c
@@ -835,10 +835,23 @@
const char *name2, /* Second part of variable name. */
int flags) /* Information about what happened. */
{
register Message *msgPtr = clientData;
const char *value;
+
+ /*
+ * See ticket [5d991b82].
+ */
+
+ if (msgPtr->textVarName == NULL) {
+ if (!(flags & TCL_INTERP_DESTROYED)) {
+ Tcl_UntraceVar2(interp, name1, name2,
+ TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ MessageTextVarProc, clientData);
+ }
+ return NULL;
+ }
/*
* If the variable is unset, then immediately recreate it unless the whole
* interpreter is going away.
*/
Index: generic/tkScale.c
==================================================================
--- generic/tkScale.c
+++ generic/tkScale.c
@@ -1189,10 +1189,23 @@
register TkScale *scalePtr = clientData;
const char *resultStr;
double value;
Tcl_Obj *valuePtr;
int result;
+
+ /*
+ * See ticket [5d991b82].
+ */
+
+ if (scalePtr->varNamePtr == NULL) {
+ if (!(flags & TCL_INTERP_DESTROYED)) {
+ Tcl_UntraceVar2(interp, name1, name2,
+ TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ ScaleVarProc, clientData);
+ }
+ return NULL;
+ }
/*
* If the variable is unset, then immediately recreate it unless the whole
* interpreter is going away.
*/
Index: generic/ttk/ttkTrace.c
==================================================================
--- generic/ttk/ttkTrace.c
+++ generic/ttk/ttkTrace.c
@@ -24,21 +24,32 @@
*/
static char *
VarTraceProc(
ClientData clientData, /* Widget record pointer */
Tcl_Interp *interp, /* Interpreter containing variable. */
- const char *name1, /* (unused) */
- const char *name2, /* (unused) */
+ const char *name1, /* Name of variable. */
+ const char *name2, /* Second part of variable name. */
int flags) /* Information about what happened. */
{
Ttk_TraceHandle *tracePtr = clientData;
const char *name, *value;
Tcl_Obj *valuePtr;
if (flags & TCL_INTERP_DESTROYED) {
return NULL;
}
+
+ /*
+ * See ticket [5d991b82].
+ */
+
+ if (tracePtr->varnameObj == NULL) {
+ Tcl_UntraceVar2(interp, name1, name2,
+ TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ VarTraceProc, clientData);
+ return NULL;
+ }
name = Tcl_GetString(tracePtr->varnameObj);
/*
* If the variable is being unset, then re-establish the trace: