3 # This file defines several procedures for managing the input
6 # RCS: @(#) $Id: focus.tcl,v 1.9.4.1 2006/01/25 18:21:41 dgp Exp $
8 # Copyright (c) 1994-1995 Sun Microsystems, Inc.
10 # See the file "license.terms" for information on usage and redistribution
11 # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
15 # This procedure returns the name of the next window after "w" in
16 # "focus order" (the window that should receive the focus next if
17 # Tab is typed in w). "Next" is defined by a pre-order search
18 # of a top-level and its non-top-level descendants, with the stacking
19 # order determining the order of siblings. The "-takefocus" options
20 # on windows determine whether or not they should be skipped.
23 # w - Name of a window.
25 proc ::tk_focusNext w
{
29 # Descend to just before the first child of the current widget.
32 set children
[winfo children
$cur]
35 # Look for the next sibling that isn't a top-level.
39 if {$i < [llength $children]} {
40 set cur
[lindex $children $i]
41 if {[winfo toplevel $cur] eq
$cur} {
48 # No more siblings, so go to the current widget's parent.
49 # If it's a top-level, break out of the loop, otherwise
50 # look for its next sibling.
53 if {[winfo toplevel $cur] eq
$cur} {
56 set parent
[winfo parent
$parent]
57 set children
[winfo children
$parent]
58 set i
[lsearch -exact $children $cur]
60 if {$w eq
$cur ||
[tk::FocusOK $cur]} {
67 # This procedure returns the name of the previous window before "w" in
68 # "focus order" (the window that should receive the focus next if
69 # Shift-Tab is typed in w). "Next" is defined by a pre-order search
70 # of a top-level and its non-top-level descendants, with the stacking
71 # order determining the order of siblings. The "-takefocus" options
72 # on windows determine whether or not they should be skipped.
75 # w - Name of a window.
77 proc ::tk_focusPrev w
{
81 # Collect information about the current window's position
82 # among its siblings. Also, if the window is a top-level,
83 # then reposition to just after the last child of the window.
85 if {[winfo toplevel $cur] eq
$cur} {
87 set children
[winfo children
$cur]
88 set i
[llength $children]
90 set parent
[winfo parent
$cur]
91 set children
[winfo children
$parent]
92 set i
[lsearch -exact $children $cur]
95 # Go to the previous sibling, then descend to its last descendant
96 # (highest in stacking order. While doing this, ignore top-levels
97 # and their descendants. When we run out of descendants, go up
98 # one level to the parent.
102 set cur
[lindex $children $i]
103 if {[winfo toplevel $cur] eq
$cur} {
107 set children
[winfo children
$parent]
108 set i
[llength $children]
111 if {$w eq
$cur ||
[tk::FocusOK $cur]} {
119 # This procedure is invoked to decide whether or not to focus on
120 # a given window. It returns 1 if it's OK to focus on the window,
121 # 0 if it's not OK. The code first checks whether the window is
122 # viewable. If not, then it never focuses on the window. Then it
123 # checks the -takefocus option for the window and uses it if it's
124 # set. If there's no -takefocus option, the procedure checks to
125 # see if (a) the widget isn't disabled, and (b) it has some key
126 # bindings. If all of these are true, then 1 is returned.
129 # w - Name of a window.
131 proc ::tk::FocusOK w
{
132 set code
[catch {$w cget
-takefocus} value
]
133 if {($code == 0) && ($value ne
"")} {
136 } elseif
{$value == 1} {
137 return [winfo viewable
$w]
139 set value
[uplevel #0 $value [list $w]]
145 if {![winfo viewable
$w]} {
148 set code
[catch {$w cget
-state} value
]
149 if {($code == 0) && $value eq
"disabled"} {
152 regexp Key|Focus
"[bind $w] [bind [winfo class $w]]"
155 # ::tk_focusFollowsMouse --
157 # If this procedure is invoked, Tk will enter "focus-follows-mouse"
158 # mode, where the focus is always on whatever window contains the
159 # mouse. If this procedure isn't invoked, then the user typically
160 # has to click on a window to give it the focus.
165 proc ::tk_focusFollowsMouse {} {
166 set old
[bind all
<Enter
>]
168 if {"%d" eq
"NotifyAncestor" \
169 ||
"%d" eq
"NotifyNonlinear" \
170 ||
"%d" eq
"NotifyInferior"} {
171 if {[tk::FocusOK %W
]} {
177 bind all
<Enter
> "$old; $script"
179 bind all
<Enter
> $script