diff options
author | hobbs <hobbs@noemail.net> | 2000-03-02 21:52:39 (GMT) |
---|---|---|
committer | hobbs <hobbs@noemail.net> | 2000-03-02 21:52:39 (GMT) |
commit | 90d2d540b248e931dcb9f2fc3a18b0528e8568d2 (patch) | |
tree | 5a53a857601925e08c884ef63ce5190f753f93cc /generic/tkListbox.c | |
parent | 7f468e0a113ed8d68bbd7f134d292a8b4f408a6c (diff) | |
download | tk-90d2d540b248e931dcb9f2fc3a18b0528e8568d2.zip tk-90d2d540b248e931dcb9f2fc3a18b0528e8568d2.tar.gz tk-90d2d540b248e931dcb9f2fc3a18b0528e8568d2.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.
FossilOrigin-Name: a54ba26b730bb5bda6191ecada040674892e29e7
Diffstat (limited to 'generic/tkListbox.c')
-rw-r--r-- | generic/tkListbox.c | 40 |
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); } } |