summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--tests/wm.test35
-rw-r--r--unix/tkUnixWm.c21
-rw-r--r--win/tkWinWm.c31
4 files changed, 95 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index c395b71..c0a1020 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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);