From e6119ff8e2695b362e38523181634e8ad31537d3 Mon Sep 17 00:00:00 2001 From: jenglish Date: Thu, 8 Aug 2002 22:32:11 +0000 Subject: Fix for Tk Bug #592201 "wm transient fails with two masters". --- ChangeLog | 7 +++++++ tests/wm.test | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- unix/tkUnixWm.c | 22 ++++------------------ win/tkWinWm.c | 8 ++++---- 4 files changed, 72 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9083281..04335c6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2002-08-08 Joe English + * unix/tkUnixWm.c: + * win/tkWinWm.c: + * tests/wm.test: Fix for Tk Bug #592201 "wm transient fails with two + masters"; fixes panic after a transient window is reassigned to + new master and either master is subsequently destroyed. + 2002-08-08 Don Porter * tests/unixWm.test: Corrected packaging of unixWm-50.3 so that diff --git a/tests/wm.test b/tests/wm.test index 6d218c1..bb2cdc3 100644 --- a/tests/wm.test +++ b/tests/wm.test @@ -7,7 +7,7 @@ # Copyright (c) 1998-1999 by Scriptics Corporation. # All rights reserved. # -# RCS: @(#) $Id: wm.test,v 1.16 2002/07/25 21:35:23 pspjuth Exp $ +# RCS: @(#) $Id: wm.test,v 1.17 2002/08/08 22:32:11 jenglish Exp $ # This file tests window manager interactions that work across # platforms. Window manager tests that only work on a specific @@ -1370,6 +1370,62 @@ test wm-transient-6.2 { a withdrawn transient does not track } {withdrawn normal withdrawn normal} +# wm-transient-7.*: See SF Tk Bug #592201 "wm transient fails with two masters" +# wm-transient-7.3 through 7.5 all caused panics on Unix in Tk 8.4b1. +# 7.1 and 7.2 added to catch (potential) future errors. +# +test wm-transient-7.1 {Destroying transient} { + toplevel .t + toplevel .transient + wm transient .transient .t + destroy .transient + destroy .t + # OK: the above did not cause a panic. +} {} + +test wm-transient-7.2 {Destroying master} { + toplevel .t + toplevel .transient + wm transient .transient .t + destroy .t + set result [wm transient .transient] + destroy .transient + set result +} {} + +test wm-transient-7.3 {Reassign transient, destroy old master} { + toplevel .t1 + toplevel .t2 + toplevel .transient + wm transient .transient .t1 + wm transient .transient .t2 + destroy .t1 ;# Caused panic in 8.4b1 + destroy .t2 + destroy .transient +} {} + +test wm-transient-7.4 {Reassign transient, destroy new master} { + toplevel .t1 + toplevel .t2 + toplevel .transient + wm transient .transient .t1 + wm transient .transient .t2 + destroy .t2 ;# caused panic in 8.4b1 + destroy .t1 + destroy .transient +} {} + +test wm-transient-7.5 {Reassign transient, destroy transient} { + toplevel .t1 + toplevel .t2 + toplevel .transient + wm transient .transient .t1 + wm transient .transient .t2 + destroy .transient + destroy .t2 ;# caused panic in 8.4b1 + destroy .t1 ;# so did this +} {} + test wm-state-1.1 {usage} { list [catch {wm state} err] $err } {1 {wrong # args: should be "wm option window ?arg ...?"}} diff --git a/unix/tkUnixWm.c b/unix/tkUnixWm.c index e73d092..227103b 100644 --- a/unix/tkUnixWm.c +++ b/unix/tkUnixWm.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkUnixWm.c,v 1.30 2002/08/05 04:30:41 dgp Exp $ + * RCS: @(#) $Id: tkUnixWm.c,v 1.31 2002/08/08 22:32:11 jenglish Exp $ */ #include "tkPort.h" @@ -197,7 +197,6 @@ typedef struct TkWmInfo { char *clientMachine; /* String to store in WM_CLIENT_MACHINE * property, or NULL. */ int flags; /* Miscellaneous flags, defined below. */ - int numTransients; /* number of transients on this window */ struct TkWmInfo *nextPtr; /* Next in list of all top-level windows. */ } WmInfo; @@ -528,7 +527,6 @@ TkWmNewWindow(winPtr) wmPtr->winPtr = winPtr; wmPtr->reparent = None; wmPtr->masterPtr = NULL; - wmPtr->numTransients = 0; wmPtr->hints.flags = InputHint | StateHint; wmPtr->hints.input = True; wmPtr->hints.initial_state = NormalState; @@ -857,7 +855,6 @@ TkWmDeadWindow(winPtr) for (wmPtr2 = winPtr->dispPtr->firstWmPtr; wmPtr2 != NULL; wmPtr2 = wmPtr2->nextPtr) { if (wmPtr2->masterPtr == winPtr) { - wmPtr->numTransients--; Tk_DeleteEventHandler((Tk_Window) wmPtr2->masterPtr, StructureNotifyMask, WmWaitMapProc, (ClientData) wmPtr2->winPtr); @@ -871,18 +868,12 @@ TkWmDeadWindow(winPtr) } } } - if (wmPtr->numTransients != 0) - panic("numTransients should be 0"); if (wmPtr->masterPtr != NULL) { wmPtr2 = wmPtr->masterPtr->wmInfoPtr; /* - * If we had a master, tell them that we aren't tied - * to them anymore + * If we had a master, remove old map/unmap binding */ - if (wmPtr2 != NULL) { - wmPtr2->numTransients--; - } Tk_DeleteEventHandler((Tk_Window) wmPtr->masterPtr, StructureNotifyMask, WmWaitMapProc, (ClientData) winPtr); @@ -2999,11 +2990,8 @@ WmTransientCmd(tkwin, winPtr, interp, objc, objv) if (Tcl_GetString(objv[3])[0] == '\0') { if (masterPtr != NULL) { /* - * If we had a master, tell them that we aren't tied - * to them anymore + * If we had a master, remove old map/unmap binding */ - - masterPtr->wmInfoPtr->numTransients--; Tk_DeleteEventHandler((Tk_Window) masterPtr, StructureNotifyMask, WmWaitMapProc, (ClientData) winPtr); @@ -3063,9 +3051,7 @@ WmTransientCmd(tkwin, winPtr, interp, objc, objv) * transient states reflect the state of the master. */ - if (wmPtr->masterPtr == NULL) { - masterPtr->wmInfoPtr->numTransients++; - } else { + if (wmPtr->masterPtr != NULL) { Tk_DeleteEventHandler((Tk_Window) wmPtr->masterPtr, StructureNotifyMask, WmWaitMapProc, (ClientData) winPtr); diff --git a/win/tkWinWm.c b/win/tkWinWm.c index 22996e9..5248a54 100644 --- a/win/tkWinWm.c +++ b/win/tkWinWm.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWinWm.c,v 1.51 2002/08/05 14:01:15 dgp Exp $ + * RCS: @(#) $Id: tkWinWm.c,v 1.52 2002/08/08 22:32:12 jenglish Exp $ */ #include "tkWinInt.h" @@ -4625,14 +4625,14 @@ WmTransientCmd(tkwin, winPtr, interp, objc, objv) * transient states reflect the state of the master. */ - if (wmPtr->masterPtr == NULL) { - masterPtr->wmInfoPtr->numTransients++; - } else { + if (wmPtr->masterPtr != NULL) { + wmPtr->masterPtr->wmInfoPtr->numTransients--; Tk_DeleteEventHandler((Tk_Window) wmPtr->masterPtr, VisibilityChangeMask|StructureNotifyMask, WmWaitVisibilityOrMapProc, (ClientData) winPtr); } + masterPtr->wmInfoPtr->numTransients++; Tk_CreateEventHandler((Tk_Window) masterPtr, VisibilityChangeMask|StructureNotifyMask, WmWaitVisibilityOrMapProc, (ClientData) winPtr); -- cgit v0.12