diff options
-rw-r--r-- | ChangeLog | 14 | ||||
-rw-r--r-- | tests/wm.test | 35 | ||||
-rw-r--r-- | unix/tkUnixWm.c | 21 | ||||
-rw-r--r-- | win/tkWinWm.c | 31 |
4 files changed, 95 insertions, 6 deletions
@@ -1,4 +1,16 @@ -2002-06-22 Donal K. Fellows <fellowsd@cs.man.ac.uk> +2002-06-21 Mo DeJong <mdejong@users.sourceforge.net> + + * tests/wm.test: Add tests to make sure a withdrawn + transient does not get remapped by state changes + in the master. + * unix/tkUnixWm.c (Tk_WmCmd, WmWaitMapProc): + * win/tkWinWm.c (Tk_WmCmd, WmWaitVisibilityOrMapProc): + Add a WM_TRANSIENT_WITHDRAWN flag that gets set by the + withdraw, deiconify, or state wm subcommands. Check + this flag before mapping a transient when processing + a MapNotify event. [Tk bug 570764] + +2002-06-21 Donal K. Fellows <fellowsd@cs.man.ac.uk> * unix/tk.spec (version), README, win/configure.in, unix/configure.in: * generic/tk.h (TK_RELEASE_*, TK_PATCH_LEVEL): Bumped to beta1. diff --git a/tests/wm.test b/tests/wm.test index c43b1a9..c7dceed 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.10 2002/06/13 21:35:09 mdejong Exp $ +# RCS: @(#) $Id: wm.test,v 1.11 2002/06/22 01:43:47 mdejong Exp $ # This file tests window manager interactions that work across # platforms. Window manager tests that only work on a specific @@ -509,6 +509,39 @@ test wm-transient-5.3 { remove transient property from window wm transient .subject } {} +test wm-transient-6.1 { a withdrawn transient does not track + state changes in the master } { + deleteWindows + toplevel .master + toplevel .subject + update + wm transient .subject .master + wm withdraw .subject + wm withdraw .master + wm deiconify .master + wm state .subject +} {withdrawn} + +test wm-transient-6.2 { a withdrawn transient does not track + state changes in the master } { + set results [list] + deleteWindows + toplevel .master + toplevel .subject + update + wm transient .subject .master + wm withdraw .subject + wm withdraw .master + wm deiconify .master + lappend results [wm state .subject] + wm deiconify .subject + lappend results [wm state .subject] + wm withdraw .master + lappend results [wm state .subject] + wm deiconify .master + lappend results [wm state .subject] +} {withdrawn normal withdrawn normal} + test wm-state-1.1 {usage} { list [catch {wm state} err] $err diff --git a/unix/tkUnixWm.c b/unix/tkUnixWm.c index 55f8c4d..5c1f615 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.23 2002/06/15 01:54:47 hobbs Exp $ + * RCS: @(#) $Id: tkUnixWm.c,v 1.24 2002/06/22 01:43:47 mdejong Exp $ */ #include "tkPort.h" @@ -244,6 +244,9 @@ typedef struct TkWmInfo { * allow the user to change the height of the * window (controlled by "wm resizable" * command). + * WM_TRANSIENT_WITHDRAWN - non-zero means that this is a transient window + * that has explicitly been withdrawn. It should + * not mirror state changes in the master. */ #define WM_NEVER_MAPPED 1 @@ -259,6 +262,7 @@ typedef struct TkWmInfo { #define WM_ADDED_TOPLEVEL_COLORMAP 0x800 #define WM_WIDTH_NOT_RESIZABLE 0x1000 #define WM_HEIGHT_NOT_RESIZABLE 0x2000 +#define WM_TRANSIENT_WITHDRAWN 0x4000 /* * This module keeps a list of all top-level windows, primarily to @@ -1139,6 +1143,9 @@ Tk_WmCmd(clientData, interp, argc, argv) (char *) NULL); return TCL_ERROR; } + if (wmPtr->flags & WM_TRANSIENT_WITHDRAWN) { + wmPtr->flags &= ~WM_TRANSIENT_WITHDRAWN; + } (void) TkpWmSetState(winPtr, NormalState); } else if ((c == 'f') && (strncmp(argv[1], "focusmodel", length) == 0) && (length >= 2)) { @@ -1941,6 +1948,9 @@ Tk_WmCmd(clientData, interp, argc, argv) length = strlen(argv[3]); if ((c == 'n') && (strncmp(argv[3], "normal", length) == 0)) { + if (wmPtr->flags & WM_TRANSIENT_WITHDRAWN) { + wmPtr->flags &= ~WM_TRANSIENT_WITHDRAWN; + } (void) TkpWmSetState(winPtr, NormalState); } else if ((c == 'i') && (strncmp(argv[3], "iconic", length) == 0)) { @@ -1965,6 +1975,9 @@ Tk_WmCmd(clientData, interp, argc, argv) } } else if ((c == 'w') && (strncmp(argv[3], "withdrawn", length) == 0)) { + if (wmPtr->masterPtr != NULL) { + wmPtr->flags |= WM_TRANSIENT_WITHDRAWN; + } if (TkpWmSetState(winPtr, WithdrawnState) == 0) { Tcl_SetResult(interp, "couldn't send withdraw message to window manager", @@ -2145,6 +2158,9 @@ Tk_WmCmd(clientData, interp, argc, argv) (char *) NULL); return TCL_ERROR; } + if (wmPtr->masterPtr != NULL) { + wmPtr->flags |= WM_TRANSIENT_WITHDRAWN; + } if (TkpWmSetState(winPtr, WithdrawnState) == 0) { Tcl_SetResult(interp, "couldn't send withdraw message to window manager", @@ -2187,7 +2203,8 @@ WmWaitMapProc(clientData, eventPtr) if (masterPtr == NULL) return; - if (eventPtr->type == MapNotify) { + if (eventPtr->type == MapNotify && + !(winPtr->wmInfoPtr->flags & WM_TRANSIENT_WITHDRAWN)) { (void) TkpWmSetState(winPtr, NormalState); } else if (eventPtr->type == UnmapNotify) { (void) TkpWmSetState(winPtr, WithdrawnState); diff --git a/win/tkWinWm.c b/win/tkWinWm.c index 0858d10..583059f 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.41 2002/06/15 01:54:48 hobbs Exp $ + * RCS: @(#) $Id: tkWinWm.c,v 1.42 2002/06/22 01:43:47 mdejong Exp $ */ #include "tkWinInt.h" @@ -283,6 +283,17 @@ typedef struct TkWmInfo { * was called the top-level itself wasn't * specified, so we added it implicitly at * the end of the list. + * WM_WIDTH_NOT_RESIZABLE - non-zero means that we're not supposed to + * allow the user to change the width of the + * window (controlled by "wm resizable" + * command). + * WM_HEIGHT_NOT_RESIZABLE - non-zero means that we're not supposed to + * allow the user to change the height of the + * window (controlled by "wm resizable" + * command). + * WM_TRANSIENT_WITHDRAWN - non-zero means that this is a transient window + * that has explicitly been withdrawn. It should + * not mirror state changes in the master. */ #define WM_NEVER_MAPPED (1<<0) @@ -297,6 +308,7 @@ typedef struct TkWmInfo { #define WM_ADDED_TOPLEVEL_COLORMAP (1<<9) #define WM_WIDTH_NOT_RESIZABLE (1<<10) #define WM_HEIGHT_NOT_RESIZABLE (1<<11) +#define WM_TRANSIENT_WITHDRAWN (1<<12) /* * Window styles for various types of toplevel windows. @@ -2419,6 +2431,11 @@ Tk_WmCmd(clientData, interp, argc, argv) ": it is an embedded window", (char *) NULL); return TCL_ERROR; } + + if (wmPtr->flags & WM_TRANSIENT_WITHDRAWN) { + wmPtr->flags &= ~WM_TRANSIENT_WITHDRAWN; + } + /* * If WM_UPDATE_PENDING is true, a pending UpdateGeometryInfo may * need to be called first to update a withdrew toplevel's geometry @@ -3271,6 +3288,9 @@ Tk_WmCmd(clientData, interp, argc, argv) length = strlen(argv[3]); if ((c == 'n') && (strncmp(argv[3], "normal", length) == 0)) { + if (wmPtr->flags & WM_TRANSIENT_WITHDRAWN) { + wmPtr->flags &= ~WM_TRANSIENT_WITHDRAWN; + } TkpWmSetState(winPtr, NormalState); /* * This varies from 'wm deiconify' because it does not @@ -3294,6 +3314,9 @@ Tk_WmCmd(clientData, interp, argc, argv) TkpWmSetState(winPtr, IconicState); } else if ((c == 'w') && (strncmp(argv[3], "withdrawn", length) == 0)) { + if (wmPtr->masterPtr != NULL) { + wmPtr->flags |= WM_TRANSIENT_WITHDRAWN; + } TkpWmSetState(winPtr, WithdrawnState); } else if ((c == 'z') && (strncmp(argv[3], "zoomed", length) == 0)) { @@ -3455,6 +3478,9 @@ Tk_WmCmd(clientData, interp, argc, argv) (char *) NULL); return TCL_ERROR; } + if (wmPtr->masterPtr != NULL) { + wmPtr->flags |= WM_TRANSIENT_WITHDRAWN; + } TkpWmSetState(winPtr, WithdrawnState); } else { Tcl_AppendResult(interp, "unknown or ambiguous option \"", argv[1], @@ -3488,7 +3514,8 @@ WmWaitVisibilityOrMapProc(clientData, eventPtr) if (masterPtr == NULL) return; - if (eventPtr->type == MapNotify) { + if (eventPtr->type == MapNotify && + !(winPtr->wmInfoPtr->flags & WM_TRANSIENT_WITHDRAWN)) { TkpWmSetState(winPtr, NormalState); } else if (eventPtr->type == UnmapNotify) { TkpWmSetState(winPtr, WithdrawnState); |