1 # This file is a Tcl script to test the code in tkEvent.c. It is
2 # organized in the standard fashion for Tcl tests.
4 # Copyright (c) 1994 The Regents of the University of California.
5 # Copyright (c) 1994-1995 Sun Microsystems, Inc.
6 # Copyright (c) 1998-1999 by Scriptics Corporation.
9 package require tcltest 2.2
10 eval tcltest::configure $argv
11 tcltest::loadTestedCommands
12 namespace import -force tcltest::test
14 # XXX This test file is woefully incomplete. Right now it only tests
15 # a few of the procedures in tkEvent.c. Please add more tests whenever
18 # Setup table used to query key events.
20 proc _init_keypress_lookup {} {
21 global keypress_lookup
26 for {set i $start} {$i <= $finish} {incr i} {
28 set keypress_lookup($l) $l
34 for {set i $start} {$i <= $finish} {incr i} {
36 set keypress_lookup($l) $l
42 for {set i $start} {$i <= $finish} {incr i} {
44 set keypress_lookup($l) $l
48 array set keypress_lookup {
72 # Characters with meaning to Tcl...
73 array set keypress_lookup [list \
88 # Lookup an event in the keypress table.
96 proc _keypress_lookup {char} {
97 global keypress_lookup
99 if {! [info exists keypress_lookup]} {
100 _init_keypress_lookup
107 if {[info exists keypress_lookup($char)]} {
108 return $keypress_lookup($char)
114 # Lookup and generate a pair of KeyPress and KeyRelease events
116 proc _keypress {win key} {
117 set keysym [_keypress_lookup $key]
119 # Force focus to the window before delivering
120 # each event so that a window manager using
121 # a focus follows mouse will not steal away
122 # the focus if the mouse is moved around.
124 if {[focus] != $win} {
127 event generate $win <KeyPress-$keysym>
129 if {[focus] != $win} {
132 event generate $win <KeyRelease-$keysym>
136 # Call _keypress for each character in the given string
138 proc _keypress_string {win string} {
139 foreach letter [split $string ""] {
140 _keypress $win $letter
144 # Delay script execution for a given amount of time
146 proc _pause {{msecs 1000}} {
149 if {! [info exists _pause(number)]} {
153 set num [incr _pause(number)]
156 after $msecs "set _pause($num) 1"
161 # Helper proc to convert index to x y position
163 proc _text_ind_to_x_y {text ind} {
164 set bbox [$text bbox $ind]
165 if {[llength $bbox] != 4} {
166 error "got bbox \{$bbox\} from $text, index $ind"
168 foreach {x1 y1 width height} $bbox break
169 set middle_y [expr {$y1 + ($height / 2)}]
170 return [list $x1 $middle_y]
173 # Return selection only if owned by the given widget
175 proc _get_selection {widget} {
176 if {[string compare $widget [selection own]] != 0} {
179 if {[catch {selection get} sel]} {
185 # Begining of the actual tests
187 test event-1.1 {Tk_HandleEvent procedure, filter events for dead windows} -setup {
197 event generate .b <1>
198 event generate .b <ButtonRelease-1>
209 test event-1.2 {event generate <Alt-z>} -setup {
211 catch {unset ::event12result}
213 set ::event12result 0
216 bind .e <Alt-z> {set ::event12result "1"}
219 event generate .e <Alt-z>
227 test event-2.1(keypress) {type into entry widget and hit Return} -setup {
234 bind $e <Return> {set return_binding 1}
236 _keypress_string $e HELLO\n
237 list [$e get] $return_binding
241 test event-2.2(keypress) {type into entry widget and then delete some text} -setup {
248 # Avoid a hang when macOS puts the mouse pointer on the green button
249 wm geometry .t +200+100
250 _keypress_string $e MELLO
251 _keypress $e BackSpace
252 _keypress $e BackSpace
257 test event-2.3(keypress) {type into entry widget, triple click, hit Delete key,
258 and then type some more} -setup {
265 _keypress_string $e JUMP
269 event generate $e <Enter>
270 for {set i 0} {$i < 3} {incr i} {
272 event generate $e <ButtonPress-1>
274 event generate $e <ButtonRelease-1>
278 _keypress_string $e UP
279 lappend result [$e get]
283 test event-2.4(keypress) {type into text widget and hit Return} -setup {
290 bind $e <Return> {set return_binding 1}
292 _keypress_string $e HELLO\n
293 list [$e get 1.0 end] $return_binding
296 } -result [list "HELLO\n\n" 1]
297 test event-2.5(keypress) {type into text widget and then delete some text} -setup {
304 _keypress_string $e MELLO
305 _keypress $e BackSpace
306 _keypress $e BackSpace
311 test event-2.6(keypress) {type into text widget, triple click,
312 hit Delete key, and then type some more} -setup {
319 _keypress_string $e JUMP
321 set result [$e get 1.0 1.end]
323 event generate $e <Enter>
324 for {set i 0} {$i < 3} {incr i} {
326 event generate $e <ButtonPress-1>
328 event generate $e <ButtonRelease-1>
332 _keypress_string $e UP
333 lappend result [$e get 1.0 1.end]
338 test event-3.1(click-drag) {click and drag in a text widget, this tests
339 tkTextSelectTo in text.tcl} -setup {
346 _keypress_string $e "A Tcl/Tk selection test!"
351 lappend result [$e get 1.0 1.end]
353 # Get the x,y coords of the second T in "Tcl/Tk"
354 foreach {anchor_x anchor_y} [_text_ind_to_x_y $e $anchor] break
356 # Click down to set the insert cursor position
357 event generate $e <Enter>
358 event generate $e <ButtonPress-1> -x $anchor_x -y $anchor_y
360 # Save the position of the insert cursor
361 lappend result [$e index insert]
363 # Now drag until selend is highlighted, then click up
366 while {[$e compare $current <= $selend]} {
367 foreach {current_x current_y} [_text_ind_to_x_y $e $current] break
368 event generate $e <B1-Motion> -x $current_x -y $current_y
369 set current [$e index [list $current + 1 char]]
373 event generate $e <ButtonRelease-1> -x $current_x -y $current_y
376 # Save the position of the insert cursor
377 lappend result [$e index insert]
379 # Save the highlighted text
380 lappend result [_get_selection $e]
382 # Now click and click and drag to the left, over "Tcl/Tk selection"
384 event generate $e <ButtonPress-1> -x $current_x -y $current_y
386 while {[$e compare $current >= [list $anchor - 4 char]]} {
387 foreach {current_x current_y} [_text_ind_to_x_y $e $current] break
388 event generate $e <B1-Motion> -x $current_x -y $current_y
389 set current [$e index [list $current - 1 char]]
393 event generate $e <ButtonRelease-1> -x $current_x -y $current_y
396 # Save the position of the insert cursor
397 lappend result [$e index insert]
399 # Save the highlighted text
400 lappend result [_get_selection $e]
404 } -result {{A Tcl/Tk selection test!} 1.6 1.18 {Tk selection} 1.2 {Tcl/Tk selection}}
405 test event-3.2(click-drag) {click and drag in an entry widget, this
406 tests tkEntryMouseSelect in entry.tcl} -setup {
413 _keypress_string $e "A Tcl/Tk selection!"
418 lappend result [$e get]
420 # Get the x,y coords of the second T in "Tcl/Tk"
421 foreach {anchor_x anchor_y} [_text_ind_to_x_y $e $anchor] break
423 # Click down to set the insert cursor position
424 event generate $e <Enter>
425 event generate $e <ButtonPress-1> -x $anchor_x -y $anchor_y
427 # Save the position of the insert cursor
428 lappend result [$e index insert]
430 # Now drag until selend is highlighted, then click up
433 while {$current <= $selend} {
434 foreach {current_x current_y} [_text_ind_to_x_y $e $current] break
435 event generate $e <B1-Motion> -x $current_x -y $current_y
440 event generate $e <ButtonRelease-1> -x $current_x -y $current_y
443 # Save the position of the insert cursor
444 lappend result [$e index insert]
446 # Save the highlighted text
447 lappend result [_get_selection $e]
449 # Now click and click and drag to the left, over "Tcl/Tk selection"
451 event generate $e <ButtonPress-1> -x $current_x -y $current_y
453 while {$current >= ($anchor - 4)} {
454 foreach {current_x current_y} [_text_ind_to_x_y $e $current] break
455 event generate $e <B1-Motion> -x $current_x -y $current_y
460 event generate $e <ButtonRelease-1> -x $current_x -y $current_y
463 # Save the position of the insert cursor
464 lappend result [$e index insert]
466 # Save the highlighted text
467 lappend result [_get_selection $e]
471 } -result {{A Tcl/Tk selection!} 6 18 {Tk selection} 2 {Tcl/Tk selection}}
474 test event-4.1(double-click-drag) {click down, click up, click down again,
475 then drag in a text widget} -setup {
482 _keypress_string $e "Word select test"
485 # Get the x,y coords of the second e in "select"
486 foreach {anchor_x anchor_y} [_text_ind_to_x_y $e $anchor] break
488 # Click down, release, then click down again
489 event generate $e <Enter>
490 event generate $e <ButtonPress-1> -x $anchor_x -y $anchor_y
492 event generate $e <ButtonRelease-1> -x $anchor_x -y $anchor_y
494 event generate $e <ButtonPress-1> -x $anchor_x -y $anchor_y
497 # Save the highlighted text
499 lappend result [_get_selection $e]
501 # Insert cursor should be at beginning of "select"
502 lappend result [$e index insert]
504 # Move mouse one character to the left
505 set current [$e index [list $anchor - 1 char]]
506 foreach {current_x current_y} [_text_ind_to_x_y $e $current] break
508 event generate $e <B1-Motion> -x $current_x -y $current_y
511 # Insert cursor should be before the l in "select"
512 lappend result [$e index insert]
514 # Selection should still be the word "select"
515 lappend result [_get_selection $e]
517 # Move mouse to the space before the word "select"
518 set current [$e index [list $current - 3 char]]
520 foreach {current_x current_y} [_text_ind_to_x_y $e $current] break
521 event generate $e <B1-Motion> -x $current_x -y $current_y
524 lappend result [$e index insert]
525 lappend result [_get_selection $e]
527 # Move mouse to the r in "Word"
529 foreach {current_x current_y} [_text_ind_to_x_y $e $current] break
531 event generate $e <B1-Motion> -x $current_x -y $current_y
534 # Selection should now be "Word select"
535 lappend result [_get_selection $e]
537 # Insert cursor should be before the r in "Word"
538 lappend result [$e index insert]
543 } -result {select 1.5 1.7 select 1.4 { select} {Word select} 1.2}
544 test event-4.2(double-click-drag) {click down, click up, click down again,
545 then drag in an entry widget} -setup {
552 _keypress_string $e "Word select test"
556 # Get the x,y coords of the second e in "select"
557 foreach {anchor_x anchor_y} [_text_ind_to_x_y $e $anchor] break
559 # Click down, release, then click down again
560 event generate $e <Enter>
561 event generate $e <ButtonPress-1> -x $anchor_x -y $anchor_y
563 event generate $e <ButtonRelease-1> -x $anchor_x -y $anchor_y
565 event generate $e <ButtonPress-1> -x $anchor_x -y $anchor_y
569 lappend result [_get_selection $e]
571 # Insert cursor should be at the end of "select"
572 lappend result [$e index insert]
574 # Move mouse one character to the left
575 set current [expr {$anchor - 1}]
576 foreach {current_x current_y} [_text_ind_to_x_y $e $current] break
578 event generate $e <B1-Motion> -x $current_x -y $current_y
581 # Insert cursor should be before the l in "select"
582 lappend result [$e index insert]
584 # Selection should still be the word "select"
585 lappend result [_get_selection $e]
587 # Move mouse to the space before the word "select"
588 set current [expr {$current - 3}]
589 foreach {current_x current_y} [_text_ind_to_x_y $e $current] break
591 event generate $e <B1-Motion> -x $current_x -y $current_y
594 lappend result [$e index insert]
595 lappend result [_get_selection $e]
597 # Move mouse to the r in "Word"
598 set current [expr {$current - 2}]
599 foreach {current_x current_y} [_text_ind_to_x_y $e $current] break
601 event generate $e <B1-Motion> -x $current_x -y $current_y
604 # Selection should now be "Word select"
605 lappend result [_get_selection $e]
607 # Insert cursor should be before the r in "Word"
608 lappend result [$e index insert]
613 } -result {select 11 7 select 4 { select} {Word select} 2}
615 test event-5.1(triple-click-drag) {Triple click and drag across lines in a
616 text widget, this should extend the selection to the new line} -setup {
623 _keypress_string $e "LINE ONE\nLINE TWO\nLINE THREE"
627 # Triple click one third line leaving mouse down
629 foreach {anchor_x anchor_y} [_text_ind_to_x_y $e $anchor] break
631 event generate $e <Enter>
633 event generate $e <ButtonPress-1> -x $anchor_x -y $anchor_y
635 event generate $e <ButtonRelease-1> -x $anchor_x -y $anchor_y
638 event generate $e <ButtonPress-1> -x $anchor_x -y $anchor_y
640 event generate $e <ButtonRelease-1> -x $anchor_x -y $anchor_y
643 event generate $e <ButtonPress-1> -x $anchor_x -y $anchor_y
647 lappend result [_get_selection $e]
649 # Drag up to second line
651 set current [$e index [list $anchor - 1 line]]
652 foreach {current_x current_y} [_text_ind_to_x_y $e $current] break
654 event generate $e <B1-Motion> -x $current_x -y $current_y
657 lappend result [_get_selection $e]
659 # Drag up to first line
661 set current [$e index [list $current - 1 line]]
662 foreach {current_x current_y} [_text_ind_to_x_y $e $current] break
664 event generate $e <B1-Motion> -x $current_x -y $current_y
667 lappend result [_get_selection $e]
672 } -result [list "LINE THREE\n" "LINE TWO\nLINE THREE\n" \
673 "LINE ONE\nLINE TWO\nLINE THREE\n"]
675 test event-6.1(button-state) {button press in a window that is then
676 destroyed, when the mouse is moved into another window it
677 should not generate a <B1-motion> event since the mouse
678 was not pressed down in that window} -setup {
683 event generate $t <ButtonPress-1>
687 bind $t <B1-Motion> {set motion inmotion}
688 event generate $t <Motion>
694 test event-7.1(double-click) {A double click on a lone character
695 in a text widget should select that character} -setup {
703 _keypress_string $e "On A letter"
707 # Get x,y coords just inside the left
708 # and right hand side of the letter A
709 foreach {x1 y1 width height} [$e bbox $anchor] break
711 set middle_y [expr {$y1 + ($height / 2)}]
713 set left_x [expr {$x1 + 2}]
716 set right_x [expr {($x1 + $width) - 2}]
717 set right_y $middle_y
719 # Double click near left hand egde of the letter A
721 event generate $e <Enter>
722 event generate $e <ButtonPress-1> -x $left_x -y $left_y
724 event generate $e <ButtonRelease-1> -x $left_x -y $left_y
726 event generate $e <ButtonPress-1> -x $left_x -y $left_y
728 event generate $e <ButtonRelease-1> -x $left_x -y $left_y
732 lappend result [$e index insert]
733 lappend result [_get_selection $e]
735 # Clear selection by clicking at 0,0
737 event generate $e <ButtonPress-1> -x 0 -y 0
739 event generate $e <ButtonRelease-1> -x 0 -y 0
742 # Double click near right hand edge of the letter A
744 event generate $e <ButtonPress-1> -x $right_x -y $right_y
746 event generate $e <ButtonRelease-1> -x $right_x -y $right_y
748 event generate $e <ButtonPress-1> -x $right_x -y $right_y
750 event generate $e <ButtonRelease-1> -x $right_x -y $right_y
753 lappend result [$e index insert]
754 lappend result [_get_selection $e]
759 } -result {1.3 A 1.3 A}
760 test event-7.2(double-click) {A double click on a lone character
761 in an entry widget should select that character} -setup {
769 _keypress_string $e "On A letter"
773 # Get x,y coords just inside the left
774 # and right hand side of the letter A
775 foreach {x1 y1 width height} [$e bbox $anchor] break
777 set middle_y [expr {$y1 + ($height / 2)}]
779 set left_x [expr {$x1 + 2}]
782 set right_x [expr {($x1 + $width) - 2}]
783 set right_y $middle_y
785 # Double click near left hand egde of the letter A
787 event generate $e <Enter>
788 event generate $e <ButtonPress-1> -x $left_x -y $left_y
790 event generate $e <ButtonRelease-1> -x $left_x -y $left_y
792 event generate $e <ButtonPress-1> -x $left_x -y $left_y
794 event generate $e <ButtonRelease-1> -x $left_x -y $left_y
798 lappend result [$e index insert]
799 lappend result [_get_selection $e]
801 # Clear selection by clicking at 0,0
803 event generate $e <ButtonPress-1> -x 0 -y 0
805 event generate $e <ButtonRelease-1> -x 0 -y 0
808 # Double click near right hand edge of the letter A
810 event generate $e <ButtonPress-1> -x $right_x -y $right_y
812 event generate $e <ButtonRelease-1> -x $right_x -y $right_y
814 event generate $e <ButtonPress-1> -x $right_x -y $right_y
816 event generate $e <ButtonRelease-1> -x $right_x -y $right_y
819 lappend result [$e index insert]
820 lappend result [_get_selection $e]
827 test event-8 {event generate with keysyms corresponding to
828 multi-byte virtual keycodes - bug
829 e36963bfe8df9f5e528134707a91b9c0051de723} -constraints nonPortable -setup {
837 bind $e <KeyPress> {lappend res keycode: %k keysym: %K}
840 event generate $e <diaeresis>
841 # The value now contained in $res depends on the actual
842 # physical keyboard layout and keycode generated, from
843 # the hardware on which the test suite happens to run.
844 # We don't need (and we can't really) check correctness
845 # of the (system-dependent) keycode received, however
846 # Tk should be able to associate this keycode to a
847 # (system-independent) known keysym, unless the system
848 # running the test does not have a keyboard with a
850 if {[expr {[lindex $res 3] ne "??"}]} {
851 # keyboard has a physical diaeresis key and bug is fixed
854 return "Test failed, unless the keyboard tied to the system \
855 on which this test is run does NOT have a diaeresis \
856 physical key - in this case, test is actually void."
862 test event-9 {no <Enter> event is generated for the container window when its
863 managed window in which the mouse pointer was inside gets
864 destroyed - bug 9e1312f32c} -setup {
867 if {[winfo ismapped .]} {
874 pack propagate .top 0
875 bind .top <Enter> {lappend res %W}
876 pack [frame .top.f -bg green -width 50 -height 50] -anchor se -side bottom
877 tkwait visibility .top.f
881 event generate .top.f <Motion> -warp 1 -x 25 -y 25 ; # <Enter> sent to .top and .top.f
882 controlPointerWarpTiming
883 update ; # idletasks not enough
884 destroy .top.f ; # no <Enter> event sent
893 } -result {.top .top.f}
897 unset -nocomplain keypress_lookup
898 rename _init_keypress_lookup {}
899 rename _keypress_lookup {}
902 rename _text_ind_to_x_y {}
903 rename _get_selection {}