# This file is a Tcl script to test out Tk's interactions with
# the window manager, including the "wm" command.  It is organized
# in the standard fashion for Tcl tests.
#
# Copyright (c) 1992-1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.
#
# RCS: @(#) $Id: wm.test,v 1.24 2004/03/17 18:15:50 das Exp $

# This file tests window manager interactions that work across
# platforms. Window manager tests that only work on a specific
# platform should be placed in unixWm.test or winWm.test.

package require tcltest 2.1
eval tcltest::configure $argv
tcltest::loadTestedCommands

wm deiconify .
if {![winfo ismapped .]} {
    tkwait visibility .
}

proc stdWindow {} {
    destroy .t
    toplevel .t -width 100 -height 50
    wm geom .t +0+0
    update
}

# [raise] and [lower] may return before the window manager
# has completed the operation.  The raiseDelay procedure
# idles for a while to give the operation a chance to complete.
#

proc raiseDelay {} {
    after 100; update
}


deleteWindows
stdWindow

test wm-1.1 {Tk_WmObjCmd procedure, miscellaneous errors} {
    list [catch {wm} msg] $msg
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-1.2 {Tk_WmObjCmd procedure, miscellaneous errors} {
    list [catch {wm foo} msg] $msg
} {1 {bad option "foo": must be aspect, attributes, client, colormapwindows, command, deiconify, focusmodel, frame, geometry, grid, group, iconbitmap, iconify, iconmask, iconname, iconposition, iconwindow, maxsize, minsize, overrideredirect, positionfrom, protocol, resizable, sizefrom, stackorder, state, title, transient, or withdraw}}

test wm-1.3 {Tk_WmObjCmd procedure, miscellaneous errors} {
    list [catch {wm command} msg] $msg
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-1.4 {Tk_WmObjCmd procedure, miscellaneous errors} {
    list [catch {wm aspect bogus} msg] $msg
} {1 {bad window path name "bogus"}}

test wm-1.5 {Tk_WmObjCmd procedure, miscellaneous errors} {
    catch {destroy .b}
    button .b -text hello
    list [catch {wm geometry .b} msg] $msg
} {1 {window ".b" isn't a top-level window}}


test wm-aspect-1.1 {usage} {
    list [catch {wm aspect} err] $err
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-aspect-1.2 {usage} {
    list [catch {wm aspect . _} err] $err
} {1 {wrong # args: should be "wm aspect window ?minNumer minDenom maxNumer maxDenom?"}}

test wm-aspect-1.3 {usage} {
    list [catch {wm aspect . _ _ _} err] $err
} {1 {wrong # args: should be "wm aspect window ?minNumer minDenom maxNumer maxDenom?"}}

test wm-aspect-1.4 {usage} {
    list [catch {wm aspect . _ _ _ _ _} err] $err
} {1 {wrong # args: should be "wm aspect window ?minNumer minDenom maxNumer maxDenom?"}}

test wm-aspect-1.5 {usage} {
    list [catch {wm aspect . bad 14 15 16} msg] $msg
} {1 {expected integer but got "bad"}}

test wm-aspect-1.6 {usage} {
    list [catch {wm aspect . 13 foo 15 16} msg] $msg
} {1 {expected integer but got "foo"}}

test wm-aspect-1.7 {usage} {
    list [catch {wm aspect . 13 14 bar 16} msg] $msg
} {1 {expected integer but got "bar"}}

test wm-aspect-1.8 {usage} {
    list [catch {wm aspect . 13 14 15 baz} msg] $msg
} {1 {expected integer but got "baz"}}

test wm-aspect-1.9 {usage} {
    list [catch {wm aspect . 0 14 15 16} msg] $msg
} {1 {aspect number can't be <= 0}}

test wm-aspect-1.10 {usage} {
    list [catch {wm aspect . 13 0 15 16} msg] $msg
} {1 {aspect number can't be <= 0}}

test wm-aspect-1.11 {usage} {
    list [catch {wm aspect . 13 14 0 16} msg] $msg
} {1 {aspect number can't be <= 0}}

test wm-aspect-1.12 {usage} {
    list [catch {wm aspect . 13 14 15 0} msg] $msg
} {1 {aspect number can't be <= 0}}

test wm-aspect-2.1 {setting and reading values} {
    set result {}
    lappend result [wm aspect .t]
    wm aspect .t 3 4 10 2
    lappend result [wm aspect .t]
    wm aspect .t {} {} {} {}
    lappend result [wm aspect .t]
} [list {} {3 4 10 2} {}]


test wm-attributes-1.1 {usage} {
    list [catch {wm attributes} err] $err
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-attributes-1.2.1 {usage} {pcOnly} {
    list [catch {wm attributes . _} err] $err
} {1 {wrong # args: should be "wm attributes window ?-disabled ?bool?? ?-toolwindow ?bool?? ?-topmost ?bool??"}}

test wm-attributes-1.2.2 {usage} {unixOnly} {
    list [catch {wm attributes . _} err] $err
} {1 {wrong # args: should be "wm attributes window"}}


test wm-client-1.1 {usage} {
    list [catch {wm client} err] $err
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-client-1.2 {usage} {
    list [catch {wm client . _ _} err] $err
} {1 {wrong # args: should be "wm client window ?name?"}}

test wm-client-2.1 {setting and reading values} {
    set result {}
    lappend result [wm client .t]
    wm client .t Miffo
    lappend result [wm client .t]
    wm client .t {}
    lappend result [wm client .t]
} [list {} Miffo {}]


test wm-colormapwindows-1.1 {usage} {
    list [catch {wm colormapwindows} err] $err
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-colormapwindows-1.2 {usage} {
    list [catch {wm colormapwindows . _ _} err] $err
} {1 {wrong # args: should be "wm colormapwindows window ?windowList?"}}

test wm-colormapwindows-1.3 {usage} {
    list [catch {wm colormapwindows . "a \{"} msg] $msg
} {1 {unmatched open brace in list}}

test wm-colormapwindows-1.4 {usage} {
    list [catch {wm colormapwindows . foo} msg] $msg
} {1 {bad window path name "foo"}}

test wm-colormapwindows-2.1 {reading values} {
    catch {destroy .t2}
    toplevel .t2 -width 200 -height 200 -colormap new
    wm geom .t2 +0+0
    frame .t2.a -width 100 -height 30
    frame .t2.b -width 100 -height 30 -colormap new
    pack .t2.a .t2.b -side top
    update
    set x [wm colormapwindows .t2]
    frame .t2.c -width 100 -height 30 -colormap new
    pack .t2.c -side top
    update
    list $x [wm colormapwindows .t2]
} {{.t2.b .t2} {.t2.b .t2.c .t2}}

test wm-colormapwindows-2.2 {setting and reading values} {
    catch {destroy .t2}
    toplevel .t2 -width 200 -height 200
    wm geom .t2 +0+0
    frame .t2.a -width 100 -height 30
    frame .t2.b -width 100 -height 30
    frame .t2.c -width 100 -height 30
    pack .t2.a .t2.b .t2.c -side top
    wm colormapwindows .t2 {.t2.b .t2.a}
    wm colormapwindows .t2
} {.t2.b .t2.a}


test wm-command-1.1 {usage} {
    list [catch {wm command} err] $err
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-command-1.2 {usage} {
    list [catch {wm command . _ _} err] $err
} {1 {wrong # args: should be "wm command window ?value?"}}

test wm-command-1.3 {usage} {
    list [catch {wm command . "a \{"} msg] $msg
} {1 {unmatched open brace in list}}

test wm-command-2.1 {setting and reading values} {
    set result {}
    lappend result [wm command .t]
    wm command .t [list Miffo Foo]
    lappend result [wm command .t]
    wm command .t {}
    lappend result [wm command .t]
} [list {} [list Miffo Foo] {}]


test wm-deiconify-1.1 {usage} {
    list [catch {wm deiconify} err] $err
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-deiconify-1.2 {usage} {
    list [catch {wm deiconify . _} err] $err
} {1 {wrong # args: should be "wm deiconify window"}}

test wm-deiconify-1.3 {usage} {
    list [catch {wm deiconify _} err] $err
} {1 {bad window path name "_"}}

test wm-deiconify-1.4 {usage} {
    catch {destroy .icon}
    toplevel .icon -width 50 -height 50 -bg red
    wm iconwindow .t .icon
    set result [list [catch {wm deiconify .icon} msg] $msg]
    destroy .icon
    set result
} {1 {can't deiconify .icon: it is an icon for .t}}

test wm-deiconify-1.5 {usage} {
    catch {destroy .embed}
    frame .t.f -container 1
    toplevel .embed -use [winfo id .t.f]
    set result [list [catch {wm deiconify .embed} msg] $msg]
    destroy .t.f .embed
    set result
} {1 {can't deiconify .embed: it is an embedded window}}

test wm-deiconify-2.1 {a window that has never been mapped
        should not be mapped by a call to deiconify} {
    deleteWindows
    toplevel .t
    wm deiconify .t
    winfo ismapped .t
} 0

test wm-deiconify-2.2 {a window that has already been
        mapped should be mapped by deiconify} {
    deleteWindows
    toplevel .t
    update idletasks
    wm withdraw .t
    wm deiconify .t
    winfo ismapped .t
} 1

test wm-deiconify-2.3 {geometry for an unmapped window
        should not be calculated by a call to deiconify,
        it should be done at idle time} {
    deleteWindows
    set results {}
    toplevel .t -width 200 -height 200
    lappend results [wm geometry .t]
    wm deiconify .t
    lappend results [wm geometry .t]
    update idletasks
    lappend results [lindex [split \
        [wm geometry .t] +] 0]
} {1x1+0+0 1x1+0+0 200x200}

test wm-deiconify-2.4 {invoking destroy after a deiconify
        should not result in a crash because of a callback
        set on the toplevel} {
    deleteWindows
    toplevel .t
    wm withdraw .t
    wm deiconify .t
    destroy .t
    update
} {}


test wm-focusmodel-1.1 {usage} {
    list [catch {wm focusmodel} err] $err
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-focusmodel-1.2 {usage} {
    list [catch {wm focusmodel . _ _} err] $err
} {1 {wrong # args: should be "wm focusmodel window ?active|passive?"}}

test wm-focusmodel-1.3 {usage} {
    list [catch {wm focusmodel . bogus} msg] $msg
} {1 {bad argument "bogus": must be active or passive}}

stdWindow

test wm-focusmodel-2.1 {setting and reading values} {
    set result {} 
    lappend result [wm focusmodel .t]
    wm focusmodel .t active
    lappend result [wm focusmodel .t]
    wm focusmodel .t passive
    lappend result [wm focusmodel .t]
    set result
} {passive active passive}


test wm-frame-1.1 {usage} {
    list [catch {wm frame} err] $err
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-frame-1.2 {usage} {
    list [catch {wm frame . _} err] $err
} {1 {wrong # args: should be "wm frame window"}}


test wm-geometry-1.1 {usage} {
    list [catch {wm geometry} err] $err
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-geometry-1.2 {usage} {
    list [catch {wm geometry . _ _} err] $err
} {1 {wrong # args: should be "wm geometry window ?newGeometry?"}}

test wm-geometry-1.3 {usage} {
    list [catch {wm geometry . bogus} msg] $msg
} {1 {bad geometry specifier "bogus"}}

test wm-geometry-2.1 {setting values} {
    set result {}
    wm geometry .t 150x150+50+50
    update
    lappend result [wm geometry .t]
    wm geometry .t {}
    update
    lappend result [string equal [wm geometry .t] "150x150+50+50"]
} [list 150x150+50+50 0]


test wm-grid-1.1 {usage} {
    list [catch {wm grid} err] $err
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-grid-1.2 {usage} {
    list [catch {wm grid . _} err] $err
} {1 {wrong # args: should be "wm grid window ?baseWidth baseHeight widthInc heightInc?"}}

test wm-grid-1.3 {usage} {
    list [catch {wm grid . _ _ _} err] $err
} {1 {wrong # args: should be "wm grid window ?baseWidth baseHeight widthInc heightInc?"}}

test wm-grid-1.4 {usage} {
    list [catch {wm grid . _ _ _ _ _} err] $err
} {1 {wrong # args: should be "wm grid window ?baseWidth baseHeight widthInc heightInc?"}}

test wm-grid-1.5 {usage} {
    list [catch {wm grid . bad 14 15 16} msg] $msg
} {1 {expected integer but got "bad"}}

test wm-grid-1.6 {usage} {
    list [catch {wm grid . 13 foo 15 16} msg] $msg
} {1 {expected integer but got "foo"}}

test wm-grid-1.7 {usage} {
    list [catch {wm grid . 13 14 bar 16} msg] $msg
} {1 {expected integer but got "bar"}}

test wm-grid-1.8 {usage} {
    list [catch {wm grid . 13 14 15 baz} msg] $msg
} {1 {expected integer but got "baz"}}

test wm-grid-1.9 {usage} {
    list [catch {wm grid . -1 14 15 16} msg] $msg
} {1 {baseWidth can't be < 0}}

test wm-grid-1.10 {usage} {
    list [catch {wm grid . 13 -1 15 16} msg] $msg
} {1 {baseHeight can't be < 0}}

test wm-grid-1.11 {usage} {
    list [catch {wm grid . 13 14 -1 16} msg] $msg
} {1 {widthInc can't be < 0}}

test wm-grid-1.12 {usage} {
    list [catch {wm grid . 13 14 15 -1} msg] $msg
} {1 {heightInc can't be < 0}}

test wm-grid-2.1 {setting and reading values} {
    set result {}
    lappend result [wm grid .t]
    wm grid .t 3 4 10 2
    lappend result [wm grid .t]
    wm grid .t {} {} {} {}
    lappend result [wm grid .t]
} [list {} {3 4 10 2} {}]


test wm-group-1.1 {usage} {
    list [catch {wm group} err] $err
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-group-1.2 {usage} {
    list [catch {wm group .t 12 13} msg] $msg
} {1 {wrong # args: should be "wm group window ?pathName?"}}

test wm-group-1.3 {usage} {
    list [catch {wm group .t bogus} msg] $msg
} {1 {bad window path name "bogus"}}

test wm-group-2.1 {setting and reading values} {
    set result {}
    lappend result [wm group .t]
    wm group .t .
    lappend result [wm group .t]
    wm group .t {}
    lappend result [wm group .t]
} [list {} . {}]


test wm-iconbitmap-1.1 {usage} {
    list [catch {wm iconbitmap} err] $err
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-iconbitmap-1.2.1 {usage} {unixOnly} {
    list [catch {wm iconbitmap .t 12 13} msg] $msg
} {1 {wrong # args: should be "wm iconbitmap window ?bitmap?"}}

test wm-iconbitmap-1.2.2 {usage} {pcOnly} {
    list [catch {wm iconbitmap .t 12 13 14} msg] $msg
} {1 {wrong # args: should be "wm iconbitmap window ?-default? ?image?"}}

test wm-iconbitmap-1.3 {usage} {pcOnly} {
    list [catch {wm iconbitmap .t 12 13} msg] $msg
} {1 {illegal option "12" must be "-default"}}

test wm-iconbitmap-1.4 {usage} {
    list [catch {wm iconbitmap .t bad-bitmap} msg] $msg
} {1 {bitmap "bad-bitmap" not defined}}

test wm-iconbitmap-2.1 {setting and reading values} {
    set result {}
    lappend result [wm iconbitmap .t]
    wm iconbitmap .t hourglass
    lappend result [wm iconbitmap .t]
    wm iconbitmap .t {}
    lappend result [wm iconbitmap .t]
} [list {} hourglass {}]


test wm-iconify-1.1 {usage} {
    list [catch {wm iconify} err] $err
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-iconify-1.2 {usage} {
    list [catch {wm iconify .t _} msg] $msg
} {1 {wrong # args: should be "wm iconify window"}}

test wm-iconify-2.1 {Misc errors} {
    catch {destroy .t2}
    toplevel .t2
    wm overrideredirect .t2 1
    set result [list [catch {wm iconify .t2} msg] $msg]
    destroy .t2
    set result
} {1 {can't iconify ".t2": override-redirect flag is set}}

test wm-iconify-2.2 {Misc errors} {
    catch {destroy .t2}
    toplevel .t2
    wm geom .t2 +0+0
    wm transient .t2 .t
    set result [list [catch {wm iconify .t2} msg] $msg]
    destroy .t2
    set result
} {1 {can't iconify ".t2": it is a transient}}

test wm-iconify-2.3 {Misc errors} {
    catch {destroy .t2}
    toplevel .t2
    wm geom .t2 +0+0
    wm iconwindow .t .t2
    set result [list [catch {wm iconify .t2} msg] $msg]
    destroy .t2
    set result
} {1 {can't iconify .t2: it is an icon for .t}}

test wm-iconify-2.4 {Misc errors} {
    catch {destroy .t2}
    frame .t.f -container 1
    toplevel .t2 -use [winfo id .t.f]
    set result [list [catch {wm iconify .t2} msg] $msg]
    destroy .t2 .r.f
    set result
} {1 {can't iconify .t2: it is an embedded window}}

test wm-iconify-3.1 {} {
    catch {destroy .t2}
    toplevel .t2
    wm geom .t2 -0+0
    update
    set result [winfo ismapped .t2]
    wm iconify .t2
    update
    lappend result [winfo ismapped .t2]
    destroy .t2
    set result
} {1 0}


test wm-iconmask-1.1 {usage} {
    list [catch {wm iconmask} err] $err
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-iconmask-1.2 {usage} {
    list [catch {wm iconmask .t 12 13} msg] $msg
} {1 {wrong # args: should be "wm iconmask window ?bitmap?"}}

test wm-iconmask-1.3 {usage} {
    list [catch {wm iconmask .t bad-bitmap} msg] $msg
} {1 {bitmap "bad-bitmap" not defined}}

test wm-iconmask-2.1 {setting and reading values} {
    set result {}
    lappend result [wm iconmask .t]
    wm iconmask .t hourglass
    lappend result [wm iconmask .t]
    wm iconmask .t {}
    lappend result [wm iconmask .t]
} [list {} hourglass {}]


test wm-iconname-1.1 {usage} {
    list [catch {wm iconname} err] $err
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-iconname-1.2 {usage} {
    list [catch {wm iconname .t 12 13} msg] $msg
} {1 {wrong # args: should be "wm iconname window ?newName?"}}

test wm-iconname-2.1 {setting and reading values} {
    set result {}
    lappend result [wm iconname .t]
    wm iconname .t ThisIconHasAName
    lappend result [wm iconname .t]
    wm iconname .t {}
    lappend result [wm iconname .t]
} [list {} ThisIconHasAName {}]


test wm-iconposition-1.1 {usage} {
    list [catch {wm iconposition} err] $err
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-iconposition-1.2 {usage} {
    list [catch {wm iconposition .t 12} msg] $msg
} {1 {wrong # args: should be "wm iconposition window ?x y?"}}

test wm-iconposition-1.3 {usage} {
    list [catch {wm iconposition .t 12 13 14} msg] $msg
} {1 {wrong # args: should be "wm iconposition window ?x y?"}}

test wm-iconposition-1.4 {usage} {
    list [catch {wm iconposition .t bad 13} msg] $msg
} {1 {expected integer but got "bad"}}

test wm-iconposition-1.5 {usage} {
    list [catch {wm iconposition .t 13 lousy} msg] $msg
} {1 {expected integer but got "lousy"}}

test wm-iconposition-2.1 {setting and reading values} {
    set result {}
    lappend result [wm iconposition .t]
    wm iconposition .t 10 20
    lappend result [wm iconposition .t]
    wm iconposition .t {} {}
    lappend result [wm iconposition .t]
} [list {} {10 20} {}]


test wm-iconwindow-1.1 {usage} {
    list [catch {wm iconwindow} err] $err
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-iconwindow-1.2 {usage} {
    list [catch {wm iconwindow .t 12 13} msg] $msg
} {1 {wrong # args: should be "wm iconwindow window ?pathName?"}}

test wm-iconwindow-1.3 {usage} {
    list [catch {wm iconwindow .t bogus} msg] $msg
} {1 {bad window path name "bogus"}}

test wm-iconwindow-1.4 {usage} {
    catch {destroy .b}
    button .b -text Help
    set result [list [catch {wm iconwindow .t .b} msg] $msg]
    destroy .b
    set result
} {1 {can't use .b as icon window: not at top level}}

test wm-iconwindow-1.5 {usage} {
    catch {destroy .icon}
    toplevel .icon -width 50 -height 50 -bg green
    catch {destroy .t2}
    toplevel .t2
    wm geom .t2 -0+0
    wm iconwindow .t2 .icon
    set result [list [catch {wm iconwindow .t .icon} msg] $msg]
    destroy .t2
    destroy .icon
    set result
} {1 {.icon is already an icon for .t2}}

test wm-iconwindow-2.1 {setting and reading values} {
    set result {}
    lappend result [wm iconwindow .t]
    catch {destroy .icon}
    toplevel .icon -width 50 -height 50 -bg green
    wm iconwindow .t .icon
    lappend result [wm iconwindow .t]
    wm iconwindow .t {}
    destroy .icon
    lappend result [wm iconwindow .t]
} [list {} .icon {}]


test wm-maxsize-1.1 {usage} {
    list [catch {wm maxsize} msg]  $msg
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-maxsize-1.2 {usage} {
    list [catch {wm maxsize . a} msg]  $msg
} {1 {wrong # args: should be "wm maxsize window ?width height?"}}

test wm-maxsize-1.3 {usage} {
    list [catch {wm maxsize . a b c} msg]  $msg
} {1 {wrong # args: should be "wm maxsize window ?width height?"}}

test wm-maxsize-1.4 {usage} {
    list [catch {wm maxsize . x 100} msg]  $msg
} {1 {expected integer but got "x"}}

test wm-maxsize-1.5 {usage} {
    list [catch {wm maxsize . 100 bogus} msg]  $msg
} {1 {expected integer but got "bogus"}}

test wm-maxsize-1.6 {usage} {
    catch {destroy .t2}
    toplevel .t2
    wm maxsize .t2 300 200
    set result [wm maxsize .t2]
    destroy .t2
    set result
} {300 200}

test wm-maxsize-1.7 {maxsize must be <= screen size} {
    destroy .t
    toplevel .t
    foreach {t_width t_height} [wm maxsize .t] break
    set s_width [winfo screenwidth .t]
    set s_height [winfo screenheight .t]
    expr {($t_width <= $s_width) && ($t_height <= $s_height)}
} 1

test wm-maxsize-2.1 {setting the maxsize to a value smaller
        than the current size will resize a toplevel} {
    destroy .t
    toplevel .t -width 300 -height 300
    update
    wm maxsize .t 200 150
    # UpdateGeometryInfo invoked at idle
    update
    lrange [split [wm geom .t] x+] 0 1
} {200 150}

test wm-maxsize-2.2 {setting the maxsize to a value smaller
        than the current size will resize a gridded toplevel} {
    destroy .t
    toplevel .t
    wm grid .t 0 0 50 50
    wm geometry .t 6x6
    update
    wm maxsize .t 4 3
    # UpdateGeometryInfo invoked at idle
    update
    lrange [split [wm geom .t] x+] 0 1
} {4 3}

test wm-maxsize-2.3 {attempting to resize to a value
        bigger than the current maxsize will
        set it to the max size} {
    destroy .t
    toplevel .t -width 200 -height 200
    wm maxsize .t 300 250
    update
    wm geom .t 400x300
    update
    lrange [split [wm geom .t] x+] 0 1
} {300 250}

test wm-maxsize-2.4 {attempting to resize to a value
        bigger than the current maxsize will
        set it to the max size when gridded} {
    destroy .t
    toplevel .t
    wm grid .t 1 1 50 50
    wm geom .t 4x4
    wm maxsize .t 6 5
    update
    wm geom .t 8x6
    update
    lrange [split [wm geom .t] x+] 0 1
} {6 5}

test wm-maxsize-2.5 {Use max size if window size is not
        explicitly set and the reqWidth/reqHeight are
        bigger than the max size} {
    destroy .t
    toplevel .t
    pack [frame .t.f -width 400 -height 400]
    update idletasks
    set req [list [winfo reqwidth .t] \
                      [winfo reqheight .t]]
    wm maxsize .t 300 300
    update
    list $req [lrange [split [wm geom .t] x+] 0 1]
} {{400 400} {300 300}}

test wm-minsize-1.1 {usage} {
    list [catch {wm minsize} msg]  $msg
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-minsize-1.2 {usage} {
    list [catch {wm minsize . a} msg]  $msg
} {1 {wrong # args: should be "wm minsize window ?width height?"}}

test wm-minsize-1.3 {usage} {
    list [catch {wm minsize . a b c} msg]  $msg
} {1 {wrong # args: should be "wm minsize window ?width height?"}}

test wm-minsize-1.4 {usage} {
    list [catch {wm minsize . x 100} msg]  $msg
} {1 {expected integer but got "x"}}

test wm-minsize-1.5 {usage} {
    list [catch {wm minsize . 100 bogus} msg]  $msg
} {1 {expected integer but got "bogus"}}

test wm-minsize-1.6 {usage} {
    catch {destroy .t2}
    toplevel .t2
    wm minsize .t2 300 200
    set result [wm minsize .t2]
    destroy .t2
    set result
} {300 200}

test wm-minsize-2.1 {setting the minsize to a value larger
        than the current size will resize a toplevel} {
    destroy .t
    toplevel .t -width 200 -height 200
    update
    wm minsize .t 400 300
    # UpdateGeometryInfo invoked at idle
    update
    lrange [split [wm geom .t] x+] 0 1
} {400 300}

test wm-minsize-2.2 {setting the minsize to a value larger
        than the current size will resize a gridded toplevel} {
    destroy .t
    toplevel .t
    wm grid .t 1 1 50 50
    wm geom .t 4x4
    update
    wm minsize .t 8 8
    # UpdateGeometryInfo invoked at idle
    update
    lrange [split [wm geom .t] x+] 0 1
} {8 8}

test wm-minsize-2.3 {attempting to resize to a value
        smaller than the current minsize will set
        it to the minsize} {
    destroy .t
    toplevel .t -width 400 -height 400
    wm minsize .t 300 300
    update
    wm geom .t 200x200
    update
    lrange [split [wm geom .t] x+] 0 1
} {300 300}

test wm-minsize-2.4 {attempting to resize to a value
        smaller than the current minsize will set
        it to the minsize when gridded} {
    destroy .t
    toplevel .t
    wm grid .t 1 1 50 50
    wm geom .t 8x8
    wm minsize .t 6 6
    update
    wm geom .t 4x4
    update
    lrange [split [wm geom .t] x+] 0 1
} {6 6}

test wm-minsize-2.5 {Use min size if window size is not
        explicitly set and the reqWidth/reqHeight are
        smaller than the min size} {
    destroy .t
    toplevel .t
    pack [frame .t.f -width 250 -height 250]
    update idletasks
    set req [list [winfo reqwidth .t] \
                      [winfo reqheight .t]]
    wm minsize .t 300 300
    update
    list $req [lrange [split [wm geom .t] x+] 0 1]
} {{250 250} {300 300}}

test wm-overrideredirect-1.1 {usage} {
    list [catch {wm overrideredirect} msg]  $msg
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-overrideredirect-1.2 {usage} {
    list [catch {wm overrideredirect .t 1 2} msg]  $msg
} {1 {wrong # args: should be "wm overrideredirect window ?boolean?"}}

test wm-overrideredirect-1.3 {usage} {
    list [catch {wm overrideredirect .t boo} msg]  $msg
} {1 {expected boolean value but got "boo"}}

test wm-overrideredirect-2.1 {setting and reading values} {
    set result {}
    lappend result [wm overrideredirect .t]
    wm overrideredirect .t true
    lappend result [wm overrideredirect .t]
    wm overrideredirect .t off
    lappend result [wm overrideredirect .t]
} {0 1 0}


test wm-positionfrom-1.1 {usage} {
    list [catch {wm positionfrom} msg]  $msg
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-positionfrom-1.2 {usage} {
    list [catch {wm positionfrom .t 1 2} msg]  $msg
} {1 {wrong # args: should be "wm positionfrom window ?user/program?"}}

test wm-positionfrom-1.3 {usage} {
    list [catch {wm positionfrom .t none} msg]  $msg
} {1 {bad argument "none": must be program or user}}

test wm-positionfrom-2.1 {setting and reading values} {
    catch {destroy .t2}
    toplevel .t2
    set result {}
    wm positionfrom .t user
    lappend result [wm positionfrom .t]
    wm positionfrom .t program
    lappend result [wm positionfrom .t]
    wm positionfrom .t {}
    lappend result [wm positionfrom .t]
    destroy .t2
    set result
} {user program {}}


test wm-protocol-1.1 {usage} {
    list [catch {wm protocol} msg]  $msg
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-protocol-1.2 {usage} {
    list [catch {wm protocol .t 1 2 3} msg]  $msg
} {1 {wrong # args: should be "wm protocol window ?name? ?command?"}}

test wm-protocol-2.1 {setting and reading values} {
    wm protocol .t {foo a} {a b c}
    wm protocol .t bar {test script for bar}
    set result [wm protocol .t]
    wm protocol .t {foo a} {}
    wm protocol .t bar {}
    set result
} {bar {foo a}}

test wm-protocol-2.2 {setting and reading values} {
    set result {}
    wm protocol .t foo {a b c}
    wm protocol .t bar {test script for bar}
    lappend result [wm protocol .t foo] [wm protocol .t bar]
    wm protocol .t foo {}
    wm protocol .t bar {}
    lappend result [wm protocol .t foo] [wm protocol .t bar]
} {{a b c} {test script for bar} {} {}}

test wm-protocol-2.3 {setting and reading values} {
    wm protocol .t foo {a b c}
    wm protocol .t foo {test script}
    set result [wm protocol .t foo]
    wm protocol .t foo {}
    set result
} {test script}


test wm-resizable-1.1 {usage} {
    list [catch {wm resizable} msg]  $msg
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-resizable-1.2 {usage} {
    list [catch {wm resizable .t 1} msg]  $msg
} {1 {wrong # args: should be "wm resizable window ?width height?"}}

test wm-resizable-1.3 {usage} {
    list [catch {wm resizable .t 1 2 3} msg]  $msg
} {1 {wrong # args: should be "wm resizable window ?width height?"}}

test wm-resizable-1.4 {usage} {
    list [catch {wm resizable .t bad 0} msg]  $msg
} {1 {expected boolean value but got "bad"}}

test wm-resizable-1.5 {usage} {
    list [catch {wm resizable .t 1 bad} msg]  $msg
} {1 {expected boolean value but got "bad"}}

test wm-resizable-2.1 {setting and reading values} {
    wm resizable .t 0 1
    set result [wm resizable .t]
    wm resizable .t 1 0
    lappend result [wm resizable .t]
    wm resizable .t 1 1
    lappend result [wm resizable .t]
} {0 1 {1 0} {1 1}}


test wm-sizefrom-1.1 {usage} {
    list [catch {wm sizefrom} msg]  $msg
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-sizefrom-1.2 {usage} {
    list [catch {wm sizefrom .t 1 2} msg]  $msg
} {1 {wrong # args: should be "wm sizefrom window ?user|program?"}}

test wm-sizefrom-1.4 {usage} {
    list [catch {wm sizefrom .t bad} msg]  $msg
} {1 {bad argument "bad": must be program or user}}

test wm-sizefrom-2.1 {setting and reading values} {
    set result [list [wm sizefrom .t]]
    wm sizefrom .t user
    lappend result [wm sizefrom .t]
    wm sizefrom .t program
    lappend result [wm sizefrom .t]
    wm sizefrom .t {}
    lappend result [wm sizefrom .t]
} {{} user program {}}



test wm-stackorder-1.1 {usage} {
    list [catch {wm stackorder} err] $err
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-stackorder-1.2 {usage} {
    list [catch {wm stackorder . _} err] $err
} {1 {wrong # args: should be "wm stackorder window ?isabove|isbelow window?"}}

test wm-stackorder-1.3 {usage} {
    list [catch {wm stackorder . _ _ _} err] $err
} {1 {wrong # args: should be "wm stackorder window ?isabove|isbelow window?"}}

test wm-stackorder-1.4 {usage} {
    list [catch {wm stackorder . is .} err] $err
} {1 {ambiguous argument "is": must be isabove or isbelow}}

test wm-stackorder-1.5 {usage} {
    list [catch {wm stackorder _} err] $err
} {1 {bad window path name "_"}}

test wm-stackorder-1.6 {usage} {
    list [catch {wm stackorder . isabove _} err] $err
} {1 {bad window path name "_"}}

test wm-stackorder-1.7 {usage} {
    catch {destroy .t}
    toplevel .t
    button .t.b
    list [catch {wm stackorder .t.b} err] $err
} {1 {window ".t.b" isn't a top-level window}}

test wm-stackorder-1.8 {usage} {
    catch {destroy .t}
    toplevel .t
    button .t.b
    pack .t.b
    update
    list [catch {wm stackorder . isabove .t.b} err] $err
} {1 {window ".t.b" isn't a top-level window}}

test wm-stackorder-1.9 {usage} {
    catch {destroy .t}
    toplevel .t
    button .t.b
    pack .t.b
    update
    list [catch {wm stackorder . isbelow .t.b} err] $err
} {1 {window ".t.b" isn't a top-level window}}

test wm-stackorder-1.10 {usage, isabove|isbelow toplevels must be mapped} {
    catch {destroy .t}
    toplevel .t ; update
    wm withdraw .t
    list [catch {wm stackorder .t isabove .} err] $err
} {1 {window ".t" isn't mapped}}

test wm-stackorder-1.11 {usage, isabove|isbelow toplevels must be mapped} {
    catch {destroy .t}
    toplevel .t ; update
    wm withdraw .t
    list [catch {wm stackorder . isbelow .t} err] $err
} {1 {window ".t" isn't mapped}}


deleteWindows


test wm-stackorder-2.1 {} {
    catch {destroy .t}
    toplevel .t ; update
    wm stackorder .
} {. .t}

test wm-stackorder-2.2 {} {
    catch {destroy .t}
    toplevel .t ; update
    raise .
    raiseDelay
    wm stackorder .
} {.t .}

test wm-stackorder-2.3 {} {
    catch {destroy .t}
    toplevel .t ; update
    catch {destroy .t2}
    toplevel .t2 ; update
    raise .
    raise .t2
    raiseDelay
    wm stackorder .
} {.t . .t2}

test wm-stackorder-2.4 {} {
    catch {destroy .t}
    toplevel .t ; update
    catch {destroy .t2}
    toplevel .t2 ; update
    raise .
    lower .t2
    raiseDelay
    wm stackorder .
} {.t2 .t .}

test wm-stackorder-2.5 {} {
    catch {destroy .parent}
    toplevel .parent ; update
    catch {destroy .parent.child1}
    toplevel .parent.child1 ; update
    catch {destroy .parent.child2}
    toplevel .parent.child2 ; update
    catch {destroy .extra}
    toplevel .extra ; update
    raise .parent
    lower .parent.child2
    raiseDelay
    wm stackorder .parent
} {.parent.child2 .parent.child1 .parent}

deleteWindows

test wm-stackorder-2.6 {non-toplevel widgets ignored} {
    catch {destroy .t1}
    toplevel .t1
    button .t1.b
    pack .t1.b
    update
    wm stackorder .
} {. .t1}

deleteWindows

test wm-stackorder-2.7 {no children returns self} {
    wm stackorder .
} {.}

deleteWindows


test wm-stackorder-3.1 {unmapped toplevel} {
    catch {destroy .t1}
    toplevel .t1 ; update
    catch {destroy .t2}
    toplevel .t2 ; update
    wm iconify .t1
    wm stackorder .
} {. .t2}

test wm-stackorder-3.2 {unmapped toplevel} {
    catch {destroy .t1}
    toplevel .t1 ; update
    catch {destroy .t2}
    toplevel .t2 ; update
    wm withdraw .t2
    wm stackorder .
} {. .t1}

test wm-stackorder-3.3 {unmapped toplevel} {
    catch {destroy .t1}
    toplevel .t1 ; update
    catch {destroy .t2}
    toplevel .t2 ; update
    wm withdraw .t2
    wm stackorder .t2
} {}

test wm-stackorder-3.4 {unmapped toplevel} {
    catch {destroy .t1}
    toplevel .t1 ; update
    toplevel .t1.t2 ; update
    wm withdraw .t1.t2
    wm stackorder .t1
} {.t1}

test wm-stackorder-3.5 {unmapped toplevel} {
    catch {destroy .t1}
    toplevel .t1 ; update
    toplevel .t1.t2 ; update
    wm withdraw .t1
    wm stackorder .t1
} {.t1.t2}

test wm-stackorder-3.6 {unmapped toplevel} {
    catch {destroy .t1}
    toplevel .t1 ; update
    toplevel .t1.t2 ; update
    toplevel .t1.t2.t3 ; update
    wm withdraw .t1.t2
    wm stackorder .t1
} {.t1 .t1.t2.t3}

test wm-stackorder-3.7 {unmapped toplevel, mapped children returned} {
    catch {destroy .t1}
    toplevel .t1 ; update
    toplevel .t1.t2 ; update
    wm withdraw .t1
    wm stackorder .t1
} {.t1.t2}

test wm-stackorder-3.8 {toplevel mapped in idle callback } {
    catch {destroy .t1}
    toplevel .t1
    wm stackorder .
} {.}


deleteWindows


test wm-stackorder-4.1 {wm stackorder isabove|isbelow} {
    catch {destroy .t}
    toplevel .t ; update
    raise .t
    wm stackorder . isabove .t
} {0}

test wm-stackorder-4.2 {wm stackorder isabove|isbelow} {
    catch {destroy .t}
    toplevel .t ; update
    raise .t
    wm stackorder . isbelow .t
} {1}

test wm-stackorder-4.3 {wm stackorder isabove|isbelow} {
    catch {destroy .t}
    toplevel .t ; update
    raise .
    raiseDelay
    wm stackorder .t isa .
} {0}

test wm-stackorder-4.4 {wm stackorder isabove|isbelow} {
    catch {destroy .t}
    toplevel .t ; update
    raise .
    raiseDelay
    wm stackorder .t isb .
} {1}

deleteWindows

test wm-stackorder-5.1 {a menu is not a toplevel} {
    catch {destroy .t}
    toplevel .t
    menu .t.m -type menubar
    .t.m add cascade -label "File"
    .t configure -menu .t.m
    update
    raise .
    raiseDelay
    wm stackorder .
} {.t .}

test wm-stackorder-5.2 {A normal toplevel can't be
        raised above an overrideredirect toplevel } {
    catch {destroy .t}
    toplevel .t
    wm overrideredirect .t 1
    raise .
    update
    raiseDelay
    wm stackorder . isabove .t
} 0

test wm-stackorder-5.3 {An overrideredirect window
        can be explicitly lowered } {
    catch {destroy .t}
    toplevel .t
    wm overrideredirect .t 1
    lower .t
    update
    raiseDelay
    wm stackorder .t isbelow .
} 1

test wm-stackorder-6.1 {An embedded toplevel does not
        appear in the stacking order} {
    deleteWindows
    toplevel .real -container 1
    toplevel .embd -bg blue -use [winfo id .real]
    update
    wm stackorder .
} {. .real}

stdWindow

test wm-title-1.1 {usage} {
    list [catch {wm title} msg]  $msg
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-title-1.2 {usage} {
    list [catch {wm title . 1 2} msg]  $msg
} {1 {wrong # args: should be "wm title window ?newTitle?"}}

test wm-title-2.1 {setting and reading values} {
    destroy .t
    toplevel .t
    set result [wm title .t]
    wm title .t Apa
    lappend result [wm title .t]
    wm title .t {}
    lappend result [wm title .t]
} {t Apa {}}


test wm-transient-1.1 {usage} {
    catch {destroy .t} ; toplevel .t
    list [catch {wm transient .t 1 2} msg]  $msg
} {1 {wrong # args: should be "wm transient window ?master?"}}

test wm-transient-1.2 {usage} {
    catch {destroy .t} ; toplevel .t
    list [catch {wm transient .t foo} msg]  $msg
} {1 {bad window path name "foo"}}

test wm-transient-1.3 {usage} {
    catch {destroy .t} ; toplevel .t
    list [catch {wm transient foo .t} msg]  $msg
} {1 {bad window path name "foo"}}

test wm-transient-1.4 {usage} {
    deleteWindows
    toplevel .master
    toplevel .subject
    wm transient .subject .master
    list [catch {wm iconify .subject} msg] $msg
} {1 {can't iconify ".subject": it is a transient}}

test wm-transient-1.5 {usage} {
    deleteWindows
    toplevel .icon -bg blue
    toplevel .top
    wm iconwindow .top .icon
    toplevel .dummy
    list [catch {wm transient .icon .dummy} msg] $msg
} {1 {can't make ".icon" a transient: it is an icon for .top}}

test wm-transient-1.6 {usage} {
    deleteWindows
    toplevel .icon -bg blue
    toplevel .top
    wm iconwindow .top .icon
    toplevel .dummy
    list [catch {wm transient .dummy .icon} msg] $msg
} {1 {can't make ".icon" a master: it is an icon for .top}}

test wm-transient-1.7 {usage} {
    deleteWindows
    toplevel .master
    list [catch {wm transient .master .master} err] $err
} {1 {can't make ".master" its own master}}

test wm-transient-1.8 {usage} {
    deleteWindows
    toplevel .master
    frame .master.f
    list [catch {wm transient .master .master.f} err] $err
} {1 {can't make ".master" its own master}}

test wm-transient-2.1 { basic get/set of master } {
    deleteWindows
    set results [list]    
    toplevel .master
    toplevel .subject
    lappend results [wm transient .subject]
    wm transient .subject .master
    lappend results [wm transient .subject]
    wm transient .subject {}
    lappend results [wm transient .subject]
    set results
} {{} .master {}}

test wm-transient-2.2 { first toplevel parent of
        non-toplevel master is used } {
    deleteWindows
    toplevel .master
    frame .master.f
    toplevel .subject
    wm transient .subject .master.f
    wm transient .subject
} {.master}

test wm-transient-3.1 { transient toplevel is withdrawn
        when mapped if master is withdrawn } {
    deleteWindows
    toplevel .master
    wm withdraw .master
    update
    toplevel .subject
    wm transient .subject .master
    update
    list [wm state .subject] [winfo ismapped .subject]
} {withdrawn 0}

test wm-transient-3.2 { already mapped transient toplevel
        takes on withdrawn state of master } {
    deleteWindows
    toplevel .master
    wm withdraw .master
    update
    toplevel .subject
    update
    wm transient .subject .master
    update
    list [wm state .subject] [winfo ismapped .subject]
} {withdrawn 0}

test wm-transient-3.3 { withdraw/deiconify on the master
        also does a withdraw/deiconify on the transient } {
    deleteWindows
    set results [list]
    toplevel .master
    toplevel .subject
    update
    wm transient .subject .master
    wm withdraw .master
    update
    lappend results [wm state .subject] \
        [winfo ismapped .subject]
    wm deiconify .master
    update
    lappend results [wm state .subject] \
        [winfo ismapped .subject]
    set results
} {withdrawn 0 normal 1}

test wm-transient-4.1 { transient toplevel is withdrawn
        when mapped if master is iconic } {
    deleteWindows
    toplevel .master
    wm iconify .master
    update
    toplevel .subject
    wm transient .subject .master
    update
    list [wm state .subject] [winfo ismapped .subject]
} {withdrawn 0}

test wm-transient-4.2 { already mapped transient toplevel
        is withdrawn if master is iconic } {
    deleteWindows
    toplevel .master
    wm iconify .master
    update
    toplevel .subject
    update
    wm transient .subject .master
    update
    list [wm state .subject] [winfo ismapped .subject]
} {withdrawn 0}

test wm-transient-4.3 { iconify/deiconify on the master
        does a withdraw/deiconify on the transient } {
    deleteWindows
    set results [list]
    toplevel .master
    toplevel .subject
    update
    wm transient .subject .master
    wm iconify .master
    update
    lappend results [wm state .subject] \
        [winfo ismapped .subject]
    wm deiconify .master
    update
    lappend results [wm state .subject] \
        [winfo ismapped .subject]
    set results
} {withdrawn 0 normal 1}

test wm-transient-5.1 { an error during transient command should not
        cause the map/unmap binding to be deleted } {
    deleteWindows
    set results [list]
    toplevel .master
    toplevel .subject
    update
    wm transient .subject .master
    # Expect a bad window path error here
    lappend results [catch {wm transient .subject .bad}]
    wm withdraw .master
    update
    lappend results [wm state .subject]
    wm deiconify .master
    update
    lappend results [wm state .subject]
    set results
} {1 withdrawn normal}

test wm-transient-5.2 { remove transient property when master
        is destroyed } {
    deleteWindows
    toplevel .master
    toplevel .subject
    wm transient .subject .master
    update
    destroy .master
    update
    wm transient .subject
} {}

test wm-transient-5.3 { remove transient property from window
        that had never been mapped when master is destroyed } {
    deleteWindows
    toplevel .master
    toplevel .subject
    wm transient .subject .master
    destroy .master
    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
    # idle handler should not map the transient
    update
    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
    # idle handler should not map the transient
    update
    lappend results [wm state .subject]
    wm deiconify .subject
    lappend results [wm state .subject]
    wm withdraw .master
    lappend results [wm state .subject]
    wm deiconify .master
    # idle handler should map transient
    update
    lappend results [wm state .subject]
} {withdrawn normal withdrawn normal}

test wm-transient-6.3 { a withdrawn transient does not track
        state changes in the master } {
    deleteWindows
    toplevel .master
    toplevel .subject
    update
    # withdraw before making window a transient
    wm withdraw .subject
    wm transient .subject .master
    wm withdraw .master
    wm deiconify .master
    # idle handler should not map the transient
    update
    wm state .subject
} {withdrawn}

# 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} {
    deleteWindows
    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} {
    deleteWindows
    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} {
    deleteWindows
    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} {
    deleteWindows
    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} {
    deleteWindows
    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 ...?"}}

test wm-state-1.2 {usage} {
    list [catch {wm state . _ _} err] $err
} {1 {wrong # args: should be "wm state window ?state?"}}

test wm-state-2.1 {initial state} {
    deleteWindows
    toplevel .t
    wm state .t
} {normal}

test wm-state-2.2 {state change before map} {
    deleteWindows
    toplevel .t
    wm state .t withdrawn
    wm state .t
} {withdrawn}

test wm-state-2.3 {state change before map} {
    deleteWindows
    toplevel .t
    wm withdraw .t
    wm state .t
} {withdrawn}

test wm-state-2.4 {state change after map} {
    deleteWindows
    toplevel .t
    update
    wm state .t withdrawn
    wm state .t
} {withdrawn}

test wm-state-2.5 {state change after map} {
    deleteWindows
    toplevel .t
    update
    wm withdraw .t
    wm state .t
} {withdrawn}

test wm-state-2.6 {state change before map} {
    deleteWindows
    toplevel .t
    wm state .t iconic
    wm state .t
} {iconic}

test wm-state-2.7 {state change before map} {
    deleteWindows
    toplevel .t
    wm iconify .t
    wm state .t
} {iconic}

test wm-state-2.8 {state change after map} {
    deleteWindows
    toplevel .t
    update
    wm state .t iconic
    wm state .t
} {iconic}

test wm-state-2.9 {state change after map} {
    deleteWindows
    toplevel .t
    update
    wm iconify .t
    wm state .t
} {iconic}

test wm-state-2.10 {state change before map} {
    deleteWindows
    toplevel .t
    wm withdraw .t
    wm state .t normal
    wm state .t
} {normal}

test wm-state-2.11 {state change before map} {
    deleteWindows
    toplevel .t
    wm withdraw .t
    wm deiconify .t
    wm state .t
} {normal}

test wm-state-2.12 {state change after map} {
    deleteWindows
    toplevel .t
    update
    wm withdraw .t
    wm state .t normal
    wm state .t
} {normal}

test wm-state-2.13 {state change after map} {
    deleteWindows
    toplevel .t
    update
    wm withdraw .t
    wm deiconify .t
    wm state .t
} {normal}

test wm-state-2.14 {state change before map} {
    deleteWindows
    toplevel .t
    wm iconify .t
    wm state .t normal
    wm state .t
} {normal}

test wm-state-2.15 {state change before map} {
    deleteWindows
    toplevel .t
    wm iconify .t
    wm deiconify .t
    wm state .t
} {normal}

test wm-state-2.16 {state change after map} {
    deleteWindows
    toplevel .t
    update
    wm iconify .t
    wm state .t normal
    wm state .t
} {normal}

test wm-state-2.17 {state change after map} {
    deleteWindows
    toplevel .t
    update
    wm iconify .t
    wm deiconify .t
    wm state .t
} {normal}


test wm-withdraw-1.1 {usage} {
    list [catch {wm withdraw} err] $err
} {1 {wrong # args: should be "wm option window ?arg ...?"}}

test wm-withdraw-1.2 {usage} {
    list [catch {wm withdraw . _} msg] $msg
} {1 {wrong # args: should be "wm withdraw window"}}

test wm-withdraw-2.1 {Misc errors} {
    deleteWindows
    toplevel .t
    toplevel .t2
    wm iconwindow .t .t2
    set result [list [catch {wm withdraw .t2} msg] $msg]
    destroy .t2
    set result
} {1 {can't withdraw .t2: it is an icon for .t}}

test wm-withdraw-3.1 {} {
    update
    set result {}
    wm withdraw .t
    lappend result [wm state .t] [winfo ismapped .t]
    wm deiconify .t
    lappend result [wm state .t] [winfo ismapped .t]
} {withdrawn 0 normal 1}

test wm-deletion-epoch-1.1 {Deletion epoch on multiple displays} {altDisplay} {
    # See Tk Bug #671330 "segfault when e.g. deiconifying destroyed window"
    deleteWindows
    set w [toplevel .t -screen $env(TK_ALT_DISPLAY)]
    wm deiconify $w         ;# this caches the WindowRep
    destroy .t
    list [catch {wm deiconify $w} msg] $msg
} {1 {bad window path name ".t"}}

# FIXME:

# Test delivery of virtual events to the WM. We could check to see
# if the window was raised after a button click for example.
# This sort of testing may not be possible.


deleteWindows
cleanupTests
return