summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvincentdarley <vincentdarley>2003-05-27 15:35:52 (GMT)
committervincentdarley <vincentdarley>2003-05-27 15:35:52 (GMT)
commit72a139a4ee101796fcc487b5b3bba46295f13b8c (patch)
tree2b0f643f9180be5a8850e6ce4a100f39000a42cf
parente8d261532f654e15e81a8d3e0f4ad562d7382e8c (diff)
downloadtk-72a139a4ee101796fcc487b5b3bba46295f13b8c.zip
tk-72a139a4ee101796fcc487b5b3bba46295f13b8c.tar.gz
tk-72a139a4ee101796fcc487b5b3bba46295f13b8c.tar.bz2
text widget cleanup fix
-rw-r--r--ChangeLog8
-rw-r--r--generic/tkText.c61
-rw-r--r--generic/tkText.h9
-rw-r--r--generic/tkTextDisp.c16
-rw-r--r--generic/tkTextTag.c10
5 files changed, 63 insertions, 41 deletions
diff --git a/ChangeLog b/ChangeLog
index 3f48bc9..f04f21e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2003-05-27 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tkText.c
+ * generic/tkTextTag.c
+ * generic/tkTextDisp.c
+ * generic/tkText.h: refactoring of text widget cleanup code
+ to ensure all resources are freed. [Bug#741179]
+
2003-05-23 Mo DeJong <mdejong@users.sourceforge.net>
* unix/mkLinks: Set the var S to "" at the top
diff --git a/generic/tkText.c b/generic/tkText.c
index 0f43d34..4ec38d7 100644
--- a/generic/tkText.c
+++ b/generic/tkText.c
@@ -14,7 +14,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkText.c,v 1.37 2003/05/21 09:21:57 dkf Exp $
+ * RCS: @(#) $Id: tkText.c,v 1.38 2003/05/27 15:35:52 vincentdarley Exp $
*/
#include "default.h"
@@ -1336,32 +1336,36 @@ TextEventProc(clientData, eventPtr)
textPtr->prevHeight = Tk_Height(textPtr->tkwin);
}
} else if (eventPtr->type == DestroyNotify) {
- if (textPtr->tkwin != NULL) {
- /*
- * NOTE: we must zero out selBorder, selBorderWidthPtr and
- * selFgColorPtr: they are duplicates of information in the
- * "sel" tag, which will be freed up when we delete all tags.
- * Hence we don't want the automatic config options freeing
- * process to delete them as well.
- */
+ /*
+ * NOTE: we must zero out selBorder, selBorderWidthPtr and
+ * selFgColorPtr: they are duplicates of information in the
+ * "sel" tag, which will be freed up when we delete all tags.
+ * Hence we don't want the automatic config options freeing
+ * process to delete them as well.
+ */
- textPtr->selBorder = NULL;
- textPtr->selBorderWidthPtr = NULL;
- textPtr->selBorderWidth = 0;
- textPtr->selFgColorPtr = NULL;
- if (textPtr->setGrid) {
- Tk_UnsetGrid(textPtr->tkwin);
- }
+ textPtr->selBorder = NULL;
+ textPtr->selBorderWidthPtr = NULL;
+ textPtr->selBorderWidth = 0;
+ textPtr->selFgColorPtr = NULL;
+ if (textPtr->setGrid) {
+ Tk_UnsetGrid(textPtr->tkwin);
+ textPtr->setGrid = 0;
+ }
+ if (!(textPtr->flags & OPTIONS_FREED)) {
Tk_FreeConfigOptions((char *) textPtr, textPtr->optionTable,
textPtr->tkwin);
- /*
- * We don't delete the associated Tcl command yet, because
- * that will cause textPtr->tkWin to be nulled out, and that
- * is needed inside DestroyText to clean up certain tags
- * which might have been created (e.g. in the text widget
- * styles demo).
- */
+ textPtr->flags |= OPTIONS_FREED;
}
+ textPtr->flags |= DESTROYED;
+
+ /*
+ * We don't delete the associated Tcl command yet, because
+ * that will cause textPtr->tkWin to be nulled out, and that
+ * is needed inside DestroyText to clean up certain tags
+ * which might have been created (e.g. in the text widget
+ * styles demo).
+ */
Tcl_EventuallyFree((ClientData) textPtr, DestroyText);
} else if ((eventPtr->type == FocusIn) || (eventPtr->type == FocusOut)) {
if (eventPtr->xfocus.detail != NotifyInferior) {
@@ -1418,16 +1422,17 @@ TextCmdDeletedProc(clientData)
/*
* This procedure could be invoked either because the window was
- * destroyed and the command was then deleted (in which case tkwin
- * is NULL) or because the command was deleted, and then this procedure
- * destroys the widget.
+ * destroyed and the command was then deleted (in which this flag is
+ * already set) or because the command was deleted, and then this
+ * procedure destroys the widget.
*/
- if (tkwin != NULL) {
+ if (!(textPtr->flags & DESTROYED)) {
if (textPtr->setGrid) {
Tk_UnsetGrid(textPtr->tkwin);
+ textPtr->setGrid = 0;
}
- textPtr->tkwin = NULL;
+ textPtr->flags |= DESTROYED;
Tk_DestroyWindow(tkwin);
}
}
diff --git a/generic/tkText.h b/generic/tkText.h
index 7521fc5..d17735c 100644
--- a/generic/tkText.h
+++ b/generic/tkText.h
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkText.h,v 1.14 2003/05/19 13:04:23 vincentdarley Exp $
+ * RCS: @(#) $Id: tkText.h,v 1.15 2003/05/27 15:35:53 vincentdarley Exp $
*/
#ifndef _TKTEXT
@@ -513,7 +513,6 @@ typedef struct TkText {
* it here. */
int state; /* Either STATE_NORMAL or STATE_DISABLED. A
* text widget is read-only when disabled. */
-
/*
* Default information for displaying (may be overridden by tags
* applied to ranges of characters).
@@ -707,6 +706,10 @@ typedef struct TkText {
* for the duration of button presses.
* UPDATE_SCROLLBARS: Non-zero means scrollbar(s) should be updated
* during next redisplay operation.
+ * NEED_REPICK This appears unused and should probably
+ * be ignored
+ * OPTIONS_FREED The widget's options have been freed
+ * DESTROYED The widget is going away
*/
#define GOT_SELECTION 1
@@ -715,6 +718,8 @@ typedef struct TkText {
#define BUTTON_DOWN 8
#define UPDATE_SCROLLBARS 0x10
#define NEED_REPICK 0x20
+#define OPTIONS_FREED 0x40
+#define DESTROYED 0x80
/*
* Records of the following type define segment types in terms of
diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c
index 6c9f7fc..f94281d 100644
--- a/generic/tkTextDisp.c
+++ b/generic/tkTextDisp.c
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkTextDisp.c,v 1.15 2003/05/19 13:04:23 vincentdarley Exp $
+ * RCS: @(#) $Id: tkTextDisp.c,v 1.16 2003/05/27 15:35:53 vincentdarley Exp $
*/
#include "tkPort.h"
@@ -2188,7 +2188,7 @@ DisplayText(clientData)
* compiler warnings. */
Tcl_Interp *interp;
- if (textPtr->tkwin == NULL) {
+ if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
/*
* The widget has been deleted. Don't do anything.
@@ -2205,7 +2205,7 @@ DisplayText(clientData)
TCL_GLOBAL_ONLY);
}
- if (textPtr->tkwin == NULL) {
+ if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
/*
* The widget has been deleted. Don't do anything.
@@ -2226,7 +2226,7 @@ DisplayText(clientData)
TCL_GLOBAL_ONLY);
}
- if (textPtr->tkwin == NULL) {
+ if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
/*
* The widget has been deleted. Don't do anything.
@@ -2244,12 +2244,14 @@ DisplayText(clientData)
*/
while (dInfoPtr->flags & REPICK_NEEDED) {
+ int flags = textPtr->flags;
+
Tcl_Preserve((ClientData) textPtr);
dInfoPtr->flags &= ~REPICK_NEEDED;
TkTextPickCurrent(textPtr, &textPtr->pickEvent);
tkwin = textPtr->tkwin;
Tcl_Release((ClientData) textPtr);
- if (tkwin == NULL) {
+ if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
goto end;
}
}
@@ -2494,7 +2496,7 @@ DisplayText(clientData)
TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
}
- if (textPtr->tkwin == NULL) {
+ if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
/*
* The widget has been deleted. Don't do anything.
@@ -2524,7 +2526,7 @@ DisplayText(clientData)
GetYView(textPtr->interp, textPtr, 1);
}
- if (textPtr->tkwin == NULL) {
+ if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
/*
* The widget has been deleted. Don't do anything.
diff --git a/generic/tkTextTag.c b/generic/tkTextTag.c
index fa8a2b9..e3bf289 100644
--- a/generic/tkTextTag.c
+++ b/generic/tkTextTag.c
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkTextTag.c,v 1.9 2003/05/19 13:04:24 vincentdarley Exp $
+ * RCS: @(#) $Id: tkTextTag.c,v 1.10 2003/05/27 15:35:53 vincentdarley Exp $
*/
#include "default.h"
@@ -1187,7 +1187,7 @@ TkTextBindProc(clientData, eventPtr)
TkTextPickCurrent(textPtr, eventPtr);
}
if ((textPtr->numCurTags > 0) && (textPtr->bindingTable != NULL)
- && (textPtr->tkwin != NULL)) {
+ && (textPtr->tkwin != NULL) && !(textPtr->flags & DESTROYED)) {
Tk_BindEvent(textPtr->bindingTable, eventPtr, textPtr->tkwin,
textPtr->numCurTags, (ClientData *) textPtr->curTagArrayPtr);
}
@@ -1359,7 +1359,8 @@ TkTextPickCurrent(textPtr, eventPtr)
oldArrayPtr = textPtr->curTagArrayPtr;
textPtr->curTagArrayPtr = newArrayPtr;
if (numOldTags != 0) {
- if ((textPtr->bindingTable != NULL) && (textPtr->tkwin != NULL)) {
+ if ((textPtr->bindingTable != NULL) && (textPtr->tkwin != NULL)
+ && !(textPtr->flags & DESTROYED)) {
event = textPtr->pickEvent;
event.type = LeaveNotify;
@@ -1387,7 +1388,8 @@ TkTextPickCurrent(textPtr, eventPtr)
textPtr->pickEvent.xcrossing.y, &index);
TkTextSetMark(textPtr, "current", &index);
if (numNewTags != 0) {
- if ((textPtr->bindingTable != NULL) && (textPtr->tkwin != NULL)) {
+ if ((textPtr->bindingTable != NULL) && (textPtr->tkwin != NULL)
+ && !(textPtr->flags & DESTROYED)) {
event = textPtr->pickEvent;
event.type = EnterNotify;
event.xcrossing.detail = NotifyAncestor;