summaryrefslogtreecommitdiffstats
path: root/generic/tkListbox.c
diff options
context:
space:
mode:
authorhobbs <hobbs>2000-03-02 21:52:40 (GMT)
committerhobbs <hobbs>2000-03-02 21:52:40 (GMT)
commit2c8a777381c7c653bf9304fd50a526a8a81ce293 (patch)
tree5a53a857601925e08c884ef63ce5190f753f93cc /generic/tkListbox.c
parent9521a71f90589b90b5506505a8c81b7cb198b96d (diff)
downloadtk-2c8a777381c7c653bf9304fd50a526a8a81ce293.zip
tk-2c8a777381c7c653bf9304fd50a526a8a81ce293.tar.gz
tk-2c8a777381c7c653bf9304fd50a526a8a81ce293.tar.bz2
* generic/tkListbox.c (DestroyListbox): fixed crash in
DestroyListbox due to null tkwin. [Bug: 4207] * tests/entry.test: added test suite for entry validation * doc/entry.n: improved docs discussing caveats and gotchas when mixing textvar with widget validation * generic/tkEntry.c (EntryValidateChange): improved handling of validation with relation to -textvariable. Previously, it would turn off whenever the textvar was set. Now it will it will turn off only when the textvar is set and validation returns 0. Added %V (type of validation occuring) to %-subs to help work with trickier validation.
Diffstat (limited to 'generic/tkListbox.c')
-rw-r--r--generic/tkListbox.c40
1 files changed, 19 insertions, 21 deletions
diff --git a/generic/tkListbox.c b/generic/tkListbox.c
index 2c587ed..4e9081a 100644
--- a/generic/tkListbox.c
+++ b/generic/tkListbox.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: tkListbox.c,v 1.15 2000/01/21 03:54:42 hobbs Exp $
+ * RCS: @(#) $Id: tkListbox.c,v 1.16 2000/03/02 21:52:41 hobbs Exp $
*/
#include "tkPort.h"
@@ -183,13 +183,15 @@ typedef struct {
* GOT_FOCUS: Non-zero means this widget currently
* has the input focus.
* MAXWIDTH_IS_STALE: Stored maxWidth may be out-of-date
+ * LISTBOX_DELETED: This listbox has been effectively destroyed.
*/
#define REDRAW_PENDING 1
#define UPDATE_V_SCROLLBAR 2
#define UPDATE_H_SCROLLBAR 4
#define GOT_FOCUS 8
-#define MAXWIDTH_IS_STALE 16
+#define MAXWIDTH_IS_STALE 16
+#define LISTBOX_DELETED 32
/*
* The optionSpecs table defines the valid configuration options for the
@@ -1409,7 +1411,17 @@ DestroyListbox(memPtr)
register Listbox *listPtr = (Listbox *) memPtr;
Tcl_HashEntry *entry;
Tcl_HashSearch search;
-
+
+ listPtr->flags |= LISTBOX_DELETED;
+
+ Tcl_DeleteCommandFromToken(listPtr->interp, listPtr->widgetCmd);
+ if (listPtr->setGrid) {
+ Tk_UnsetGrid(listPtr->tkwin);
+ }
+ if (listPtr->flags & REDRAW_PENDING) {
+ Tcl_CancelIdleCall(DisplayListbox, (ClientData) listPtr);
+ }
+
/* If we have an internal list object, free it */
if (listPtr->listObj != NULL) {
Tcl_DecrRefCount(listPtr->listObj);
@@ -1448,6 +1460,7 @@ DestroyListbox(memPtr)
}
Tk_FreeConfigOptions((char *)listPtr, listPtr->optionTable,
listPtr->tkwin);
+ listPtr->tkwin = NULL;
ckfree((char *) listPtr);
}
@@ -2352,17 +2365,7 @@ ListboxEventProc(clientData, eventPtr)
NearestListboxElement(listPtr, eventPtr->xexpose.y
+ eventPtr->xexpose.height));
} else if (eventPtr->type == DestroyNotify) {
- if (listPtr->tkwin != NULL) {
- if (listPtr->setGrid) {
- Tk_UnsetGrid(listPtr->tkwin);
- }
- listPtr->tkwin = NULL;
- Tcl_DeleteCommandFromToken(listPtr->interp, listPtr->widgetCmd);
- }
- if (listPtr->flags & REDRAW_PENDING) {
- Tcl_CancelIdleCall(DisplayListbox, (ClientData) listPtr);
- }
- Tcl_EventuallyFree((ClientData) listPtr, DestroyListbox);
+ DestroyListbox((char *) clientData);
} else if (eventPtr->type == ConfigureNotify) {
int vertSpace;
@@ -2421,7 +2424,6 @@ ListboxCmdDeletedProc(clientData)
ClientData clientData; /* Pointer to widget record for widget. */
{
Listbox *listPtr = (Listbox *) clientData;
- Tk_Window tkwin = listPtr->tkwin;
/*
* This procedure could be invoked either because the window was
@@ -2430,12 +2432,8 @@ ListboxCmdDeletedProc(clientData)
* destroys the widget.
*/
- if (tkwin != NULL) {
- if (listPtr->setGrid) {
- Tk_UnsetGrid(listPtr->tkwin);
- }
- listPtr->tkwin = NULL;
- Tk_DestroyWindow(tkwin);
+ if (!(listPtr->flags & LISTBOX_DELETED)) {
+ Tk_DestroyWindow(listPtr->tkwin);
}
}