1 # This file is a Tcl script to test out the "focus" command and the
2 # other procedures in the file tkFocus.c. It is organized in the
3 # standard fashion for Tcl tests.
5 # Copyright (c) 1994-1996 Sun Microsystems, Inc.
6 # Copyright (c) 1998-1999 by Scriptics Corporation.
11 package require tcltest 2.1
12 namespace import -force tcltest::configure
13 namespace import -force tcltest::testsDirectory
14 configure -testdir [file join [pwd] [file dirname [info script]]]
15 configure -loadfile [file join [testsDirectory] constraints.tcl]
16 tcltest::loadTestedCommands
18 button .b -text .b -relief raised -bd 2
25 foreach i {b1 b2 b3 b4} {
26 button .t.$i -text .t.$i -relief raised -bd 2
29 tkwait visibility .t.b4
31 proc focusSetupAlt {} {
34 toplevel .alt -screen $env(TK_ALT_DISPLAY)
36 button .alt.$i -text .alt.$i -relief raised -bd 2
39 tkwait visibility .alt.d
42 # Make sure the window manager knows who has focus
45 # The following procedure ensures that there is no input focus
46 # in this application. It does it by arranging for another
47 # application to grab the focus. The "after" and "update" stuff
48 # is needed to wait long enough for pending actions to get through
49 # the X server and possibly also the window manager.
56 dobg {focus -force .; update}
61 if {[testConstraint altDisplay]} {
67 append focusInfo "in %W %d\n"
70 append focusInfo "out %W %d\n"
73 append focusInfo "press %W %K"
76 test focus-1.1 {Tk_FocusCmd procedure} {unixOnly} {
80 test focus-1.2 {Tk_FocusCmd procedure} {unixOnly altDisplay} {
84 test focus-1.3 {Tk_FocusCmd procedure} {unixOnly} {
89 test focus-1.4 {Tk_FocusCmd procedure} {unixOnly} {
90 list [catch {focus ""} msg] $msg
92 test focus-1.5 {Tk_FocusCmd procedure} {unixOnly} {
98 test focus-1.6 {Tk_FocusCmd procedure} {unixOnly} {
99 list [catch {focus .gorp} msg] $msg
100 } {1 {bad window path name ".gorp"}}
101 test focus-1.7 {Tk_FocusCmd procedure} {unixOnly} {
102 list [catch {focus .gorp a} msg] $msg
103 } {1 {bad option ".gorp": must be -displayof, -force, or -lastfor}}
104 test focus-1.8 {Tk_FocusCmd procedure, focussing on dead window} {unixOnly} {
107 frame .t2.f -width 200 -height 100 -bd 2 -relief raised
108 frame .t2.f2 -width 200 -height 100 -bd 2 -relief raised
110 bind .t2.f <Destroy> {focus .t2.f}
111 bind .t2.f2 <Destroy> {focus .t2}
113 tkwait visibility .t2.f2
123 test focus-1.9 {Tk_FocusCmd procedure, -displayof option} {unixOnly} {
124 list [catch {focus -displayof} msg] $msg
125 } {1 {wrong # args: should be "focus -displayof window"}}
126 test focus-1.10 {Tk_FocusCmd procedure, -displayof option} {unixOnly} {
127 list [catch {focus -displayof a b} msg] $msg
128 } {1 {wrong # args: should be "focus -displayof window"}}
129 test focus-1.11 {Tk_FocusCmd procedure, -displayof option} {unixOnly} {
130 list [catch {focus -displayof .lousy} msg] $msg
131 } {1 {bad window path name ".lousy"}}
132 test focus-1.12 {Tk_FocusCmd procedure, -displayof option} {unixOnly} {
135 focus -displayof .t.b3
137 test focus-1.13 {Tk_FocusCmd procedure, -displayof option} {unixOnly} {
140 focus -displayof .t.b3
142 test focus-1.14 {Tk_FocusCmd procedure, -displayof option} {unixOnly altDisplay} {
144 focus -displayof .alt
146 test focus-1.15 {Tk_FocusCmd procedure, -force option} {unixOnly} {
147 list [catch {focus -force} msg] $msg
148 } {1 {wrong # args: should be "focus -force window"}}
149 test focus-1.16 {Tk_FocusCmd procedure, -force option} {unixOnly} {
150 list [catch {focus -force a b} msg] $msg
151 } {1 {wrong # args: should be "focus -force window"}}
152 test focus-1.17 {Tk_FocusCmd procedure, -force option} {unixOnly} {
153 list [catch {focus -force foo} msg] $msg
154 } {1 {bad window path name "foo"}}
155 test focus-1.18 {Tk_FocusCmd procedure, -force option} {unixOnly} {
156 list [catch {focus -force ""} msg] $msg
158 test focus-1.19 {Tk_FocusCmd procedure, -force option} {unixOnly} {
165 test focus-1.20 {Tk_FocusCmd procedure, -lastfor option} {unixOnly} {
166 list [catch {focus -lastfor} msg] $msg
167 } {1 {wrong # args: should be "focus -lastfor window"}}
168 test focus-1.21 {Tk_FocusCmd procedure, -lastfor option} {unixOnly} {
169 list [catch {focus -lastfor 1 2} msg] $msg
170 } {1 {wrong # args: should be "focus -lastfor window"}}
171 test focus-1.22 {Tk_FocusCmd procedure, -lastfor option} {unixOnly} {
172 list [catch {focus -lastfor who_knows?} msg] $msg
173 } {1 {bad window path name "who_knows?"}}
174 test focus-1.23 {Tk_FocusCmd procedure, -lastfor option} {unixOnly} {
177 list [focus -lastfor .] [focus -lastfor .t.b3]
179 test focus-1.24 {Tk_FocusCmd procedure, -lastfor option} {unixOnly} {
185 test focus-1.25 {Tk_FocusCmd procedure} {unixOnly} {
186 list [catch {focus -unknown} msg] $msg
187 } {1 {bad option "-unknown": must be -displayof, -force, or -lastfor}}
189 test focus-2.1 {TkFocusFilterEvent procedure} {unixOnly nonPortable testwrapper} {
195 event gen [testwrapper .t] <FocusIn> -detail NotifyAncestor \
196 -sendevent 0x54217567
199 test focus-2.2 {TkFocusFilterEvent procedure} {unixOnly nonPortable testwrapper} {
205 event gen .t <FocusIn> -detail NotifyAncestor -sendevent 0x547321ac
206 list $focusInfo [focus]
207 } {{in .t NotifyAncestor
209 test focus-2.3 {TkFocusFilterEvent procedure} {unixOnly nonPortable testwrapper} {
215 event gen [testwrapper .t] <FocusIn> -detail NotifyAncestor
217 list $focusInfo [focus -lastfor .t]
218 } {{out .b NotifyNonlinear
219 out . NotifyNonlinearVirtual
220 in .t NotifyNonlinear
222 test focus-2.4 {TkFocusFilterEvent procedure, FocusIn events} \
223 {unixOnly nonPortable testwrapper} {
226 # Important to end with NotifyAncestor, which is an
227 # event that is processed normally. This has a side
229 foreach detail {NotifyAncestor NotifyNonlinear
230 NotifyNonlinearVirtual NotifyPointer NotifyPointerRoot
231 NotifyVirtual NotifyAncestor} {
234 event gen [testwrapper .t] <FocusIn> -detail $detail
237 lappend result $focusInfo
240 } {{out . NotifyNonlinear
241 in .t NotifyNonlinearVirtual
242 in .t.b1 NotifyNonlinear
243 } {out . NotifyNonlinear
244 in .t NotifyNonlinearVirtual
245 in .t.b1 NotifyNonlinear
246 } {} {out . NotifyNonlinear
247 in .t NotifyNonlinearVirtual
248 in .t.b1 NotifyNonlinear
249 } {} {} {out . NotifyNonlinear
250 in .t NotifyNonlinearVirtual
251 in .t.b1 NotifyNonlinear
253 test focus-2.5 {TkFocusFilterEvent procedure, creating FocusInfo struct} \
254 {unixOnly nonPortable testwrapper} {
258 event gen [testwrapper .t] <FocusIn> -detail NotifyAncestor
259 list $focusInfo [focus]
260 } {{out . NotifyNonlinear
261 in .t NotifyNonlinearVirtual
262 in .t.b1 NotifyNonlinear
264 test focus-2.6 {TkFocusFilterEvent procedure, FocusIn events} \
265 {unixOnly testwrapper} {
269 event gen [testwrapper .t] <FocusIn> -detail NotifyAncestor
272 event gen . <KeyPress-x>
274 } {.t.b1 {press .t.b1 x}}
275 test focus-2.7 {TkFocusFilterEvent procedure, FocusOut events} \
276 {unixOnly testwrapper} {
278 foreach detail {NotifyAncestor NotifyInferior NotifyNonlinear
279 NotifyNonlinearVirtual NotifyPointer NotifyPointerRoot
282 event gen [testwrapper .t] <FocusOut> -detail $detail
284 lappend result [focus]
287 } {{} .t.b1 {} {} .t.b1 .t.b1 {}}
288 test focus-2.8 {TkFocusFilterEvent procedure, FocusOut events} \
289 {unixOnly testwrapper} {
291 event gen .t.b1 <FocusOut> -detail NotifyAncestor
294 test focus-2.9 {TkFocusFilterEvent procedure, FocusOut events} \
295 {unixOnly testwrapper} {
297 event gen [testwrapper .] <FocusOut> -detail NotifyAncestor
300 test focus-2.10 {TkFocusFilterEvent procedure, Enter events} \
301 {unixOnly testwrapper} {
305 foreach detail {NotifyAncestor NotifyInferior NotifyNonlinear
306 NotifyNonlinearVirtual NotifyVirtual} {
307 event gen [testwrapper .t] <Enter> -detail $detail -focus 1
309 lappend result [focus]
310 event gen [testwrapper .t] <Leave> -detail NotifyAncestor
314 } {.t.b1 {} .t.b1 .t.b1 .t.b1}
315 test focus-2.11 {TkFocusFilterEvent procedure, Enter events} \
316 {unixOnly testwrapper} {
319 event gen [testwrapper .t] <Enter> -detail NotifyAncestor
323 test focus-2.12 {TkFocusFilterEvent procedure, Enter events} \
324 {unixOnly testwrapper} {
328 event gen [testwrapper .t] <Enter> -detail NotifyAncestor -focus 1
332 test focus-2.13 {TkFocusFilterEvent procedure, Enter events} \
333 {unixOnly testwrapper} {
336 event gen [testwrapper .t] <Enter> -detail NotifyAncestor -focus 1
340 } {in .t NotifyVirtual
341 in .t.b1 NotifyAncestor
343 test focus-2.14 {TkFocusFilterEvent procedure, Enter events, ignore errors when setting focus due to implicit focus} {unixOnly testwrapper} {
350 event gen [testwrapper .t2] <Enter> -detail NotifyAncestor -focus 1
354 test focus-2.15 {TkFocusFilterEvent procedure, Leave events} \
355 {unixOnly testwrapper} {
358 foreach detail {NotifyAncestor NotifyInferior NotifyNonlinear
359 NotifyNonlinearVirtual NotifyVirtual} {
361 event gen [testwrapper .t] <Enter> -detail NotifyAncestor -focus 1
363 event gen [testwrapper .t] <Leave> -detail $detail
365 lappend result [focus]
368 } {{} .t.b1 {} {} {}}
369 test focus-2.16 {TkFocusFilterEvent procedure, Leave events} \
370 {unixOnly testwrapper} {
373 event gen [testwrapper .t] <Enter> -detail NotifyAncestor -focus 1
376 event gen [testwrapper .t] <Leave> -detail NotifyAncestor
379 } {out .t.b1 NotifyAncestor
382 test focus-2.17 {TkFocusFilterEvent procedure, Leave events} \
383 {unixOnly testwrapper} {
386 event gen [testwrapper .t] <Enter> -detail NotifyAncestor -focus 1
389 event gen .t.b1 <Leave> -detail NotifyAncestor
390 event gen [testwrapper .] <Leave> -detail NotifyAncestor
392 list $focusInfo [focus]
393 } {{out .t.b1 NotifyAncestor
397 test focus-3.1 {SetFocus procedure, create record on focus} \
398 {unixOnly testwrapper} {
399 toplevel .t2 -width 250 -height 100
407 # This test produces no result, but it will generate a protocol
408 # error if Tk forgets to make the window exist before focussing
410 test focus-3.2 {SetFocus procedure, making window exist} \
411 {unixOnly testwrapper} {
413 button .b2 -text "Another button"
419 # The following test doesn't produce a check-able result, but if
420 # there are bugs it may generate an X protocol error.
421 test focus-3.3 {SetFocus procedure, delaying claim of X focus} \
422 {unixOnly testwrapper} {
427 test focus-3.4 {SetFocus procedure, delaying claim of X focus} \
428 {unixOnly testwrapper} {
432 toplevel .t2 -width 250 -height 100
433 wm geometry .t2 +10+10
441 test focus-3.5 {SetFocus procedure, generating events} \
442 {unixOnly testwrapper} {
449 } {in .t NotifyVirtual
450 in .t.b2 NotifyAncestor
452 test focus-3.6 {SetFocus procedure, generating events} \
453 {unixOnly testwrapper} {
461 } {out .b NotifyNonlinear
462 out . NotifyNonlinearVirtual
463 in .t NotifyNonlinearVirtual
464 in .t.b2 NotifyNonlinear
466 test focus-3.7 {SetFocus procedure, generating events} \
467 {unixOnly nonPortable testwrapper} {
468 # Non-portable because some platforms generate extra events.
478 test focus-4.1 {TkFocusDeadWindow procedure} {unixOnly testwrapper} {
486 test focus-4.2 {TkFocusDeadWindow procedure} {unixOnly testwrapper} {
497 # Non-portable due to wm-specific redirection of input focus when
498 # windows are deleted:
500 test focus-4.3 {TkFocusDeadWindow procedure} {unixOnly nonPortable testwrapper} {
509 test focus-4.4 {TkFocusDeadWindow procedure} {unixOnly testwrapper} {
517 # I don't know how to test most of the remaining procedures of this file
518 # explicitly; they've already been exercised by the preceding tests.
521 test focus-5.1 {ChangeXFocus procedure, don't take focus unless have it} \
522 {unixOnly testwrapper secureserver} {
527 send [dobg {tk appname}] {focus -force .; update}
528 lappend result [focus]
531 lappend result [focus]
535 bind all <FocusIn> {}
536 bind all <FocusOut> {}
537 bind all <KeyPress> {}
541 test focus-6.1 {miscellaneous - embedded application in same process} \
542 {unixOnly testwrapper} {
543 eval interp delete [interp slaves]
547 frame .t.f1 -container 1
550 entry .t.f2.e1 -bg red
552 bind all <FocusIn> {lappend x "focus in %W %d"}
553 bind all <FocusOut> {lappend x "focus out %W %d"}
555 child eval "set argv {-use [winfo id .t.f1]}"
558 entry .e1 -bg lightBlue
560 bind all <FocusIn> {lappend x "focus in %W %d"}
561 bind all <FocusOut> {lappend x "focus out %W %d"}
565 # Claim the focus and wait long enough for it to really arrive.
567 focus -force .t.f2.e1
568 after 300 {set timer 1}
571 lappend x [focus] [child eval focus]
573 # See if a "focus" command will move the focus to the embedded
576 child eval {focus .e1}
577 after 300 {set timer 1}
580 child eval {lappend x |}
582 # Bring the focus back to the main application.
585 after 300 {set timer 1}
587 set result [list $x [child eval {set x}]]
590 } {{.t.f2.e1 {} {focus out .t.f2.e1 NotifyNonlinear} {focus out .t.f2 NotifyNonlinearVirtual} {focus in .t.f1 NotifyNonlinear} | {focus out .t.f1 NotifyNonlinear} {focus in .t.f2 NotifyNonlinearVirtual} {focus in .t.f2.e1 NotifyNonlinear}} {{focus in . NotifyVirtual} {focus in .e1 NotifyAncestor} | {focus out .e1 NotifyAncestor} {focus out . NotifyVirtual}}}
591 test focus-6.2 {miscellaneous - embedded application in different process} \
592 {unixOnly testwrapper} {
593 eval interp delete [interp slaves]
598 frame .t.f1 -container 1
601 entry .t.f2.e1 -bg red
603 bind all <FocusIn> {lappend x "focus in %W %d"}
604 bind all <FocusOut> {lappend x "focus out %W %d"}
605 setupbg -use [winfo id .t.f1]
607 entry .e1 -bg lightBlue
609 bind all <FocusIn> {lappend x "focus in %W %d"}
610 bind all <FocusOut> {lappend x "focus out %W %d"}
614 # Claim the focus and wait long enough for it to really arrive.
616 focus -force .t.f2.e1
617 after 300 {set timer 1}
620 lappend x [focus] [dobg focus]
622 # See if a "focus" command will move the focus to the embedded
626 after 300 {set timer 1}
631 # Bring the focus back to the main application.
634 after 300 {set timer 1}
636 set result [list $x [dobg {set x}]]
639 } {{.t.f2.e1 {} {focus out .t.f2.e1 NotifyNonlinear} {focus out .t.f2 NotifyNonlinearVirtual} {focus in .t.f1 NotifyNonlinear} | {focus out .t.f1 NotifyNonlinear} {focus in .t.f2 NotifyNonlinearVirtual} {focus in .t.f2.e1 NotifyNonlinear}} {{focus in . NotifyVirtual} {focus in .e1 NotifyAncestor} | {focus out .e1 NotifyAncestor} {focus out . NotifyVirtual}}}
642 bind all <FocusIn> {}
643 bind all <FocusOut> {}
646 ::tcltest::cleanupTests