# HG changeset patch # User Darkvater # Date 2006-12-30 01:08:12 # Node ID fdcdacfe53ee435b2edd121f7d73ad952dd4b3bf # Parent f3458f5e2b6087125d8bc67c6f1db62b97db0472 (svn r7635) -Fix (r7618, r7621): Guard against recursive deletion. It is possible that when a parent window is deleted it deletes its child (always) and in turn, through some code the child initiates the deletion of the parent which, if not guarded against, deletes the child and so on... diff --git a/misc_gui.c b/misc_gui.c --- a/misc_gui.c +++ b/misc_gui.c @@ -1226,7 +1226,10 @@ static void QueryWndProc(Window *w, Wind break; case WE_DESTROY: /* Call callback function (if any) on window close if not yet called */ - if (!q->calledback && q->proc != NULL) q->proc(w->parent, false); + if (!q->calledback && q->proc != NULL) { + q->calledback = true; + q->proc(w->parent, false); + } break; } } diff --git a/window.c b/window.c --- a/window.c +++ b/window.c @@ -308,10 +308,13 @@ Window **FindWindowZPosition(const Windo { Window **wz; - for (wz = _z_windows;; wz++) { - assert(wz < _last_z_window); + for (wz = _z_windows; wz != _last_z_window; wz++) { if (*wz == w) return wz; } + + DEBUG(misc, 3, "Window (class %d, number %d) is not open, probably removed by recursive calls", + w->window_class, w->window_number); + return NULL; } void DeleteWindow(Window *w) @@ -342,6 +345,7 @@ void DeleteWindow(Window *w) /* Find the window in the z-array, and effectively remove it * by moving all windows after it one to the left */ wz = FindWindowZPosition(w); + if (wz == NULL) return; memmove(wz, wz + 1, (byte*)_last_z_window - (byte*)wz); _last_z_window--; }