summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhobbs <hobbs>2001-04-03 04:41:08 (GMT)
committerhobbs <hobbs>2001-04-03 04:41:08 (GMT)
commit0bd9d904e73bc0d302afe8b82bb2b9186c7801a9 (patch)
tree0ee52a4755cfc619e731dbddf8f550b6ff5a1e0d
parent5c2ad0a34a4a78a7879cd6dc7e4523f789aa3d0e (diff)
downloadtk-0bd9d904e73bc0d302afe8b82bb2b9186c7801a9.zip
tk-0bd9d904e73bc0d302afe8b82bb2b9186c7801a9.tar.gz
tk-0bd9d904e73bc0d302afe8b82bb2b9186c7801a9.tar.bz2
* tests/listbox.test: added test listbox-27.1, delete during
scrollbar update * generic/tkListbox.c (DestroyListbox, ListboxEventProc): corrected listbox to make proper use of Tcl_EventuallyFree and protect against unusual listbox deletion.
-rw-r--r--generic/tkListbox.c31
-rw-r--r--tests/listbox.test18
2 files changed, 30 insertions, 19 deletions
diff --git a/generic/tkListbox.c b/generic/tkListbox.c
index 25e8563..6c45dfd 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.19 2000/11/22 01:49:38 ericm Exp $
+ * RCS: @(#) $Id: tkListbox.c,v 1.20 2001/04/03 04:41:08 hobbs Exp $
*/
#include "tkPort.h"
@@ -1456,16 +1456,6 @@ DestroyListbox(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);
@@ -1834,6 +1824,9 @@ DisplayListbox(clientData)
Pixmap pixmap;
listPtr->flags &= ~REDRAW_PENDING;
+ if (listPtr->flags & LISTBOX_DELETED) {
+ return;
+ }
if (listPtr->flags & MAXWIDTH_IS_STALE) {
ListboxComputeGeometry(listPtr, 0, 1, 0);
@@ -1848,7 +1841,7 @@ DisplayListbox(clientData)
ListboxUpdateHScrollbar(listPtr);
}
listPtr->flags &= ~(REDRAW_PENDING|UPDATE_V_SCROLLBAR|UPDATE_H_SCROLLBAR);
- if ((listPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
+ if ((listPtr->flags & LISTBOX_DELETED) || (!Tk_IsMapped(tkwin))) {
return;
}
@@ -2453,7 +2446,17 @@ ListboxEventProc(clientData, eventPtr)
NearestListboxElement(listPtr, eventPtr->xexpose.y
+ eventPtr->xexpose.height));
} else if (eventPtr->type == DestroyNotify) {
- DestroyListbox((char *) clientData);
+ if (!(listPtr->flags & LISTBOX_DELETED)) {
+ 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);
+ }
+ Tcl_EventuallyFree(clientData, DestroyListbox);
+ }
} else if (eventPtr->type == ConfigureNotify) {
int vertSpace;
@@ -3067,7 +3070,7 @@ EventuallyRedrawRange(listPtr, first, last)
/* We don't have to register a redraw callback if one is already pending,
* or if the window doesn't exist, or if the window isn't mapped */
if ((listPtr->flags & REDRAW_PENDING)
- || (listPtr->tkwin == NULL)
+ || (listPtr->flags & LISTBOX_DELETED)
|| !Tk_IsMapped(listPtr->tkwin)) {
return;
}
diff --git a/tests/listbox.test b/tests/listbox.test
index 45443f6..8d3d75e 100644
--- a/tests/listbox.test
+++ b/tests/listbox.test
@@ -6,7 +6,7 @@
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.
#
-# RCS: @(#) $Id: listbox.test,v 1.13 2000/07/28 16:34:55 ericm Exp $
+# RCS: @(#) $Id: listbox.test,v 1.14 2001/04/03 04:41:08 hobbs Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
source [file join [pwd] [file dirname [info script]] defs.tcl]
@@ -2101,12 +2101,20 @@ test listbox-26.5 {listbox disabled state disallows active modification} {
} 0
resetGridInfo
-catch {destroy .l2}
-catch {destroy .t}
-catch {destroy .e}
-catch {destroy .partial}
+eval destroy [winfo children .]
option clear
+test listbox-27.1 {widget deletion while active} {
+ destroy .l
+ pack [listbox .l]
+ update
+ .l configure -cursor xterm -xscrollcommand { destroy .l }
+ update idle
+ winfo exists .l
+} 0
+
+eval destroy [winfo children .]
+
# cleanup
::tcltest::cleanupTests
return